From 15eb56d4dd2ed23afbea78178a3854ba30bc0323 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Sun, 28 Mar 2021 09:06:17 +0500 Subject: [PATCH] Add PackageUtils and fix ReportActivity - PackageUtils has been added to get various package related info. This will be used to get info based on Context objects instead of using BuildConfig which wouldn't have been available across termux plugins. - Support for getting Context objects of all termux plugin apps have been added to TermuxUtils. - Support for showing more details for the app has been added for ReportActivity. This will also allow app info of Termux app to be generated when TermuxUtils.getAppInfoMarkdownString() is called by a termux plugin so that both are shown so that devs/users can more easily detect compatibility issues. - ReportActivity has been fixed to also include report and device info instead of just the ExecutionCommand info when copying and sharing. - Moved the generation of markdown for ReportInfo to its own class and added creationTimestamp field. - Increased markdown headings size for some cases. --- .../termux/app/activities/ReportActivity.java | 34 +-- .../termux/app/models/ExecutionCommand.java | 22 +- .../com/termux/app/models/ReportInfo.java | 46 +++- .../TermuxAppSharedPreferences.java | 3 +- .../java/com/termux/app/utils/Logger.java | 4 +- .../com/termux/app/utils/PackageUtils.java | 108 +++++++++ .../com/termux/app/utils/PluginUtils.java | 2 +- .../com/termux/app/utils/TermuxUtils.java | 225 +++++++++++++----- 8 files changed, 346 insertions(+), 98 deletions(-) create mode 100644 app/src/main/java/com/termux/app/utils/PackageUtils.java diff --git a/app/src/main/java/com/termux/app/activities/ReportActivity.java b/app/src/main/java/com/termux/app/activities/ReportActivity.java index 6d6651db44..ae3b5db03a 100644 --- a/app/src/main/java/com/termux/app/activities/ReportActivity.java +++ b/app/src/main/java/com/termux/app/activities/ReportActivity.java @@ -32,6 +32,7 @@ public class ReportActivity extends AppCompatActivity { private static final String EXTRA_REPORT_INFO = "report_info"; ReportInfo mReportInfo; + String mReportActivityMarkdownString; @Override protected void onCreate(Bundle savedInstanceState) { @@ -98,7 +99,9 @@ private void updateUI(Bundle bundle) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); - adapter.setMarkdown(markwon, mReportInfo.reportString + getReportAndDeviceDetailsMarkdownString()); + + generateReportActivityMarkdownString(); + adapter.setMarkdown(markwon, mReportActivityMarkdownString); adapter.notifyDataSetChanged(); } @@ -129,39 +132,20 @@ public boolean onOptionsItemSelected(final MenuItem item) { int id = item.getItemId(); if (id == R.id.menu_item_share_report) { if (mReportInfo != null) - ShareUtils.shareText(this, getString(R.string.title_report_text), mReportInfo.reportString); + ShareUtils.shareText(this, getString(R.string.title_report_text), mReportActivityMarkdownString); } else if (id == R.id.menu_item_copy_report) { if (mReportInfo != null) - ShareUtils.copyTextToClipboard(this, mReportInfo.reportString, null); + ShareUtils.copyTextToClipboard(this, mReportActivityMarkdownString, null); } return false; } /** - * Get a markdown {@link String} for {@link #mReportInfo} and device details. - * - * @return Returns the markdown {@link String}. + * Generate the markdown {@link String} to be shown in {@link ReportActivity}. */ - private String getReportAndDeviceDetailsMarkdownString() { - if(!mReportInfo.addReportAndDeviceDetails) return ""; - - StringBuilder markdownString = new StringBuilder(); - - markdownString.append("\n\n### Report And Device Details\n\n"); - - if (mReportInfo != null) { - markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("User Action", mReportInfo.userAction, "-")); - markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Sender", mReportInfo.sender, "-")); - } - - markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Timestamp", TermuxUtils.getCurrentTimeStamp(), "-")); - - markdownString.append("\n\n").append(TermuxUtils.getDeviceDetailsMarkdownString(this)); - - markdownString.append("\n##\n"); - - return markdownString.toString(); + private void generateReportActivityMarkdownString() { + mReportActivityMarkdownString = ReportInfo.getReportInfoMarkdownString(this, mReportInfo); } diff --git a/app/src/main/java/com/termux/app/models/ExecutionCommand.java b/app/src/main/java/com/termux/app/models/ExecutionCommand.java index b81badc868..44485921d2 100644 --- a/app/src/main/java/com/termux/app/models/ExecutionCommand.java +++ b/app/src/main/java/com/termux/app/models/ExecutionCommand.java @@ -160,7 +160,7 @@ public String toString() { * @param ignoreNull Set to {@code true} if non-critical {@code null} values are to be ignored. * @return Returns the log friendly {@link String}. */ - public static String getExecutionInputLogString(ExecutionCommand executionCommand, boolean ignoreNull) { + public static String getExecutionInputLogString(final ExecutionCommand executionCommand, boolean ignoreNull) { if (executionCommand == null) return "null"; StringBuilder logString = new StringBuilder(); @@ -197,7 +197,7 @@ public static String getExecutionInputLogString(ExecutionCommand executionComman * @param ignoreNull Set to {@code true} if non-critical {@code null} values are to be ignored. * @return Returns the log friendly {@link String}. */ - public static String getExecutionOutputLogString(ExecutionCommand executionCommand, boolean ignoreNull) { + public static String getExecutionOutputLogString(final ExecutionCommand executionCommand, boolean ignoreNull) { if (executionCommand == null) return "null"; StringBuilder logString = new StringBuilder(); @@ -223,7 +223,7 @@ public static String getExecutionOutputLogString(ExecutionCommand executionComma * @param ignoreNull Set to {@code true} if non-critical {@code null} values are to be ignored. * @return Returns the log friendly {@link String}. */ - public static String getExecutionErrLogString(ExecutionCommand executionCommand, boolean ignoreNull) { + public static String getExecutionErrLogString(final ExecutionCommand executionCommand, boolean ignoreNull) { StringBuilder logString = new StringBuilder(); if(!ignoreNull || (executionCommand.isStateFailed())) { @@ -243,7 +243,7 @@ public static String getExecutionErrLogString(ExecutionCommand executionCommand, * @param executionCommand The {@link ExecutionCommand} to convert. * @return Returns the log friendly {@link String}. */ - public static String getDetailedLogString(ExecutionCommand executionCommand) { + public static String getDetailedLogString(final ExecutionCommand executionCommand) { if (executionCommand == null) return "null"; StringBuilder logString = new StringBuilder(); @@ -264,14 +264,14 @@ public static String getDetailedLogString(ExecutionCommand executionCommand) { * @param executionCommand The {@link ExecutionCommand} to convert. * @return Returns the markdown {@link String}. */ - public static String getDetailedMarkdownString(ExecutionCommand executionCommand) { + public static String getExecutionCommandMarkdownString(final ExecutionCommand executionCommand) { if (executionCommand == null) return "null"; if (executionCommand.commandLabel == null) executionCommand.commandLabel = "Execution Command"; StringBuilder markdownString = new StringBuilder(); - markdownString.append("### ").append(executionCommand.commandLabel).append("\n"); + markdownString.append("## ").append(executionCommand.commandLabel).append("\n"); markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Previous State", executionCommand.previousState.getName(), "-")); @@ -301,14 +301,14 @@ public static String getDetailedMarkdownString(ExecutionCommand executionCommand if(executionCommand.commandDescription != null || executionCommand.commandHelp != null) { if (executionCommand.commandDescription != null) - markdownString.append("\n\n#### Command Description\n\n").append(executionCommand.commandDescription).append("\n"); + markdownString.append("\n\n### Command Description\n\n").append(executionCommand.commandDescription).append("\n"); if (executionCommand.commandHelp != null) - markdownString.append("\n\n#### Command Help\n\n").append(executionCommand.commandHelp).append("\n"); + markdownString.append("\n\n### Command Help\n\n").append(executionCommand.commandHelp).append("\n"); markdownString.append("\n##\n"); } if(executionCommand.pluginAPIHelp != null) { - markdownString.append("\n\n#### Plugin API Help\n\n").append(executionCommand.pluginAPIHelp); + markdownString.append("\n\n### Plugin API Help\n\n").append(executionCommand.pluginAPIHelp); markdownString.append("\n##\n"); } @@ -439,7 +439,7 @@ public String geStackTracesMarkdownString() { * @param argumentsArray The {@link String[]} argumentsArray to convert. * @return Returns the markdown {@link String}. */ - public static String getArgumentsMarkdownString(String[] argumentsArray) { + public static String getArgumentsMarkdownString(final String[] argumentsArray) { StringBuilder argumentsString = new StringBuilder("**Arguments:**"); if (argumentsArray != null && argumentsArray.length != 0) { @@ -469,7 +469,7 @@ public static String getArgumentsMarkdownString(String[] argumentsArray) { * @param argumentsArray The {@link String[]} argumentsArray to convert. * @return Returns the log friendly {@link String}. */ - public static String getArgumentsLogString(String[] argumentsArray) { + public static String getArgumentsLogString(final String[] argumentsArray) { StringBuilder argumentsString = new StringBuilder("Arguments:"); if (argumentsArray != null && argumentsArray.length != 0) { diff --git a/app/src/main/java/com/termux/app/models/ReportInfo.java b/app/src/main/java/com/termux/app/models/ReportInfo.java index 4f8b4cef0e..7832d64602 100644 --- a/app/src/main/java/com/termux/app/models/ReportInfo.java +++ b/app/src/main/java/com/termux/app/models/ReportInfo.java @@ -1,5 +1,10 @@ package com.termux.app.models; +import android.content.Context; + +import com.termux.app.utils.MarkdownUtils; +import com.termux.app.utils.TermuxUtils; + import java.io.Serializable; public class ReportInfo implements Serializable { @@ -12,15 +17,48 @@ public class ReportInfo implements Serializable { public String reportTitle; /** The markdown text for the report. */ public String reportString; - /** If set to {@code true}, then report and device details will be added to the report. */ - public boolean addReportAndDeviceDetails; + /** If set to {@code true}, then report, app and device info will be added to the report when + * markdown is generated. + */ + public boolean addReportInfoToMarkdown; + /** The timestamp for the report. */ + public String creationTimestammp; - public ReportInfo(UserAction userAction, String sender, String reportTitle, String reportString, boolean addReportAndDeviceDetails) { + public ReportInfo(UserAction userAction, String sender, String reportTitle, String reportString, boolean addReportInfoToMarkdown) { this.userAction = userAction; this.sender = sender; this.reportTitle = reportTitle; this.reportString = reportString; - this.addReportAndDeviceDetails = addReportAndDeviceDetails; + this.addReportInfoToMarkdown = addReportInfoToMarkdown; + this.creationTimestammp = TermuxUtils.getCurrentTimeStamp(); + } + + /** + * Get a markdown {@link String} for {@link ReportInfo}. + * + * @param currentPackageContext The context of current package. + * @param reportInfo The {@link ReportInfo} to convert. + * @return Returns the markdown {@link String}. + */ + public static String getReportInfoMarkdownString(final Context currentPackageContext, final ReportInfo reportInfo) { + if (reportInfo == null) return "null"; + + StringBuilder markdownString = new StringBuilder(); + + markdownString.append(reportInfo.reportString); + + if(reportInfo.addReportInfoToMarkdown) { + markdownString.append("## Report Info\n\n"); + markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("User Action", reportInfo.userAction, "-")); + markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Sender", reportInfo.sender, "-")); + markdownString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Creation Timestamp", reportInfo.creationTimestammp, "-")); + markdownString.append("\n##\n"); + + markdownString.append("\n\n").append(TermuxUtils.getAppInfoMarkdownString(currentPackageContext, true)); + markdownString.append("\n\n").append(TermuxUtils.getDeviceInfoMarkdownString(currentPackageContext)); + } + + return markdownString.toString(); } } diff --git a/app/src/main/java/com/termux/app/settings/preferences/TermuxAppSharedPreferences.java b/app/src/main/java/com/termux/app/settings/preferences/TermuxAppSharedPreferences.java index de469143a6..5ada86440e 100644 --- a/app/src/main/java/com/termux/app/settings/preferences/TermuxAppSharedPreferences.java +++ b/app/src/main/java/com/termux/app/settings/preferences/TermuxAppSharedPreferences.java @@ -25,7 +25,8 @@ public class TermuxAppSharedPreferences { private static final String LOG_TAG = "TermuxAppSharedPreferences"; public TermuxAppSharedPreferences(@Nonnull Context context) { - mContext = TermuxUtils.getTermuxPackageContext(context); + // We use the default context if failed to get termux package context + mContext = TextDataUtils.getDefaultIfNull(TermuxUtils.getTermuxPackageContext(context), context); mSharedPreferences = getPrivateSharedPreferences(mContext); setFontVariables(context); diff --git a/app/src/main/java/com/termux/app/utils/Logger.java b/app/src/main/java/com/termux/app/utils/Logger.java index 40a4b68b21..0ff5b940a1 100644 --- a/app/src/main/java/com/termux/app/utils/Logger.java +++ b/app/src/main/java/com/termux/app/utils/Logger.java @@ -216,13 +216,13 @@ public static String getStackTracesString(String label, String[] stackTraceStrin public static String getStackTracesMarkdownString(String label, String[] stackTraceStringArray) { if(label == null) label = "StackTraces:"; - StringBuilder stackTracesString = new StringBuilder("#### " + label); + StringBuilder stackTracesString = new StringBuilder("### " + label); if (stackTraceStringArray == null || stackTraceStringArray.length == 0) { stackTracesString.append("\n\n`-`"); } else { for (int i = 0; i != stackTraceStringArray.length; i++) { - stackTracesString.append("\n\n\n##### Stacktrace ").append(i + 1).append("\n\n```\n").append(stackTraceStringArray[i]).append("\n```"); + stackTracesString.append("\n\n\n#### Stacktrace ").append(i + 1).append("\n\n```\n").append(stackTraceStringArray[i]).append("\n```"); } } diff --git a/app/src/main/java/com/termux/app/utils/PackageUtils.java b/app/src/main/java/com/termux/app/utils/PackageUtils.java new file mode 100644 index 0000000000..96e9609904 --- /dev/null +++ b/app/src/main/java/com/termux/app/utils/PackageUtils.java @@ -0,0 +1,108 @@ +package com.termux.app.utils; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; + +import androidx.annotation.NonNull; + +public class PackageUtils { + + /** + * Get the {@link Context} for the package name. + * + * @param context The {@link Context} to use to get the {@link Context} of the {@code packageName}. + * @return Returns the {@link Context}. This will {@code null} if an exception is raised. + */ + public static Context getContextForPackage(@NonNull final Context context, String packageName) { + try { + return context.createPackageContext(packageName, Context.CONTEXT_RESTRICTED); + } catch (Exception e) { + Logger.logStackTraceWithMessage("Failed to get \"" + packageName + "\" package context.", e); + return null; + } + } + + /** + * Get the {@link PackageInfo} for the package associated with the {@code context}. + * + * @param context The {@link Context} for the package. + * @return Returns the {@link PackageInfo}. This will be {@code null} if an exception is raised. + */ + public static PackageInfo getPackageInfoForPackage(@NonNull final Context context) { + try { + return context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + } catch (final Exception e) { + return null; + } + } + + /** + * Get the app name for the package associated with the {@code context}. + * + * @param context The {@link Context} for the package. + * @return Returns the {@code android:name} attribute. + */ + public static String getAppNameForPackage(@NonNull final Context context) { + return context.getApplicationInfo().loadLabel(context.getPackageManager()).toString(); + } + + /** + * Get the package name for the package associated with the {@code context}. + * + * @param context The {@link Context} for the package. + * @return Returns the package name. + */ + public static String getPackageNameForPackage(@NonNull final Context context) { + return context.getApplicationInfo().packageName; + } + + /** + * Get the {@code targetSdkVersion} for the package associated with the {@code context}. + * + * @param context The {@link Context} for the package. + * @return Returns the {@code targetSdkVersion}. + */ + public static int getTargetSDKForPackage(@NonNull final Context context) { + return context.getApplicationInfo().targetSdkVersion; + } + + /** + * Get the {@code versionName} for the package associated with the {@code context}. + * + * @param context The {@link Context} for the package. + * @return Returns the {@code versionName}. This will be {@code null} if an exception is raised. + */ + public static Boolean isAppForPackageADebugBuild(@NonNull final Context context) { + return ( 0 != ( context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) ); + } + + /** + * Get the {@code versionCode} for the package associated with the {@code context}. + * + * @param context The {@link Context} for the package. + * @return Returns the {@code versionCode}. This will be {@code null} if an exception is raised. + */ + public static Integer getVersionCodeForPackage(@NonNull final Context context) { + try { + return getPackageInfoForPackage(context).versionCode; + } catch (final Exception e) { + return null; + } + } + + /** + * Get the {@code versionName} for the package associated with the {@code context}. + * + * @param context The {@link Context} for the package. + * @return Returns the {@code versionName}. This will be {@code null} if an exception is raised. + */ + public static String getVersionNameForPackage(@NonNull final Context context) { + try { + return getPackageInfoForPackage(context).versionName; + } catch (final Exception e) { + return 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 059457b512..bb7e6b7dd0 100644 --- a/app/src/main/java/com/termux/app/utils/PluginUtils.java +++ b/app/src/main/java/com/termux/app/utils/PluginUtils.java @@ -149,7 +149,7 @@ public static void processPluginExecutionCommandError(final Context context, Str // to show the details of the error String title = TermuxConstants.TERMUX_APP_NAME + " Plugin Execution Command Error"; - Intent notificationIntent = ReportActivity.newInstance(context, new ReportInfo(UserAction.PLUGIN_EXECUTION_COMMAND, logTag, title, ExecutionCommand.getDetailedMarkdownString(executionCommand), true)); + Intent notificationIntent = ReportActivity.newInstance(context, new ReportInfo(UserAction.PLUGIN_EXECUTION_COMMAND, logTag, title, ExecutionCommand.getExecutionCommandMarkdownString(executionCommand), true)); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); // Setup the notification channel if not already set up diff --git a/app/src/main/java/com/termux/app/utils/TermuxUtils.java b/app/src/main/java/com/termux/app/utils/TermuxUtils.java index 8e40fcbd2e..9640b63fed 100644 --- a/app/src/main/java/com/termux/app/utils/TermuxUtils.java +++ b/app/src/main/java/com/termux/app/utils/TermuxUtils.java @@ -10,7 +10,6 @@ import androidx.annotation.NonNull; import com.google.common.base.Joiner; -import com.termux.BuildConfig; import com.termux.app.TermuxConstants; @@ -28,23 +27,87 @@ public class TermuxUtils { - public static Context getTermuxPackageContext(Context context) { - try { - return context.createPackageContext(TermuxConstants.TERMUX_PACKAGE_NAME, Context.CONTEXT_RESTRICTED); - } catch (Exception e) { - Logger.logStackTraceWithMessage("Failed to get \"" + TermuxConstants.TERMUX_PACKAGE_NAME + "\" package context. Force using current context.", e); - Logger.logError("Force using current context"); - return context; - } + /** + * Get the {@link Context} for {@link TermuxConstants#TERMUX_PACKAGE_NAME} package. + * + * @param context The {@link Context} to use to get the {@link Context} of the package. + * @return Returns the {@link Context}. This will {@code null} if an exception is raised. + */ + public static Context getTermuxPackageContext(@NonNull Context context) { + return PackageUtils.getContextForPackage(context, TermuxConstants.TERMUX_PACKAGE_NAME); + } + + /** + * Get the {@link Context} for {@link TermuxConstants#TERMUX_API_PACKAGE_NAME} package. + * + * @param context The {@link Context} to use to get the {@link Context} of the package. + * @return Returns the {@link Context}. This will {@code null} if an exception is raised. + */ + public static Context getTermuxAPIPackageContext(@NonNull Context context) { + return PackageUtils.getContextForPackage(context, TermuxConstants.TERMUX_API_PACKAGE_NAME); + } + + /** + * Get the {@link Context} for {@link TermuxConstants#TERMUX_BOOT_PACKAGE_NAME} package. + * + * @param context The {@link Context} to use to get the {@link Context} of the package. + * @return Returns the {@link Context}. This will {@code null} if an exception is raised. + */ + public static Context getTermuxBootPackageContext(@NonNull Context context) { + return PackageUtils.getContextForPackage(context, TermuxConstants.TERMUX_BOOT_PACKAGE_NAME); } + /** + * Get the {@link Context} for {@link TermuxConstants#TERMUX_FLOAT_PACKAGE_NAME} package. + * + * @param context The {@link Context} to use to get the {@link Context} of the package. + * @return Returns the {@link Context}. This will {@code null} if an exception is raised. + */ + public static Context getTermuxFloatPackageContext(@NonNull Context context) { + return PackageUtils.getContextForPackage(context, TermuxConstants.TERMUX_FLOAT_PACKAGE_NAME); + } + + /** + * Get the {@link Context} for {@link TermuxConstants#TERMUX_STYLING_PACKAGE_NAME} package. + * + * @param context The {@link Context} to use to get the {@link Context} of the package. + * @return Returns the {@link Context}. This will {@code null} if an exception is raised. + */ + public static Context getTermuxStylingPackageContext(@NonNull Context context) { + return PackageUtils.getContextForPackage(context, TermuxConstants.TERMUX_STYLING_PACKAGE_NAME); + } + + /** + * Get the {@link Context} for {@link TermuxConstants#TERMUX_TASKER_PACKAGE_NAME} package. + * + * @param context The {@link Context} to use to get the {@link Context} of the package. + * @return Returns the {@link Context}. This will {@code null} if an exception is raised. + */ + public static Context getTermuxTaskerPackageContext(@NonNull Context context) { + return PackageUtils.getContextForPackage(context, TermuxConstants.TERMUX_TASKER_PACKAGE_NAME); + } + + /** + * Get the {@link Context} for {@link TermuxConstants#TERMUX_WIDGET_PACKAGE_NAME} package. + * + * @param context The {@link Context} to use to get the {@link Context} of the package. + * @return Returns the {@link Context}. This will {@code null} if an exception is raised. + */ + public static Context getTermuxWidgetPackageContext(@NonNull Context context) { + return PackageUtils.getContextForPackage(context, TermuxConstants.TERMUX_WIDGET_PACKAGE_NAME); + } + + + /** * Send the {@link TermuxConstants#BROADCAST_TERMUX_OPENED} broadcast to notify apps that Termux * app has been opened. * * @param context The Context to send the broadcast. */ - public static void sendTermuxOpenedBroadcast(Context context) { + 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); @@ -60,12 +123,78 @@ public static void sendTermuxOpenedBroadcast(Context context) { } /** - * Get a markdown {@link String} for the device details. + * Get a markdown {@link String} for the app info. If the {@code context} passed is different + * from the {@link TermuxConstants#TERMUX_PACKAGE_NAME} package context, then this function + * must have been called by a different package like a plugin, so we return info for both packages + * if {@code returnTermuxPackageInfoToo} is {@code true}. + * + * @param currentPackageContext The context of current package. + * @param returnTermuxPackageInfoToo If set to {@code true}, then will return info of the + * {@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) { + if (currentPackageContext == null) return "null"; + + StringBuilder markdownString = new StringBuilder(); + + Context termuxPackageContext = getTermuxPackageContext(currentPackageContext); + + String termuxPackageName = null; + String termuxAppName = null; + if(termuxPackageContext != null) { + termuxPackageName = PackageUtils.getPackageNameForPackage(termuxPackageContext); + termuxAppName = PackageUtils.getAppNameForPackage(termuxPackageContext); + } + + String currentPackageName = PackageUtils.getPackageNameForPackage(currentPackageContext); + String currentAppName = PackageUtils.getAppNameForPackage(currentPackageContext); + + boolean isTermuxPackage = (termuxPackageName != null && termuxPackageName.equals(currentPackageName)); + + + if(returnTermuxPackageInfoToo && !isTermuxPackage) + markdownString.append("## ").append(currentAppName).append(" App Info (Current)\n"); + else + markdownString.append("## ").append(currentAppName).append(" App Info\n"); + markdownString.append(getAppInfoMarkdownStringInner(currentPackageContext)); + + if(returnTermuxPackageInfoToo && !isTermuxPackage) { + markdownString.append("\n\n## ").append(termuxAppName).append(" App Info\n"); + markdownString.append(getAppInfoMarkdownStringInner(termuxPackageContext)); + } + + markdownString.append("\n##\n"); + + return markdownString.toString(); + } + + /** + * 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 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)); + + 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 getDeviceDetailsMarkdownString(final Context context) { + 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 @@ -74,36 +203,37 @@ public static String getDeviceDetailsMarkdownString(final Context context) { StringBuilder markdownString = new StringBuilder(); - markdownString.append("#### Software\n"); - appendPropertyMarkdown(markdownString, - TermuxConstants.TERMUX_APP_NAME.toUpperCase() + "_VERSION", getTermuxAppVersionName() + "(" + getTermuxAppVersionCode() + ")"); - appendPropertyMarkdown(markdownString,TermuxConstants.TERMUX_APP_NAME.toUpperCase() + "_DEBUG_BUILD", isTermuxAppDebugBuild()); - appendPropertyMarkdown(markdownString,"OS_VERSION", getSystemPropertyWithAndroidAPI("os.version")); - appendPropertyMarkdown(markdownString, "SDK_INT", Build.VERSION.SDK_INT); + 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)) - appendPropertyMarkdown(markdownString, "RELEASE", Build.VERSION.RELEASE); + appendPropertyToMarkdown(markdownString, "RELEASE", Build.VERSION.RELEASE); else - appendPropertyMarkdown(markdownString, "CODENAME", Build.VERSION.CODENAME); - appendPropertyMarkdown(markdownString, "INCREMENTAL", Build.VERSION.INCREMENTAL); - appendPropertyMarkdownIfSet(markdownString, "SECURITY_PATCH", systemProperties.getProperty("ro.build.version.security_patch")); - appendPropertyMarkdownIfSet(markdownString, "IS_DEBUGGABLE", systemProperties.getProperty("ro.debuggable")); - appendPropertyMarkdownIfSet(markdownString, "IS_EMULATOR", systemProperties.getProperty("ro.boot.qemu")); - appendPropertyMarkdownIfSet(markdownString, "IS_TREBLE_ENABLED", systemProperties.getProperty("ro.treble.enabled")); - appendPropertyMarkdown(markdownString, "TYPE", Build.TYPE); - appendPropertyMarkdown(markdownString, "TAGS", Build.TAGS); - - markdownString.append("\n\n#### Hardware\n"); - appendPropertyMarkdown(markdownString, "MANUFACTURER", Build.MANUFACTURER); - appendPropertyMarkdown(markdownString, "BRAND", Build.BRAND); - appendPropertyMarkdown(markdownString, "MODEL", Build.MODEL); - appendPropertyMarkdown(markdownString, "PRODUCT", Build.PRODUCT); - appendPropertyMarkdown(markdownString, "DISPLAY", Build.DISPLAY); - appendPropertyMarkdown(markdownString, "ID", Build.ID); - appendPropertyMarkdown(markdownString, "BOARD", Build.BOARD); - appendPropertyMarkdown(markdownString, "HARDWARE", Build.HARDWARE); - appendPropertyMarkdown(markdownString, "DEVICE", Build.DEVICE); - appendPropertyMarkdown(markdownString, "SUPPORTED_ABIS", Joiner.on(", ").skipNulls().join(Build.SUPPORTED_ABIS)); + appendPropertyToMarkdown(markdownString, "CODENAME", Build.VERSION.CODENAME); + 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, "DISPLAY", Build.DISPLAY); + appendPropertyToMarkdown(markdownString, "ID", Build.ID); + 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(); } @@ -163,13 +293,13 @@ private static String getSystemPropertyWithAndroidAPI(@NonNull String property) } } - private static void appendPropertyMarkdownIfSet(StringBuilder markdownString, String label, Object value) { + 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 appendPropertyMarkdown(StringBuilder markdownString, String label, Object value) { + private static void appendPropertyToMarkdown(StringBuilder markdownString, String label, Object value) { markdownString.append("\n").append(getPropertyMarkdown(label, value)); } @@ -179,18 +309,6 @@ private static String getPropertyMarkdown(String label, Object value) { - public static int getTermuxAppVersionCode() { - return BuildConfig.VERSION_CODE; - } - - public static String getTermuxAppVersionName() { - return BuildConfig.VERSION_NAME; - } - - public static boolean isTermuxAppDebugBuild() { - return BuildConfig.DEBUG; - } - public static String getCurrentTimeStamp() { @SuppressLint("SimpleDateFormat") final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); @@ -198,5 +316,4 @@ public static String getCurrentTimeStamp() { return df.format(new Date()); } - }