1
0
mirror of https://github.com/termux/termux-app synced 2024-06-21 08:37:10 +00:00
termux-app/termux-shared/src/main/java/com/termux/shared/termux/TermuxBootstrap.java

220 lines
8.5 KiB
Java

package com.termux.shared.termux;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.termux.shared.logger.Logger;
import com.termux.shared.termux.TermuxConstants.TERMUX_APP;
public class TermuxBootstrap {
private static final String LOG_TAG = "TermuxBootstrap";
/** The field name used by Termux app to store package variant in
* {@link TERMUX_APP#BUILD_CONFIG_CLASS_NAME} class. */
public static final String BUILD_CONFIG_FIELD_TERMUX_PACKAGE_VARIANT = "TERMUX_PACKAGE_VARIANT";
/** The {@link PackageManager} for the bootstrap in the app APK added in app/build.gradle. */
public static PackageManager TERMUX_APP_PACKAGE_MANAGER;
/** The {@link PackageVariant} for the bootstrap in the app APK added in app/build.gradle. */
public static PackageVariant TERMUX_APP_PACKAGE_VARIANT;
/** Set {@link #TERMUX_APP_PACKAGE_VARIANT} and {@link #TERMUX_APP_PACKAGE_MANAGER} from {@code packageVariantName} passed. */
public static void setTermuxPackageManagerAndVariant(@Nullable String packageVariantName) {
TERMUX_APP_PACKAGE_VARIANT = PackageVariant.variantOf(packageVariantName);
if (TERMUX_APP_PACKAGE_VARIANT == null) {
throw new RuntimeException("Unsupported TERMUX_APP_PACKAGE_VARIANT \"" + packageVariantName + "\"");
}
Logger.logVerbose(LOG_TAG, "Set TERMUX_APP_PACKAGE_VARIANT to \"" + TERMUX_APP_PACKAGE_VARIANT + "\"");
// Set packageManagerName to substring before first dash "-" in packageVariantName
int index = packageVariantName.indexOf('-');
String packageManagerName = (index == -1) ? null : packageVariantName.substring(0, index);
TERMUX_APP_PACKAGE_MANAGER = PackageManager.managerOf(packageManagerName);
if (TERMUX_APP_PACKAGE_MANAGER == null) {
throw new RuntimeException("Unsupported TERMUX_APP_PACKAGE_MANAGER \"" + packageManagerName + "\" with variant \"" + packageVariantName + "\"");
}
Logger.logVerbose(LOG_TAG, "Set TERMUX_APP_PACKAGE_MANAGER to \"" + TERMUX_APP_PACKAGE_MANAGER + "\"");
}
/**
* Set {@link #TERMUX_APP_PACKAGE_VARIANT} and {@link #TERMUX_APP_PACKAGE_MANAGER} with the
* {@link #BUILD_CONFIG_FIELD_TERMUX_PACKAGE_VARIANT} field value from the
* {@link TERMUX_APP#BUILD_CONFIG_CLASS_NAME} class of the Termux app APK installed on the device.
* This can only be used by apps that share `sharedUserId` with the Termux app and can be used
* by plugin apps.
*
* @param currentPackageContext The context of current package.
*/
public static void setTermuxPackageManagerAndVariantFromTermuxApp(@NonNull Context currentPackageContext) {
String packageVariantName = getTermuxAppBuildConfigPackageVariantFromTermuxApp(currentPackageContext);
if (packageVariantName != null) {
TermuxBootstrap.setTermuxPackageManagerAndVariant(packageVariantName);
} else {
Logger.logError(LOG_TAG, "Failed to set TERMUX_APP_PACKAGE_VARIANT and TERMUX_APP_PACKAGE_MANAGER from the termux app");
}
}
/**
* Get {@link #BUILD_CONFIG_FIELD_TERMUX_PACKAGE_VARIANT} field value from the
* {@link TERMUX_APP#BUILD_CONFIG_CLASS_NAME} class of the Termux app APK installed on the device.
* This can only be used by apps that share `sharedUserId` with the Termux app.
*
* @param currentPackageContext The context of current package.
* @return Returns the field value, otherwise {@code null} if an exception was raised or failed
* to get termux app package context.
*/
public static String getTermuxAppBuildConfigPackageVariantFromTermuxApp(@NonNull Context currentPackageContext) {
try {
return (String) TermuxUtils.getTermuxAppAPKBuildConfigClassField(currentPackageContext, BUILD_CONFIG_FIELD_TERMUX_PACKAGE_VARIANT);
} catch (Exception e) {
Logger.logStackTraceWithMessage(LOG_TAG, "Failed to get \"" + BUILD_CONFIG_FIELD_TERMUX_PACKAGE_VARIANT + "\" value from \"" + TERMUX_APP.BUILD_CONFIG_CLASS_NAME + "\" class", e);
return null;
}
}
/** Is {@link PackageManager#APT} set as {@link #TERMUX_APP_PACKAGE_MANAGER}. */
public static boolean isAppPackageManagerAPT() {
return PackageManager.APT.equals(TERMUX_APP_PACKAGE_MANAGER);
}
///** Is {@link PackageManager#TAPM} set as {@link #TERMUX_APP_PACKAGE_MANAGER}. */
//public static boolean isAppPackageManagerTAPM() {
// return PackageManager.TAPM.equals(TERMUX_APP_PACKAGE_MANAGER);
//}
///** Is {@link PackageManager#PACMAN} set as {@link #TERMUX_APP_PACKAGE_MANAGER}. */
//public static boolean isAppPackageManagerPACMAN() {
// return PackageManager.PACMAN.equals(TERMUX_APP_PACKAGE_MANAGER);
//}
/** Is {@link PackageVariant#APT_ANDROID_7} set as {@link #TERMUX_APP_PACKAGE_VARIANT}. */
public static boolean isAppPackageVariantAPTAndroid7() {
return PackageVariant.APT_ANDROID_7.equals(TERMUX_APP_PACKAGE_VARIANT);
}
/** Is {@link PackageVariant#APT_ANDROID_5} set as {@link #TERMUX_APP_PACKAGE_VARIANT}. */
public static boolean isAppPackageVariantAPTAndroid5() {
return PackageVariant.APT_ANDROID_5.equals(TERMUX_APP_PACKAGE_VARIANT);
}
///** Is {@link PackageVariant#TAPM_ANDROID_7} set as {@link #TERMUX_APP_PACKAGE_VARIANT}. */
//public static boolean isAppPackageVariantTAPMAndroid7() {
// return PackageVariant.TAPM_ANDROID_7.equals(TERMUX_APP_PACKAGE_VARIANT);
//}
///** Is {@link PackageVariant#PACMAN_ANDROID_7} set as {@link #TERMUX_APP_PACKAGE_VARIANT}. */
//public static boolean isAppPackageVariantTPACMANAndroid7() {
// return PackageVariant.PACMAN_ANDROID_7.equals(TERMUX_APP_PACKAGE_VARIANT);
//}
/** Termux package manager. */
public enum PackageManager {
/**
* Advanced Package Tool (APT) for managing debian deb package files.
* https://wiki.debian.org/Apt
* https://wiki.debian.org/deb
*/
APT("apt");
///**
// * Termux Android Package Manager (TAPM) for managing termux apk package files.
// * https://en.wikipedia.org/wiki/Apk_(file_format)
// */
//TAPM("tapm");
///**
// * Package Manager (PACMAN) for managing arch linux pkg.tar package files.
// * https://wiki.archlinux.org/title/pacman
// * https://en.wikipedia.org/wiki/Arch_Linux#Pacman
// */
//PACMAN("pacman");
private final String name;
PackageManager(final String name) {
this.name = name;
}
public String getName() {
return name;
}
public boolean equalsManager(String manager) {
return manager != null && manager.equals(this.name);
}
/** Get {@link PackageManager} for {@code name} if found, otherwise {@code null}. */
@Nullable
public static PackageManager managerOf(String name) {
if (name == null || name.isEmpty()) return null;
for (PackageManager v : PackageManager.values()) {
if (v.name.equals(name)) {
return v;
}
}
return null;
}
}
/** Termux package variant. The substring before first dash "-" must match one of the {@link PackageManager}. */
public enum PackageVariant {
/** {@link PackageManager#APT} variant for Android 7+. */
APT_ANDROID_7("apt-android-7"),
/** {@link PackageManager#APT} variant for Android 5+. */
APT_ANDROID_5("apt-android-5");
///** {@link PackageManager#TAPM} variant for Android 7+. */
//TAPM_ANDROID_7("tapm-android-7");
///** {@link PackageManager#PACMAN} variant for Android 7+. */
//PACMAN_ANDROID_7("pacman-android-7");
private final String name;
PackageVariant(final String name) {
this.name = name;
}
public String getName() {
return name;
}
public boolean equalsVariant(String variant) {
return variant != null && variant.equals(this.name);
}
/** Get {@link PackageVariant} for {@code name} if found, otherwise {@code null}. */
@Nullable
public static PackageVariant variantOf(String name) {
if (name == null || name.isEmpty()) return null;
for (PackageVariant v : PackageVariant.values()) {
if (v.name.equals(name)) {
return v;
}
}
return null;
}
}
}