From afc06cfd0a9855e8443d0b62cd57d8fa9e4547a1 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Sat, 11 Jun 2022 19:48:26 +0500 Subject: [PATCH] Added|Changed!: Add `TermuxAppShellEnvironment` and `TermuxAPIShellEnvironment` to export `Termux` and `Termux:API` app variables in `TermuxShellEnvironment` This adds onto f102ea20 to build termux environment. Variables for `Termux` app have the `TERMUX_APP__` scope and variables for `Termux:API` app have `TERMUX_API_APP__` scope, which allows easier management for variables and know which variable belongs to which component. Some variables that were added in the last `termux-app` `v0.118.0` release have been renamed as per scoped variable design. The `TERMUX_VERSION` variable will stay as is for backward compatibility and will be duplicate of `TERMUX_APP__VERSION_NAME`. Docs will be provided for details of the variables. - `TERMUX_APP__VERSION_NAME` - `TERMUX_APP__VERSION_CODE` - `TERMUX_APP__PACKAGE_NAME` - `TERMUX_APP__PID` (previously `TERMUX_APP_PID`) - `TERMUX_APP__UID` - `TERMUX_APP__TARGET_SDK` - `TERMUX_APP__IS_DEBUGGABLE_BUILD` (previously `TERMUX_IS_DEBUGGABLE_BUILD`) - `TERMUX_APP__APK_RELEASE` (previously `TERMUX_APK_RELEASE`) - `TERMUX_APP__APK_PATH` - `TERMUX_APP__IS_INSTALLED_ON_EXTERNAL_STORAGE` - `TERMUX_APP__SE_PROCESS_CONTEXT` - `TERMUX_APP__SE_FILE_CONTEXT` - `TERMUX_APP__SE_INFO` - `TERMUX_APP__USER_ID` - `TERMUX_APP__PROFILE_OWNER` - `TERMUX_APP__PACKAGE_MANAGER` (previously `TERMUX_APP_PACKAGE_MANAGER`) - `TERMUX_APP__PACKAGE_VARIANT` (previously `TERMUX_APP_PACKAGE_VARIANT`) - `TERMUX_APP__FILES_DIR` - `TERMUX_APP__AM_SOCKET_SERVER_ENABLED` (previously `TERMUX_APP_AM_SOCKET_SERVER_ENABLED`) - `TERMUX_API_APP__VERSION_NAME` (previously `TERMUX_API_VERSION`) --- .../termux/shared/termux/TermuxConstants.java | 8 +- .../shared/termux/shell/TermuxShellUtils.java | 67 ------- .../termux/shell/am/TermuxAmSocketServer.java | 26 ++- .../TermuxAPIShellEnvironment.java | 43 +++++ .../TermuxAppShellEnvironment.java | 164 ++++++++++++++++++ .../environment/TermuxShellEnvironment.java | 8 + 6 files changed, 245 insertions(+), 71 deletions(-) create mode 100644 termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxAPIShellEnvironment.java create mode 100644 termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxAppShellEnvironment.java diff --git a/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java b/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java index 63b5cbb3..309ef970 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java @@ -11,7 +11,7 @@ import java.util.Formatter; import java.util.List; /* - * Version: v0.48.0 + * Version: v0.49.0 * SPDX-License-Identifier: MIT * * Changelog @@ -265,6 +265,9 @@ import java.util.List; * - 0.48.0 (2022-06-04) * - Removed `TERMUX_GAME_PACKAGES_GITHUB_*`, `TERMUX_SCIENCE_PACKAGES_GITHUB_*`, * `TERMUX_ROOT_PACKAGES_GITHUB_*`, `TERMUX_UNSTABLE_PACKAGES_GITHUB_*` + * + * - 0.49.0 (2022-06-10) + * - Added `TERMUX_ENV_PREFIX_ROOT`. */ /** @@ -871,6 +874,9 @@ public final class TermuxConstants { * may be used instead of {@link #COMMA_NORMAL} */ public static final String COMMA_ALTERNATIVE = "‚"; // Default: "‚" + /** Environment variable prefix root for the Termux app. */ + public static final String TERMUX_ENV_PREFIX_ROOT = "TERMUX"; + diff --git a/termux-shared/src/main/java/com/termux/shared/termux/shell/TermuxShellUtils.java b/termux-shared/src/main/java/com/termux/shared/termux/shell/TermuxShellUtils.java index 3a005d8a..de56a29e 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/shell/TermuxShellUtils.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/shell/TermuxShellUtils.java @@ -1,7 +1,5 @@ package com.termux.shared.termux.shell; -import android.content.Context; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -10,8 +8,6 @@ import com.termux.shared.file.filesystem.FileTypes; import com.termux.shared.termux.TermuxConstants; import com.termux.shared.file.FileUtils; import com.termux.shared.logger.Logger; -import com.termux.shared.android.PackageUtils; -import com.termux.shared.termux.TermuxUtils; import com.termux.shared.termux.settings.properties.TermuxAppSharedProperties; import org.apache.commons.io.filefilter.TrueFileFilter; @@ -27,32 +23,6 @@ public class TermuxShellUtils { private static final String LOG_TAG = "TermuxShellUtils"; - - public static String[] buildEnvironment(Context currentPackageContext, boolean isFailSafe, String workingDirectory) { - TermuxConstants.TERMUX_HOME_DIR.mkdirs(); - List environment = new ArrayList<>(); - - loadTermuxEnvVariables(currentPackageContext); - - if (TERMUX_VERSION_NAME != null) - environment.add("TERMUX_VERSION=" + TERMUX_VERSION_NAME); - if (TERMUX_IS_DEBUGGABLE_BUILD != null) - environment.add("TERMUX_IS_DEBUGGABLE_BUILD=" + TERMUX_IS_DEBUGGABLE_BUILD); - if (TERMUX_APP_PID != null) - environment.add("TERMUX_APP_PID=" + TERMUX_APP_PID); - if (TERMUX_APK_RELEASE != null) - environment.add("TERMUX_APK_RELEASE=" + TERMUX_APK_RELEASE); - if (TermuxBootstrap.TERMUX_APP_PACKAGE_MANAGER != null) - environment.add("TERMUX_APP_PACKAGE_MANAGER=" + TermuxBootstrap.TERMUX_APP_PACKAGE_MANAGER.getName()); - if (TermuxBootstrap.TERMUX_APP_PACKAGE_VARIANT != null) - environment.add("TERMUX_APP_PACKAGE_VARIANT=" + TermuxBootstrap.TERMUX_APP_PACKAGE_VARIANT.getName()); - if (TERMUX_APP_AM_SOCKET_SERVER_ENABLED != null) - environment.add("TERMUX_APP_AM_SOCKET_SERVER_ENABLED=" + TERMUX_APP_AM_SOCKET_SERVER_ENABLED); - - if (TERMUX_API_VERSION_NAME != null) - environment.add("TERMUX_API_VERSION=" + TERMUX_API_VERSION_NAME); - return environment.toArray(new String[0]); - } /** * Setup shell command arguments for the execute. The file interpreter may be prefixed to * command arguments if needed. @@ -149,41 +119,4 @@ public class TermuxShellUtils { } } - public static void loadTermuxEnvVariables(Context currentPackageContext) { - String termuxAPKReleaseOld = TERMUX_APK_RELEASE; - TERMUX_VERSION_NAME = TERMUX_IS_DEBUGGABLE_BUILD = TERMUX_APP_PID = TERMUX_APK_RELEASE = null; - - // Check if Termux app is installed and not disabled - if (TermuxUtils.isTermuxAppInstalled(currentPackageContext) == null) { - // This function may be called by a different package like a plugin, so we get version for Termux package via its context - Context termuxPackageContext = TermuxUtils.getTermuxPackageContext(currentPackageContext); - if (termuxPackageContext != null) { - TERMUX_VERSION_NAME = PackageUtils.getVersionNameForPackage(termuxPackageContext); - TERMUX_IS_DEBUGGABLE_BUILD = PackageUtils.isAppForPackageADebuggableBuild(termuxPackageContext) ? "1" : "0"; - - TERMUX_APP_PID = TermuxUtils.getTermuxAppPID(currentPackageContext); - - // Getting APK signature is a slightly expensive operation, so do it only when needed - if (termuxAPKReleaseOld == null) { - String signingCertificateSHA256Digest = PackageUtils.getSigningCertificateSHA256DigestForPackage(termuxPackageContext); - if (signingCertificateSHA256Digest != null) - TERMUX_APK_RELEASE = TermuxUtils.getAPKRelease(signingCertificateSHA256Digest).replaceAll("[^a-zA-Z]", "_").toUpperCase(); - } else { - TERMUX_APK_RELEASE = termuxAPKReleaseOld; - } - } - } - - - TERMUX_API_VERSION_NAME = null; - - // Check if Termux:API app is installed and not disabled - if (TermuxUtils.isTermuxAPIAppInstalled(currentPackageContext) == null) { - // This function may be called by a different package like a plugin, so we get version for Termux:API package via its context - Context termuxAPIPackageContext = TermuxUtils.getTermuxAPIPackageContext(currentPackageContext); - if (termuxAPIPackageContext != null) - TERMUX_API_VERSION_NAME = PackageUtils.getVersionNameForPackage(termuxAPIPackageContext); - } - } - } diff --git a/termux-shared/src/main/java/com/termux/shared/termux/shell/am/TermuxAmSocketServer.java b/termux-shared/src/main/java/com/termux/shared/termux/shell/am/TermuxAmSocketServer.java index 32116b30..e6c293e9 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/shell/am/TermuxAmSocketServer.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/shell/am/TermuxAmSocketServer.java @@ -2,6 +2,7 @@ package com.termux.shared.termux.shell.am; import android.content.Context; +import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -18,7 +19,7 @@ import com.termux.shared.termux.crash.TermuxCrashUtils; import com.termux.shared.termux.plugins.TermuxPluginUtils; import com.termux.shared.termux.settings.properties.TermuxAppSharedProperties; import com.termux.shared.termux.settings.properties.TermuxPropertyConstants; -import com.termux.shared.termux.shell.TermuxShellUtils; +import com.termux.shared.termux.shell.command.environment.TermuxAppShellEnvironment; /** * A wrapper for {@link AmSocketServer} for termux-app usage. @@ -48,7 +49,7 @@ import com.termux.shared.termux.shell.TermuxShellUtils; * require termux-app to be force stopped and restarted. * * The current state of the server can be checked with the - * {@link TermuxShellUtils#TERMUX_APP_AM_SOCKET_SERVER_ENABLED} env variable, which is exported + * {@link TermuxAppShellEnvironment#ENV_TERMUX_APP__AM_SOCKET_SERVER_ENABLED} env variable, which is exported * for all shell sessions and tasks. * * https://github.com/termux/termux-am-socket @@ -63,6 +64,10 @@ public class TermuxAmSocketServer { /** The static instance for the {@link TermuxAmSocketServer} {@link LocalSocketManager}. */ private static LocalSocketManager termuxAmSocketServer; + /** Whether {@link TermuxAmSocketServer} is enabled and running or not. */ + @Keep + protected static Boolean TERMUX_APP_AM_SOCKET_SERVER_ENABLED; + /** * Setup the {@link AmSocketServer} {@link LocalServerSocket} and start listening for * new {@link LocalClientSocket} if enabled. @@ -86,7 +91,7 @@ public class TermuxAmSocketServer { // Once termux-app has started, the server state must not be changed since the variable is // exported in shell sessions and tasks and if state is changed, then env of older shells will // retain invalid value. User should force stop the app to update state after changing prop. - TermuxShellUtils.TERMUX_APP_AM_SOCKET_SERVER_ENABLED = enabled; + TERMUX_APP_AM_SOCKET_SERVER_ENABLED = enabled; } /** @@ -160,6 +165,21 @@ public class TermuxAmSocketServer { + public static Boolean getTermuxAppAMSocketServerEnabled(@NonNull Context currentPackageContext) { + boolean isTermuxApp = TermuxConstants.TERMUX_PACKAGE_NAME.equals(currentPackageContext.getPackageName()); + if (isTermuxApp) { + return TERMUX_APP_AM_SOCKET_SERVER_ENABLED; + } else { + // Currently, unsupported since plugin app processes don't know that value is set in termux + // app process TermuxAmSocketServer class. A binder API or a way to check if server is actually + // running needs to be used. Long checks would also not be possible on main application thread + return null; + } + + } + + + /** Enhanced implementation for {@link AmSocketServer.AmSocketServerClient} for {@link TermuxAmSocketServer}. */ diff --git a/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxAPIShellEnvironment.java b/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxAPIShellEnvironment.java new file mode 100644 index 00000000..78c4772e --- /dev/null +++ b/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxAPIShellEnvironment.java @@ -0,0 +1,43 @@ +package com.termux.shared.termux.shell.command.environment; + +import android.content.Context; +import android.content.pm.PackageInfo; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.termux.shared.android.PackageUtils; +import com.termux.shared.shell.command.environment.ShellEnvironmentUtils; +import com.termux.shared.termux.TermuxConstants; +import com.termux.shared.termux.TermuxUtils; + +import java.util.HashMap; + +/** + * Environment for {@link TermuxConstants#TERMUX_API_PACKAGE_NAME} app. + */ +public class TermuxAPIShellEnvironment { + + /** Environment variable prefix for the Termux:API app. */ + public static final String TERMUX_API_APP_ENV_PREFIX = TermuxConstants.TERMUX_ENV_PREFIX_ROOT + "_API_APP__"; + + /** Environment variable for the Termux:API app version. */ + public static final String ENV_TERMUX_API_APP__VERSION_NAME = TERMUX_API_APP_ENV_PREFIX + "VERSION_NAME"; + + /** Get shell environment for Termux:API app. */ + @Nullable + public static HashMap getEnvironment(@NonNull Context currentPackageContext) { + if (TermuxUtils.isTermuxAPIAppInstalled(currentPackageContext) != null) return null; + + String packageName = TermuxConstants.TERMUX_API_PACKAGE_NAME; + PackageInfo packageInfo = PackageUtils.getPackageInfoForPackage(currentPackageContext, packageName); + if (packageInfo == null) return null; + + HashMap environment = new HashMap<>(); + + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_API_APP__VERSION_NAME, PackageUtils.getVersionNameForPackage(packageInfo)); + + return environment; + } + +} diff --git a/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxAppShellEnvironment.java b/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxAppShellEnvironment.java new file mode 100644 index 00000000..078afc1b --- /dev/null +++ b/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxAppShellEnvironment.java @@ -0,0 +1,164 @@ +package com.termux.shared.termux.shell.command.environment; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.os.Build; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.termux.shared.android.PackageUtils; +import com.termux.shared.android.SELinuxUtils; +import com.termux.shared.data.DataUtils; +import com.termux.shared.shell.command.environment.ShellEnvironmentUtils; +import com.termux.shared.termux.TermuxBootstrap; +import com.termux.shared.termux.TermuxConstants; +import com.termux.shared.termux.TermuxUtils; +import com.termux.shared.termux.shell.am.TermuxAmSocketServer; + +import java.util.HashMap; + +/** + * Environment for {@link TermuxConstants#TERMUX_PACKAGE_NAME} app. + */ +public class TermuxAppShellEnvironment { + + /** Termux app environment variables. */ + public static HashMap termuxAppEnvironment; + + /** Environment variable for the Termux app version. */ + public static final String ENV_TERMUX_VERSION = TermuxConstants.TERMUX_ENV_PREFIX_ROOT + "_VERSION"; + + /** Environment variable prefix for the Termux app. */ + public static final String TERMUX_APP_ENV_PREFIX = TermuxConstants.TERMUX_ENV_PREFIX_ROOT + "_APP__"; + + /** Environment variable for the Termux app version name. */ + public static final String ENV_TERMUX_APP__VERSION_NAME = TERMUX_APP_ENV_PREFIX + "VERSION_NAME"; + /** Environment variable for the Termux app version code. */ + public static final String ENV_TERMUX_APP__VERSION_CODE = TERMUX_APP_ENV_PREFIX + "VERSION_CODE"; + /** Environment variable for the Termux app package name. */ + public static final String ENV_TERMUX_APP__PACKAGE_NAME = TERMUX_APP_ENV_PREFIX + "PACKAGE_NAME"; + /** Environment variable for the Termux app process id. */ + public static final String ENV_TERMUX_APP__PID = TERMUX_APP_ENV_PREFIX + "PID"; + /** Environment variable for the Termux app uid. */ + public static final String ENV_TERMUX_APP__UID = TERMUX_APP_ENV_PREFIX + "UID"; + /** Environment variable for the Termux app targetSdkVersion. */ + public static final String ENV_TERMUX_APP__TARGET_SDK = TERMUX_APP_ENV_PREFIX + "TARGET_SDK"; + /** Environment variable for the Termux app is debuggable apk build. */ + public static final String ENV_TERMUX_APP__IS_DEBUGGABLE_BUILD = TERMUX_APP_ENV_PREFIX + "IS_DEBUGGABLE_BUILD"; + /** Environment variable for the Termux app {@link TermuxConstants} APK_RELEASE_*. */ + public static final String ENV_TERMUX_APP__APK_RELEASE = TERMUX_APP_ENV_PREFIX + "APK_RELEASE"; + /** Environment variable for the Termux app install path. */ + public static final String ENV_TERMUX_APP__APK_PATH = TERMUX_APP_ENV_PREFIX + "APK_PATH"; + /** Environment variable for the Termux app is installed on external/portable storage. */ + public static final String ENV_TERMUX_APP__IS_INSTALLED_ON_EXTERNAL_STORAGE = TERMUX_APP_ENV_PREFIX + "IS_INSTALLED_ON_EXTERNAL_STORAGE"; + + /** Environment variable for the Termux app process selinux context. */ + public static final String ENV_TERMUX_APP__SE_PROCESS_CONTEXT = TERMUX_APP_ENV_PREFIX + "SE_PROCESS_CONTEXT"; + /** Environment variable for the Termux app data files selinux context. */ + public static final String ENV_TERMUX_APP__SE_FILE_CONTEXT = TERMUX_APP_ENV_PREFIX + "SE_FILE_CONTEXT"; + /** Environment variable for the Termux app seInfo tag found in selinux policy used to set app process and app data files selinux context. */ + public static final String ENV_TERMUX_APP__SE_INFO = TERMUX_APP_ENV_PREFIX + "SE_INFO"; + /** Environment variable for the Termux app user id. */ + public static final String ENV_TERMUX_APP__USER_ID = TERMUX_APP_ENV_PREFIX + "USER_ID"; + /** Environment variable for the Termux app profile owner. */ + public static final String ENV_TERMUX_APP__PROFILE_OWNER = TERMUX_APP_ENV_PREFIX + "PROFILE_OWNER"; + + /** Environment variable for the Termux app {@link TermuxBootstrap#TERMUX_APP_PACKAGE_MANAGER}. */ + public static final String ENV_TERMUX_APP__PACKAGE_MANAGER = TERMUX_APP_ENV_PREFIX + "PACKAGE_MANAGER"; + /** Environment variable for the Termux app {@link TermuxBootstrap#TERMUX_APP_PACKAGE_VARIANT}. */ + public static final String ENV_TERMUX_APP__PACKAGE_VARIANT = TERMUX_APP_ENV_PREFIX + "PACKAGE_VARIANT"; + /** Environment variable for the Termux app files directory. */ + public static final String ENV_TERMUX_APP__FILES_DIR = TERMUX_APP_ENV_PREFIX + "FILES_DIR"; + + + /** Environment variable for the Termux app {@link TermuxAmSocketServer#getTermuxAppAMSocketServerEnabled(Context)}. */ + public static final String ENV_TERMUX_APP__AM_SOCKET_SERVER_ENABLED = TERMUX_APP_ENV_PREFIX + "AM_SOCKET_SERVER_ENABLED"; + + + + /** Get shell environment for Termux app. */ + @Nullable + public static HashMap getEnvironment(@NonNull Context currentPackageContext) { + setTermuxAppEnvironment(currentPackageContext); + return termuxAppEnvironment; + } + + /** Set Termux app environment variables in {@link #termuxAppEnvironment}. */ + public synchronized static void setTermuxAppEnvironment(@NonNull Context currentPackageContext) { + boolean isTermuxApp = TermuxConstants.TERMUX_PACKAGE_NAME.equals(currentPackageContext.getPackageName()); + + // If current package context is of termux app and its environment is already set, then no need to set again since it won't change + // Other apps should always set environment again since termux app may be installed/updated/deleted in background + if (termuxAppEnvironment != null && isTermuxApp) + return; + + termuxAppEnvironment = null; + + String packageName = TermuxConstants.TERMUX_PACKAGE_NAME; + PackageInfo packageInfo = PackageUtils.getPackageInfoForPackage(currentPackageContext, packageName); + if (packageInfo == null) return; + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfoForPackage(currentPackageContext, packageName); + if (applicationInfo == null || !applicationInfo.enabled) return; + + HashMap environment = new HashMap<>(); + + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_VERSION, PackageUtils.getVersionNameForPackage(packageInfo)); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__VERSION_NAME, PackageUtils.getVersionNameForPackage(packageInfo)); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__VERSION_CODE, String.valueOf(PackageUtils.getVersionCodeForPackage(packageInfo))); + + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__PACKAGE_NAME, packageName); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__PID, TermuxUtils.getTermuxAppPID(currentPackageContext)); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__UID, String.valueOf(PackageUtils.getUidForPackage(applicationInfo))); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__TARGET_SDK, String.valueOf(PackageUtils.getTargetSDKForPackage(applicationInfo))); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__IS_DEBUGGABLE_BUILD, PackageUtils.isAppForPackageADebuggableBuild(applicationInfo)); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__APK_PATH, PackageUtils.getBaseAPKPathForPackage(applicationInfo)); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__IS_INSTALLED_ON_EXTERNAL_STORAGE, PackageUtils.isAppInstalledOnExternalStorage(applicationInfo)); + + putTermuxAPKSignature(currentPackageContext, environment); + + Context termuxPackageContext = TermuxUtils.getTermuxPackageContext(currentPackageContext); + if (termuxPackageContext != null) { + // An app that does not have the same sharedUserId as termux app will not be able to get + // get termux context's classloader to get BuildConfig.TERMUX_PACKAGE_VARIANT via reflection. + // Check TermuxBootstrap.setTermuxPackageManagerAndVariantFromTermuxApp() + if (TermuxBootstrap.TERMUX_APP_PACKAGE_MANAGER != null) + environment.put(ENV_TERMUX_APP__PACKAGE_MANAGER, TermuxBootstrap.TERMUX_APP_PACKAGE_MANAGER.getName()); + if (TermuxBootstrap.TERMUX_APP_PACKAGE_VARIANT != null) + environment.put(ENV_TERMUX_APP__PACKAGE_VARIANT, TermuxBootstrap.TERMUX_APP_PACKAGE_VARIANT.getName()); + + // Will not be set for plugins + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__AM_SOCKET_SERVER_ENABLED, + TermuxAmSocketServer.getTermuxAppAMSocketServerEnabled(currentPackageContext)); + + String filesDirPath = currentPackageContext.getFilesDir().getAbsolutePath(); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__FILES_DIR, filesDirPath); + + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__SE_PROCESS_CONTEXT, SELinuxUtils.getContext()); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__SE_FILE_CONTEXT, SELinuxUtils.getFileContext(filesDirPath)); + + String seInfoUser = PackageUtils.getApplicationInfoSeInfoUserForPackage(applicationInfo); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__SE_INFO, PackageUtils.getApplicationInfoSeInfoForPackage(applicationInfo) + + (DataUtils.isNullOrEmpty(seInfoUser) ? "" : seInfoUser)); + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__USER_ID, String.valueOf(PackageUtils.getUserIdForPackage(currentPackageContext))); + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__PROFILE_OWNER, PackageUtils.getProfileOwnerPackageNameForUser(currentPackageContext)); + } + + termuxAppEnvironment = environment; + } + + /** Put {@link #ENV_TERMUX_APP__APK_RELEASE} in {@code environment}. */ + public static void putTermuxAPKSignature(@NonNull Context currentPackageContext, + @NonNull HashMap environment) { + String signingCertificateSHA256Digest = PackageUtils.getSigningCertificateSHA256DigestForPackage(currentPackageContext, + TermuxConstants.TERMUX_PACKAGE_NAME); + if (signingCertificateSHA256Digest != null) { + ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__APK_RELEASE, + TermuxUtils.getAPKRelease(signingCertificateSHA256Digest).replaceAll("[^a-zA-Z]", "_").toUpperCase()); + } + } + +} diff --git a/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxShellEnvironment.java b/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxShellEnvironment.java index 24d10f7b..0677c20f 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxShellEnvironment.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/shell/command/environment/TermuxShellEnvironment.java @@ -32,6 +32,14 @@ public class TermuxShellEnvironment extends AndroidShellEnvironment { // Termux environment builds upon the Android environment HashMap environment = super.getEnvironment(currentPackageContext, isFailSafe); + HashMap termuxAppEnvironment = TermuxAppShellEnvironment.getEnvironment(currentPackageContext); + if (termuxAppEnvironment != null) + environment.putAll(termuxAppEnvironment); + + HashMap termuxApiAppEnvironment = TermuxAPIShellEnvironment.getEnvironment(currentPackageContext); + if (termuxApiAppEnvironment != null) + environment.putAll(termuxApiAppEnvironment); + environment.put(ENV_HOME, TermuxConstants.TERMUX_HOME_DIR_PATH); environment.put(ENV_PREFIX, TermuxConstants.TERMUX_PREFIX_DIR_PATH);