From 6bca378cecbbe6658bc09eed4986c88cfc8b5402 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Wed, 30 Jun 2021 04:26:20 +0500 Subject: [PATCH] Move Android specific utils from TermuxUtils to AndroidUtils --- .../app/activities/SettingsActivity.java | 3 +- .../terminal/TermuxTerminalViewClient.java | 3 +- .../com/termux/app/utils/PluginUtils.java | 5 +- .../com/termux/shared/crash/CrashHandler.java | 5 +- .../com/termux/shared/models/ReportInfo.java | 4 +- .../com/termux/shared/shell/ResultSender.java | 6 +- .../termux/shared/termux/AndroidUtils.java | 181 ++++++++++++++++++ .../com/termux/shared/termux/TermuxUtils.java | 168 +--------------- 8 files changed, 203 insertions(+), 172 deletions(-) create mode 100644 termux-shared/src/main/java/com/termux/shared/termux/AndroidUtils.java diff --git a/app/src/main/java/com/termux/app/activities/SettingsActivity.java b/app/src/main/java/com/termux/app/activities/SettingsActivity.java index 9c2015b8..1ae903a6 100644 --- a/app/src/main/java/com/termux/app/activities/SettingsActivity.java +++ b/app/src/main/java/com/termux/app/activities/SettingsActivity.java @@ -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)); diff --git a/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java b/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java index 08201b57..7b3592fb 100644 --- a/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java +++ b/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java @@ -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) diff --git a/app/src/main/java/com/termux/app/utils/PluginUtils.java b/app/src/main/java/com/termux/app/utils/PluginUtils.java index 6515fd00..67fe6c18 100644 --- a/app/src/main/java/com/termux/app/utils/PluginUtils.java +++ b/app/src/main/java/com/termux/app/utils/PluginUtils.java @@ -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 `-.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); diff --git a/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java b/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java index 1f7c82ad..8f5e028e 100644 --- a/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java +++ b/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java @@ -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()); diff --git a/termux-shared/src/main/java/com/termux/shared/models/ReportInfo.java b/termux-shared/src/main/java/com/termux/shared/models/ReportInfo.java index 824c11ac..fdb648b2 100644 --- a/termux-shared/src/main/java/com/termux/shared/models/ReportInfo.java +++ b/termux-shared/src/main/java/com/termux/shared/models/ReportInfo.java @@ -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(); } /** diff --git a/termux-shared/src/main/java/com/termux/shared/shell/ResultSender.java b/termux-shared/src/main/java/com/termux/shared/shell/ResultSender.java index 2a5e9308..6e19958a 100644 --- a/termux-shared/src/main/java/com/termux/shared/shell/ResultSender.java +++ b/termux-shared/src/main/java/com/termux/shared/shell/ResultSender.java @@ -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); diff --git a/termux-shared/src/main/java/com/termux/shared/termux/AndroidUtils.java b/termux-shared/src/main/java/com/termux/shared/termux/AndroidUtils.java new file mode 100644 index 00000000..698d2c28 --- /dev/null +++ b/termux-shared/src/main/java/com/termux/shared/termux/AndroidUtils.java @@ -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()); + } + +} diff --git a/termux-shared/src/main/java/com/termux/shared/termux/TermuxUtils.java b/termux-shared/src/main/java/com/termux/shared/termux/TermuxUtils.java index 71e6a3ae..3eeb584e 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/TermuxUtils.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/TermuxUtils.java @@ -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 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";