mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-06 02:35:19 +08:00
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`)
This commit is contained in:
@@ -11,7 +11,7 @@ import java.util.Formatter;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Version: v0.48.0
|
* Version: v0.49.0
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* Changelog
|
* Changelog
|
||||||
@@ -265,6 +265,9 @@ import java.util.List;
|
|||||||
* - 0.48.0 (2022-06-04)
|
* - 0.48.0 (2022-06-04)
|
||||||
* - Removed `TERMUX_GAME_PACKAGES_GITHUB_*`, `TERMUX_SCIENCE_PACKAGES_GITHUB_*`,
|
* - Removed `TERMUX_GAME_PACKAGES_GITHUB_*`, `TERMUX_SCIENCE_PACKAGES_GITHUB_*`,
|
||||||
* `TERMUX_ROOT_PACKAGES_GITHUB_*`, `TERMUX_UNSTABLE_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} */
|
* may be used instead of {@link #COMMA_NORMAL} */
|
||||||
public static final String COMMA_ALTERNATIVE = "‚"; // Default: "‚"
|
public static final String COMMA_ALTERNATIVE = "‚"; // Default: "‚"
|
||||||
|
|
||||||
|
/** Environment variable prefix root for the Termux app. */
|
||||||
|
public static final String TERMUX_ENV_PREFIX_ROOT = "TERMUX";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,7 +1,5 @@
|
|||||||
package com.termux.shared.termux.shell;
|
package com.termux.shared.termux.shell;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
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.termux.TermuxConstants;
|
||||||
import com.termux.shared.file.FileUtils;
|
import com.termux.shared.file.FileUtils;
|
||||||
import com.termux.shared.logger.Logger;
|
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 com.termux.shared.termux.settings.properties.TermuxAppSharedProperties;
|
||||||
|
|
||||||
import org.apache.commons.io.filefilter.TrueFileFilter;
|
import org.apache.commons.io.filefilter.TrueFileFilter;
|
||||||
@@ -27,32 +23,6 @@ public class TermuxShellUtils {
|
|||||||
|
|
||||||
private static final String LOG_TAG = "TermuxShellUtils";
|
private static final String LOG_TAG = "TermuxShellUtils";
|
||||||
|
|
||||||
|
|
||||||
public static String[] buildEnvironment(Context currentPackageContext, boolean isFailSafe, String workingDirectory) {
|
|
||||||
TermuxConstants.TERMUX_HOME_DIR.mkdirs();
|
|
||||||
List<String> 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
|
* Setup shell command arguments for the execute. The file interpreter may be prefixed to
|
||||||
* command arguments if needed.
|
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package com.termux.shared.termux.shell.am;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.annotation.Keep;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
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.plugins.TermuxPluginUtils;
|
||||||
import com.termux.shared.termux.settings.properties.TermuxAppSharedProperties;
|
import com.termux.shared.termux.settings.properties.TermuxAppSharedProperties;
|
||||||
import com.termux.shared.termux.settings.properties.TermuxPropertyConstants;
|
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.
|
* 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.
|
* require termux-app to be force stopped and restarted.
|
||||||
*
|
*
|
||||||
* The current state of the server can be checked with the
|
* 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.
|
* for all shell sessions and tasks.
|
||||||
*
|
*
|
||||||
* https://github.com/termux/termux-am-socket
|
* https://github.com/termux/termux-am-socket
|
||||||
@@ -63,6 +64,10 @@ public class TermuxAmSocketServer {
|
|||||||
/** The static instance for the {@link TermuxAmSocketServer} {@link LocalSocketManager}. */
|
/** The static instance for the {@link TermuxAmSocketServer} {@link LocalSocketManager}. */
|
||||||
private static LocalSocketManager termuxAmSocketServer;
|
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
|
* Setup the {@link AmSocketServer} {@link LocalServerSocket} and start listening for
|
||||||
* new {@link LocalClientSocket} if enabled.
|
* 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
|
// 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
|
// 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.
|
// 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}. */
|
/** Enhanced implementation for {@link AmSocketServer.AmSocketServerClient} for {@link TermuxAmSocketServer}. */
|
||||||
|
@@ -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<String, String> 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<String, String> environment = new HashMap<>();
|
||||||
|
|
||||||
|
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_API_APP__VERSION_NAME, PackageUtils.getVersionNameForPackage(packageInfo));
|
||||||
|
|
||||||
|
return environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -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<String, String> 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<String, String> 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<String, String> 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<String, String> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -32,6 +32,14 @@ public class TermuxShellEnvironment extends AndroidShellEnvironment {
|
|||||||
// Termux environment builds upon the Android environment
|
// Termux environment builds upon the Android environment
|
||||||
HashMap<String, String> environment = super.getEnvironment(currentPackageContext, isFailSafe);
|
HashMap<String, String> environment = super.getEnvironment(currentPackageContext, isFailSafe);
|
||||||
|
|
||||||
|
HashMap<String, String> termuxAppEnvironment = TermuxAppShellEnvironment.getEnvironment(currentPackageContext);
|
||||||
|
if (termuxAppEnvironment != null)
|
||||||
|
environment.putAll(termuxAppEnvironment);
|
||||||
|
|
||||||
|
HashMap<String, String> termuxApiAppEnvironment = TermuxAPIShellEnvironment.getEnvironment(currentPackageContext);
|
||||||
|
if (termuxApiAppEnvironment != null)
|
||||||
|
environment.putAll(termuxApiAppEnvironment);
|
||||||
|
|
||||||
environment.put(ENV_HOME, TermuxConstants.TERMUX_HOME_DIR_PATH);
|
environment.put(ENV_HOME, TermuxConstants.TERMUX_HOME_DIR_PATH);
|
||||||
environment.put(ENV_PREFIX, TermuxConstants.TERMUX_PREFIX_DIR_PATH);
|
environment.put(ENV_PREFIX, TermuxConstants.TERMUX_PREFIX_DIR_PATH);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user