mirror of https://github.com/termux/termux-app
Move Android specific utils from TermuxUtils to AndroidUtils
This commit is contained in:
parent
12f910c32d
commit
6bca378cec
|
@ -16,6 +16,7 @@ import com.termux.app.models.UserAction;
|
|||
import com.termux.shared.interact.ShareUtils;
|
||||
import com.termux.shared.packages.PackageUtils;
|
||||
import com.termux.shared.settings.preferences.TermuxTaskerAppSharedPreferences;
|
||||
import com.termux.shared.termux.AndroidUtils;
|
||||
import com.termux.shared.termux.TermuxConstants;
|
||||
import com.termux.shared.termux.TermuxUtils;
|
||||
|
||||
|
@ -82,7 +83,7 @@ public class SettingsActivity extends AppCompatActivity {
|
|||
if (termuxPluginAppsInfo != null)
|
||||
aboutString.append("\n\n").append(termuxPluginAppsInfo);
|
||||
|
||||
aboutString.append("\n\n").append(TermuxUtils.getDeviceInfoMarkdownString(context));
|
||||
aboutString.append("\n\n").append(AndroidUtils.getDeviceInfoMarkdownString(context));
|
||||
aboutString.append("\n\n").append(TermuxUtils.getImportantLinksMarkdownString(context));
|
||||
|
||||
ReportActivity.startReportActivity(context, new ReportInfo(UserAction.ABOUT.getName(), TermuxConstants.TERMUX_APP.TERMUX_SETTINGS_ACTIVITY_NAME, title, null, aboutString.toString(), null, false));
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.termux.app.TermuxActivity;
|
|||
import com.termux.shared.data.UrlUtils;
|
||||
import com.termux.shared.shell.ShellUtils;
|
||||
import com.termux.shared.terminal.TermuxTerminalViewClientBase;
|
||||
import com.termux.shared.termux.AndroidUtils;
|
||||
import com.termux.shared.termux.TermuxConstants;
|
||||
import com.termux.shared.activities.ReportActivity;
|
||||
import com.termux.shared.models.ReportInfo;
|
||||
|
@ -664,7 +665,7 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
|
|||
reportString.append("\n").append(MarkdownUtils.getMarkdownCodeForString(transcriptTextTruncated, true));
|
||||
|
||||
reportString.append("\n\n").append(TermuxUtils.getAppInfoMarkdownString(mActivity, true));
|
||||
reportString.append("\n\n").append(TermuxUtils.getDeviceInfoMarkdownString(mActivity));
|
||||
reportString.append("\n\n").append(AndroidUtils.getDeviceInfoMarkdownString(mActivity));
|
||||
|
||||
String termuxAptInfo = TermuxUtils.geAPTInfoMarkdownString(mActivity);
|
||||
if (termuxAptInfo != null)
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.termux.shared.models.errors.Error;
|
|||
import com.termux.shared.notification.NotificationUtils;
|
||||
import com.termux.shared.shell.ResultSender;
|
||||
import com.termux.shared.shell.ShellUtils;
|
||||
import com.termux.shared.termux.AndroidUtils;
|
||||
import com.termux.shared.termux.TermuxConstants;
|
||||
import com.termux.shared.termux.TermuxConstants.TERMUX_APP.TERMUX_SERVICE;
|
||||
import com.termux.shared.logger.Logger;
|
||||
|
@ -193,7 +194,7 @@ public class PluginUtils {
|
|||
|
||||
// Set default resultFileBasename if resultSingleFile is true to `<executable_basename>-<timestamp>.log`
|
||||
if (resultConfig.resultSingleFile && resultConfig.resultFileBasename == null)
|
||||
resultConfig.resultFileBasename = ShellUtils.getExecutableBasename(executionCommand.executable) + "-" + TermuxUtils.getCurrentMilliSecondLocalTimeStamp() + ".log";
|
||||
resultConfig.resultFileBasename = ShellUtils.getExecutableBasename(executionCommand.executable) + "-" + AndroidUtils.getCurrentMilliSecondLocalTimeStamp() + ".log";
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,7 +216,7 @@ public class PluginUtils {
|
|||
|
||||
reportString.append(ExecutionCommand.getExecutionCommandMarkdownString(executionCommand));
|
||||
reportString.append("\n\n").append(TermuxUtils.getAppInfoMarkdownString(context, true));
|
||||
reportString.append("\n\n").append(TermuxUtils.getDeviceInfoMarkdownString(context));
|
||||
reportString.append("\n\n").append(AndroidUtils.getDeviceInfoMarkdownString(context));
|
||||
|
||||
Intent notificationIntent = ReportActivity.newInstance(context, new ReportInfo(UserAction.PLUGIN_EXECUTION_COMMAND.getName(), logTag, title, null, reportString.toString(), null,true));
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.termux.shared.file.FileUtils;
|
|||
import com.termux.shared.logger.Logger;
|
||||
import com.termux.shared.markdown.MarkdownUtils;
|
||||
import com.termux.shared.models.errors.Error;
|
||||
import com.termux.shared.termux.AndroidUtils;
|
||||
import com.termux.shared.termux.TermuxConstants;
|
||||
import com.termux.shared.termux.TermuxUtils;
|
||||
|
||||
|
@ -56,11 +57,11 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler {
|
|||
|
||||
reportString.append("## Crash Details\n");
|
||||
reportString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Crash Thread", thread.toString(), "-"));
|
||||
reportString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Crash Timestamp", TermuxUtils.getCurrentTimeStamp(), "-"));
|
||||
reportString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Crash Timestamp", AndroidUtils.getCurrentTimeStamp(), "-"));
|
||||
|
||||
reportString.append("\n\n").append(Logger.getStackTracesMarkdownString("Stacktrace", Logger.getStackTracesStringArray(throwable)));
|
||||
reportString.append("\n\n").append(TermuxUtils.getAppInfoMarkdownString(context, true));
|
||||
reportString.append("\n\n").append(TermuxUtils.getDeviceInfoMarkdownString(context));
|
||||
reportString.append("\n\n").append(AndroidUtils.getDeviceInfoMarkdownString(context));
|
||||
|
||||
// Log report string to logcat
|
||||
Logger.logError(reportString.toString());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.termux.shared.models;
|
||||
|
||||
import com.termux.shared.markdown.MarkdownUtils;
|
||||
import com.termux.shared.termux.TermuxUtils;
|
||||
import com.termux.shared.termux.AndroidUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
@ -34,7 +34,7 @@ public class ReportInfo implements Serializable {
|
|||
this.reportString = reportString;
|
||||
this.reportStringSuffix = reportStringSuffix;
|
||||
this.addReportInfoToMarkdown = addReportInfoToMarkdown;
|
||||
this.reportTimestamp = TermuxUtils.getCurrentTimeStamp();
|
||||
this.reportTimestamp = AndroidUtils.getCurrentTimeStamp();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,8 +15,8 @@ import com.termux.shared.models.ResultConfig;
|
|||
import com.termux.shared.models.ResultData;
|
||||
import com.termux.shared.models.errors.FunctionErrno;
|
||||
import com.termux.shared.models.errors.ResultSenderErrno;
|
||||
import com.termux.shared.termux.AndroidUtils;
|
||||
import com.termux.shared.termux.TermuxConstants.RESULT_SENDER;
|
||||
import com.termux.shared.termux.TermuxUtils;
|
||||
|
||||
public class ResultSender {
|
||||
|
||||
|
@ -235,7 +235,7 @@ public class ResultSender {
|
|||
|
||||
// Write error or output to temp file
|
||||
// Check errCode file creation below for explanation for why temp file is used
|
||||
String temp_filename = resultConfig.resultFileBasename + "-" + TermuxUtils.getCurrentMilliSecondLocalTimeStamp();
|
||||
String temp_filename = resultConfig.resultFileBasename + "-" + AndroidUtils.getCurrentMilliSecondLocalTimeStamp();
|
||||
error = FileUtils.writeStringToFile(temp_filename, resultConfig.resultDirectoryPath + "/" + temp_filename,
|
||||
null, error_or_output, false);
|
||||
if (error != null) {
|
||||
|
@ -312,7 +312,7 @@ public class ResultSender {
|
|||
// caller may otherwise read from an empty file in some cases.
|
||||
|
||||
// Write errCode to temp file
|
||||
String temp_filename = RESULT_SENDER.RESULT_FILE_ERR_PREFIX + "-" + TermuxUtils.getCurrentMilliSecondLocalTimeStamp();
|
||||
String temp_filename = RESULT_SENDER.RESULT_FILE_ERR_PREFIX + "-" + AndroidUtils.getCurrentMilliSecondLocalTimeStamp();
|
||||
if (!resultConfig.resultFilesSuffix.isEmpty()) temp_filename = temp_filename + "-" + resultConfig.resultFilesSuffix;
|
||||
error = FileUtils.writeStringToFile(temp_filename, resultConfig.resultDirectoryPath + "/" + temp_filename,
|
||||
null, String.valueOf(resultData.getErrCode()), false);
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
package com.termux.shared.termux;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.termux.shared.logger.Logger;
|
||||
import com.termux.shared.markdown.MarkdownUtils;
|
||||
import com.termux.shared.packages.PackageUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AndroidUtils {
|
||||
|
||||
/**
|
||||
* Get a markdown {@link String} for the app info for the package associated with the {@code context}.
|
||||
*
|
||||
* @param context The context for operations for the package.
|
||||
* @return Returns the markdown {@link String}.
|
||||
*/
|
||||
public static String getAppInfoMarkdownString(@NonNull final Context context) {
|
||||
StringBuilder markdownString = new StringBuilder();
|
||||
|
||||
AndroidUtils.appendPropertyToMarkdown(markdownString,"APP_NAME", PackageUtils.getAppNameForPackage(context));
|
||||
AndroidUtils.appendPropertyToMarkdown(markdownString,"PACKAGE_NAME", PackageUtils.getPackageNameForPackage(context));
|
||||
AndroidUtils.appendPropertyToMarkdown(markdownString,"VERSION_NAME", PackageUtils.getVersionNameForPackage(context));
|
||||
AndroidUtils.appendPropertyToMarkdown(markdownString,"VERSION_CODE", PackageUtils.getVersionCodeForPackage(context));
|
||||
AndroidUtils.appendPropertyToMarkdown(markdownString,"TARGET_SDK", PackageUtils.getTargetSDKForPackage(context));
|
||||
AndroidUtils.appendPropertyToMarkdown(markdownString,"IS_DEBUG_BUILD", PackageUtils.isAppForPackageADebugBuild(context));
|
||||
|
||||
return markdownString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a markdown {@link String} for the device info.
|
||||
*
|
||||
* @param context The context for operations.
|
||||
* @return Returns the markdown {@link String}.
|
||||
*/
|
||||
public static String getDeviceInfoMarkdownString(@NonNull final Context context) {
|
||||
// Some properties cannot be read with {@link System#getProperty(String)} but can be read
|
||||
// directly by running getprop command
|
||||
Properties systemProperties = getSystemProperties();
|
||||
|
||||
StringBuilder markdownString = new StringBuilder();
|
||||
|
||||
markdownString.append("## Device Info");
|
||||
|
||||
markdownString.append("\n\n### Software\n");
|
||||
appendPropertyToMarkdown(markdownString,"OS_VERSION", getSystemPropertyWithAndroidAPI("os.version"));
|
||||
appendPropertyToMarkdown(markdownString, "SDK_INT", Build.VERSION.SDK_INT);
|
||||
// If its a release version
|
||||
if ("REL".equals(Build.VERSION.CODENAME))
|
||||
appendPropertyToMarkdown(markdownString, "RELEASE", Build.VERSION.RELEASE);
|
||||
else
|
||||
appendPropertyToMarkdown(markdownString, "CODENAME", Build.VERSION.CODENAME);
|
||||
appendPropertyToMarkdown(markdownString, "ID", Build.ID);
|
||||
appendPropertyToMarkdown(markdownString, "DISPLAY", Build.DISPLAY);
|
||||
appendPropertyToMarkdown(markdownString, "INCREMENTAL", Build.VERSION.INCREMENTAL);
|
||||
appendPropertyToMarkdownIfSet(markdownString, "SECURITY_PATCH", systemProperties.getProperty("ro.build.version.security_patch"));
|
||||
appendPropertyToMarkdownIfSet(markdownString, "IS_DEBUGGABLE", systemProperties.getProperty("ro.debuggable"));
|
||||
appendPropertyToMarkdownIfSet(markdownString, "IS_EMULATOR", systemProperties.getProperty("ro.boot.qemu"));
|
||||
appendPropertyToMarkdownIfSet(markdownString, "IS_TREBLE_ENABLED", systemProperties.getProperty("ro.treble.enabled"));
|
||||
appendPropertyToMarkdown(markdownString, "TYPE", Build.TYPE);
|
||||
appendPropertyToMarkdown(markdownString, "TAGS", Build.TAGS);
|
||||
|
||||
markdownString.append("\n\n### Hardware\n");
|
||||
appendPropertyToMarkdown(markdownString, "MANUFACTURER", Build.MANUFACTURER);
|
||||
appendPropertyToMarkdown(markdownString, "BRAND", Build.BRAND);
|
||||
appendPropertyToMarkdown(markdownString, "MODEL", Build.MODEL);
|
||||
appendPropertyToMarkdown(markdownString, "PRODUCT", Build.PRODUCT);
|
||||
appendPropertyToMarkdown(markdownString, "BOARD", Build.BOARD);
|
||||
appendPropertyToMarkdown(markdownString, "HARDWARE", Build.HARDWARE);
|
||||
appendPropertyToMarkdown(markdownString, "DEVICE", Build.DEVICE);
|
||||
appendPropertyToMarkdown(markdownString, "SUPPORTED_ABIS", Joiner.on(", ").skipNulls().join(Build.SUPPORTED_ABIS));
|
||||
|
||||
markdownString.append("\n##\n");
|
||||
|
||||
return markdownString.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Properties getSystemProperties() {
|
||||
Properties systemProperties = new Properties();
|
||||
|
||||
// getprop commands returns values in the format `[key]: [value]`
|
||||
// Regex matches string starting with a literal `[`,
|
||||
// followed by one or more characters that do not match a closing square bracket as the key,
|
||||
// followed by a literal `]: [`,
|
||||
// followed by one or more characters as the value,
|
||||
// followed by string ending with literal `]`
|
||||
// multiline values will be ignored
|
||||
Pattern propertiesPattern = Pattern.compile("^\\[([^]]+)]: \\[(.+)]$");
|
||||
|
||||
try {
|
||||
Process process = new ProcessBuilder()
|
||||
.command("/system/bin/getprop")
|
||||
.redirectErrorStream(true)
|
||||
.start();
|
||||
|
||||
InputStream inputStream = process.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
String line, key, value;
|
||||
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
Matcher matcher = propertiesPattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
key = matcher.group(1);
|
||||
value = matcher.group(2);
|
||||
if (key != null && value != null && !key.isEmpty() && !value.isEmpty())
|
||||
systemProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
bufferedReader.close();
|
||||
process.destroy();
|
||||
|
||||
} catch (IOException e) {
|
||||
Logger.logStackTraceWithMessage("Failed to get run \"/system/bin/getprop\" to get system properties.", e);
|
||||
}
|
||||
|
||||
//for (String key : systemProperties.stringPropertyNames()) {
|
||||
// Logger.logVerbose(key + ": " + systemProperties.get(key));
|
||||
//}
|
||||
|
||||
return systemProperties;
|
||||
}
|
||||
|
||||
private static String getSystemPropertyWithAndroidAPI(@NonNull String property) {
|
||||
try {
|
||||
return System.getProperty(property);
|
||||
} catch (Exception e) {
|
||||
Logger.logVerbose("Failed to get system property \"" + property + "\":" + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendPropertyToMarkdownIfSet(StringBuilder markdownString, String label, Object value) {
|
||||
if (value == null) return;
|
||||
if (value instanceof String && (((String) value).isEmpty()) || "REL".equals(value)) return;
|
||||
markdownString.append("\n").append(getPropertyMarkdown(label, value));
|
||||
}
|
||||
|
||||
static void appendPropertyToMarkdown(StringBuilder markdownString, String label, Object value) {
|
||||
markdownString.append("\n").append(getPropertyMarkdown(label, value));
|
||||
}
|
||||
|
||||
private static String getPropertyMarkdown(String label, Object value) {
|
||||
return MarkdownUtils.getSingleLineMarkdownStringEntry(label, value, "-");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getCurrentTimeStamp() {
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||
df.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
return df.format(new Date());
|
||||
}
|
||||
|
||||
public static String getCurrentMilliSecondLocalTimeStamp() {
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss.SSS");
|
||||
df.setTimeZone(TimeZone.getDefault());
|
||||
return df.format(new Date());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +1,12 @@
|
|||
package com.termux.shared.termux;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import com.termux.shared.R;
|
||||
import com.termux.shared.logger.Logger;
|
||||
import com.termux.shared.markdown.MarkdownUtils;
|
||||
|
@ -21,17 +17,10 @@ import com.termux.shared.shell.TermuxTask;
|
|||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TermuxUtils {
|
||||
|
@ -117,8 +106,6 @@ public class TermuxUtils {
|
|||
* @param context The Context to send the broadcast.
|
||||
*/
|
||||
public static void sendTermuxOpenedBroadcast(@NonNull Context context) {
|
||||
if (context == null) return;
|
||||
|
||||
Intent broadcast = new Intent(TermuxConstants.BROADCAST_TERMUX_OPENED);
|
||||
List<ResolveInfo> matches = context.getPackageManager().queryBroadcastReceivers(broadcast, 0);
|
||||
|
||||
|
@ -139,7 +126,7 @@ public class TermuxUtils {
|
|||
* @param currentPackageContext The context of current package.
|
||||
* @return Returns the markdown {@link String}.
|
||||
*/
|
||||
public static String getTermuxPluginAppsInfoMarkdownString(@NonNull final Context currentPackageContext) {
|
||||
public static String getTermuxPluginAppsInfoMarkdownString(final Context currentPackageContext) {
|
||||
if (currentPackageContext == null) return "null";
|
||||
|
||||
StringBuilder markdownString = new StringBuilder();
|
||||
|
@ -154,7 +141,7 @@ public class TermuxUtils {
|
|||
if (termuxPluginAppContext != null) {
|
||||
if (i != 0)
|
||||
markdownString.append("\n\n");
|
||||
markdownString.append(TermuxUtils.getAppInfoMarkdownString(termuxPluginAppContext, false));
|
||||
markdownString.append(getAppInfoMarkdownString(termuxPluginAppContext, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +163,7 @@ public class TermuxUtils {
|
|||
* {@link TermuxConstants#TERMUX_PACKAGE_NAME} package as well if its different from current package.
|
||||
* @return Returns the markdown {@link String}.
|
||||
*/
|
||||
public static String getAppInfoMarkdownString(@NonNull final Context currentPackageContext, final boolean returnTermuxPackageInfoToo) {
|
||||
public static String getAppInfoMarkdownString(final Context currentPackageContext, final boolean returnTermuxPackageInfoToo) {
|
||||
if (currentPackageContext == null) return "null";
|
||||
|
||||
StringBuilder markdownString = new StringBuilder();
|
||||
|
@ -202,7 +189,7 @@ public class TermuxUtils {
|
|||
markdownString.append("## ").append(currentAppName).append(" App Info\n");
|
||||
markdownString.append(getAppInfoMarkdownStringInner(currentPackageContext));
|
||||
|
||||
if (returnTermuxPackageInfoToo && !isTermuxPackage) {
|
||||
if (returnTermuxPackageInfoToo && termuxPackageContext != null && !isTermuxPackage) {
|
||||
markdownString.append("\n\n## ").append(termuxAppName).append(" App Info\n");
|
||||
markdownString.append(getAppInfoMarkdownStringInner(termuxPackageContext));
|
||||
}
|
||||
|
@ -221,72 +208,17 @@ public class TermuxUtils {
|
|||
public static String getAppInfoMarkdownStringInner(@NonNull final Context context) {
|
||||
StringBuilder markdownString = new StringBuilder();
|
||||
|
||||
appendPropertyToMarkdown(markdownString,"APP_NAME", PackageUtils.getAppNameForPackage(context));
|
||||
appendPropertyToMarkdown(markdownString,"PACKAGE_NAME", PackageUtils.getPackageNameForPackage(context));
|
||||
appendPropertyToMarkdown(markdownString,"VERSION_NAME", PackageUtils.getVersionNameForPackage(context));
|
||||
appendPropertyToMarkdown(markdownString,"VERSION_CODE", PackageUtils.getVersionCodeForPackage(context));
|
||||
appendPropertyToMarkdown(markdownString,"TARGET_SDK", PackageUtils.getTargetSDKForPackage(context));
|
||||
appendPropertyToMarkdown(markdownString,"IS_DEBUG_BUILD", PackageUtils.isAppForPackageADebugBuild(context));
|
||||
markdownString.append((AndroidUtils.getAppInfoMarkdownString(context)));
|
||||
|
||||
String signingCertificateSHA256Digest = PackageUtils.getSigningCertificateSHA256DigestForPackage(context);
|
||||
if (signingCertificateSHA256Digest != null) {
|
||||
appendPropertyToMarkdown(markdownString,"APK_RELEASE", getAPKRelease(signingCertificateSHA256Digest));
|
||||
appendPropertyToMarkdown(markdownString,"SIGNING_CERTIFICATE_SHA256_DIGEST", signingCertificateSHA256Digest);
|
||||
AndroidUtils.appendPropertyToMarkdown(markdownString,"APK_RELEASE", getAPKRelease(signingCertificateSHA256Digest));
|
||||
AndroidUtils.appendPropertyToMarkdown(markdownString,"SIGNING_CERTIFICATE_SHA256_DIGEST", signingCertificateSHA256Digest);
|
||||
}
|
||||
|
||||
return markdownString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a markdown {@link String} for the device info.
|
||||
*
|
||||
* @param context The context for operations.
|
||||
* @return Returns the markdown {@link String}.
|
||||
*/
|
||||
public static String getDeviceInfoMarkdownString(@NonNull final Context context) {
|
||||
if (context == null) return "null";
|
||||
|
||||
// Some properties cannot be read with {@link System#getProperty(String)} but can be read
|
||||
// directly by running getprop command
|
||||
Properties systemProperties = getSystemProperties();
|
||||
|
||||
StringBuilder markdownString = new StringBuilder();
|
||||
|
||||
markdownString.append("## Device Info");
|
||||
|
||||
markdownString.append("\n\n### Software\n");
|
||||
appendPropertyToMarkdown(markdownString,"OS_VERSION", getSystemPropertyWithAndroidAPI("os.version"));
|
||||
appendPropertyToMarkdown(markdownString, "SDK_INT", Build.VERSION.SDK_INT);
|
||||
// If its a release version
|
||||
if ("REL".equals(Build.VERSION.CODENAME))
|
||||
appendPropertyToMarkdown(markdownString, "RELEASE", Build.VERSION.RELEASE);
|
||||
else
|
||||
appendPropertyToMarkdown(markdownString, "CODENAME", Build.VERSION.CODENAME);
|
||||
appendPropertyToMarkdown(markdownString, "ID", Build.ID);
|
||||
appendPropertyToMarkdown(markdownString, "DISPLAY", Build.DISPLAY);
|
||||
appendPropertyToMarkdown(markdownString, "INCREMENTAL", Build.VERSION.INCREMENTAL);
|
||||
appendPropertyToMarkdownIfSet(markdownString, "SECURITY_PATCH", systemProperties.getProperty("ro.build.version.security_patch"));
|
||||
appendPropertyToMarkdownIfSet(markdownString, "IS_DEBUGGABLE", systemProperties.getProperty("ro.debuggable"));
|
||||
appendPropertyToMarkdownIfSet(markdownString, "IS_EMULATOR", systemProperties.getProperty("ro.boot.qemu"));
|
||||
appendPropertyToMarkdownIfSet(markdownString, "IS_TREBLE_ENABLED", systemProperties.getProperty("ro.treble.enabled"));
|
||||
appendPropertyToMarkdown(markdownString, "TYPE", Build.TYPE);
|
||||
appendPropertyToMarkdown(markdownString, "TAGS", Build.TAGS);
|
||||
|
||||
markdownString.append("\n\n### Hardware\n");
|
||||
appendPropertyToMarkdown(markdownString, "MANUFACTURER", Build.MANUFACTURER);
|
||||
appendPropertyToMarkdown(markdownString, "BRAND", Build.BRAND);
|
||||
appendPropertyToMarkdown(markdownString, "MODEL", Build.MODEL);
|
||||
appendPropertyToMarkdown(markdownString, "PRODUCT", Build.PRODUCT);
|
||||
appendPropertyToMarkdown(markdownString, "BOARD", Build.BOARD);
|
||||
appendPropertyToMarkdown(markdownString, "HARDWARE", Build.HARDWARE);
|
||||
appendPropertyToMarkdown(markdownString, "DEVICE", Build.DEVICE);
|
||||
appendPropertyToMarkdown(markdownString, "SUPPORTED_ABIS", Joiner.on(", ").skipNulls().join(Build.SUPPORTED_ABIS));
|
||||
|
||||
markdownString.append("\n##\n");
|
||||
|
||||
return markdownString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a markdown {@link String} for reporting an issue.
|
||||
*
|
||||
|
@ -418,92 +350,6 @@ public class TermuxUtils {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public static Properties getSystemProperties() {
|
||||
Properties systemProperties = new Properties();
|
||||
|
||||
// getprop commands returns values in the format `[key]: [value]`
|
||||
// Regex matches string starting with a literal `[`,
|
||||
// followed by one or more characters that do not match a closing square bracket as the key,
|
||||
// followed by a literal `]: [`,
|
||||
// followed by one or more characters as the value,
|
||||
// followed by string ending with literal `]`
|
||||
// multiline values will be ignored
|
||||
Pattern propertiesPattern = Pattern.compile("^\\[([^]]+)]: \\[(.+)]$");
|
||||
|
||||
try {
|
||||
Process process = new ProcessBuilder()
|
||||
.command("/system/bin/getprop")
|
||||
.redirectErrorStream(true)
|
||||
.start();
|
||||
|
||||
InputStream inputStream = process.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
String line, key, value;
|
||||
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
Matcher matcher = propertiesPattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
key = matcher.group(1);
|
||||
value = matcher.group(2);
|
||||
if (key != null && value != null && !key.isEmpty() && !value.isEmpty())
|
||||
systemProperties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
bufferedReader.close();
|
||||
process.destroy();
|
||||
|
||||
} catch (IOException e) {
|
||||
Logger.logStackTraceWithMessage("Failed to get run \"/system/bin/getprop\" to get system properties.", e);
|
||||
}
|
||||
|
||||
//for (String key : systemProperties.stringPropertyNames()) {
|
||||
// Logger.logVerbose(key + ": " + systemProperties.get(key));
|
||||
//}
|
||||
|
||||
return systemProperties;
|
||||
}
|
||||
|
||||
private static String getSystemPropertyWithAndroidAPI(@NonNull String property) {
|
||||
try {
|
||||
return System.getProperty(property);
|
||||
} catch (Exception e) {
|
||||
Logger.logVerbose("Failed to get system property \"" + property + "\":" + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendPropertyToMarkdownIfSet(StringBuilder markdownString, String label, Object value) {
|
||||
if (value == null) return;
|
||||
if (value instanceof String && (((String) value).isEmpty()) || "REL".equals(value)) return;
|
||||
markdownString.append("\n").append(getPropertyMarkdown(label, value));
|
||||
}
|
||||
|
||||
private static void appendPropertyToMarkdown(StringBuilder markdownString, String label, Object value) {
|
||||
markdownString.append("\n").append(getPropertyMarkdown(label, value));
|
||||
}
|
||||
|
||||
private static String getPropertyMarkdown(String label, Object value) {
|
||||
return MarkdownUtils.getSingleLineMarkdownStringEntry(label, value, "-");
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String getCurrentTimeStamp() {
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||
df.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
return df.format(new Date());
|
||||
}
|
||||
|
||||
public static String getCurrentMilliSecondLocalTimeStamp() {
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss.SSS");
|
||||
df.setTimeZone(TimeZone.getDefault());
|
||||
return df.format(new Date());
|
||||
}
|
||||
|
||||
public static String getAPKRelease(String signingCertificateSHA256Digest) {
|
||||
if (signingCertificateSHA256Digest == null) return "null";
|
||||
|
||||
|
|
Loading…
Reference in New Issue