Extract tooling-api-all.jar at startup

This commit is contained in:
Akash Yadav
2022-04-29 17:59:16 +05:30
parent 1331ff89c7
commit 53f55ed390
3 changed files with 124 additions and 96 deletions
@@ -31,10 +31,13 @@ import org.jetbrains.annotations.Contract;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
public class ToolsManager {
public static final int TOOLING_API_VERSION = 1;
public static final int LOG_SENDER_VERSION = 2;
public static final String KEY_TOOLING_API_VERSION = "tools_toolingApiVersion";
public static final String KEY_LOG_SENDER_VERSION = "tools_logsenderVersion";
private static final ILogger LOG = ILogger.newInstance("ToolsManager");
public static String ARCH_SPECIFIC_ASSET_DATA_DIR = "data/" + BaseApplication.getArch();
@@ -50,15 +53,64 @@ public class ToolsManager {
prefs = app.getPrefManager();
copyBusyboxIfNeeded();
extractLogsenderIfNeeded();
extractLibHooks();
extractGradlePlugin();
writeInitScript();
rewriteProjectData();
CompletableFuture.runAsync(
() -> {
copyBusyboxIfNeeded();
extractLogsenderIfNeeded();
extractLibHooks();
extractGradlePlugin();
extractToolingApi();
writeInitScript();
rewriteProjectData();
})
.whenComplete(
(__, error) -> {
if (error != null) {
LOG.error("Error extracting tools", error);
}
if (onFinish != null) {
onFinish.run();
if (onFinish != null) {
onFinish.run();
}
});
}
private static void copyBusyboxIfNeeded() {
File exec = Environment.BUSYBOX;
if (exec.exists()) return;
Environment.mkdirIfNotExits(exec.getParentFile());
ResourceUtils.copyFileFromAssets(getArchSpecificAsset("busybox"), exec.getAbsolutePath());
if (!exec.canExecute()) {
if (!exec.setExecutable(true)) {
LOG.error("Cannot set busybox executable permissions.");
}
}
}
private static void extractLogsenderIfNeeded() {
try {
final boolean isOld = LOG_SENDER_VERSION > prefs.getInt(KEY_LOG_SENDER_VERSION, 0);
if (isOld) {
final File logsenderZip = new File(Environment.TMP_DIR, "logsender.zip");
ResourceUtils.copyFileFromAssets(
getCommonAsset("logsender.zip"), logsenderZip.getAbsolutePath());
ZipUtils.unzipFile(logsenderZip, Environment.HOME);
prefs.putInt(KEY_LOG_SENDER_VERSION, LOG_SENDER_VERSION);
}
} catch (IOException e) {
LOG.error("Error extracting log sender", e);
}
}
public static void extractLibHooks() {
if (!Environment.LIB_HOOK.exists()) {
ResourceUtils.copyFileFromAssets(
getArchSpecificAsset("libhook.so"), Environment.LIB_HOOK.getAbsolutePath());
}
if (!Environment.LIB_HOOK2.exists()) {
ResourceUtils.copyFileFromAssets(
getArchSpecificAsset("libhook2.so"), Environment.LIB_HOOK2.getAbsolutePath());
}
}
@@ -80,31 +132,12 @@ public class ToolsManager {
}
}
public static void extractLibHooks() {
if (!Environment.LIB_HOOK.exists()) {
private static void extractToolingApi() {
final var currentVersion = prefs.getInt(KEY_TOOLING_API_VERSION, 0);
if (!Environment.TOOLING_API_JAR.exists() || currentVersion < TOOLING_API_VERSION) {
ResourceUtils.copyFileFromAssets(
getArchSpecificAsset("libhook.so"), Environment.LIB_HOOK.getAbsolutePath());
}
if (!Environment.LIB_HOOK2.exists()) {
ResourceUtils.copyFileFromAssets(
getArchSpecificAsset("libhook2.so"), Environment.LIB_HOOK2.getAbsolutePath());
}
}
private static void rewriteProjectData() {
FileIOUtils.writeFileFromString(Environment.PROJECT_DATA_FILE, "/**********************/");
}
private static void copyBusyboxIfNeeded() {
File exec = Environment.BUSYBOX;
if (exec.exists()) return;
Environment.mkdirIfNotExits(exec.getParentFile());
ResourceUtils.copyFileFromAssets(getArchSpecificAsset("busybox"), exec.getAbsolutePath());
if (!exec.canExecute()) {
if (!exec.setExecutable(true)) {
LOG.error("Cannot set busybox executable permissions.");
}
getCommonAsset("tooling-api-all.jar"),
Environment.TOOLING_API_JAR.getAbsolutePath());
}
}
@@ -115,24 +148,8 @@ public class ToolsManager {
FileIOUtils.writeFileFromString(Environment.INIT_SCRIPT, readInitScript());
}
@NonNull
private static String readInitScript() {
return ResourceUtils.readAssets2String(getCommonAsset("androidide.init.gradle"));
}
private static void extractLogsenderIfNeeded() {
try {
final boolean isOld = LOG_SENDER_VERSION > prefs.getInt(KEY_LOG_SENDER_VERSION, 0);
if (isOld) {
final File logsenderZip = new File(Environment.TMP_DIR, "logsender.zip");
ResourceUtils.copyFileFromAssets(
getCommonAsset("logsender.zip"), logsenderZip.getAbsolutePath());
ZipUtils.unzipFile(logsenderZip, Environment.HOME);
prefs.putInt(KEY_LOG_SENDER_VERSION, LOG_SENDER_VERSION);
}
} catch (IOException e) {
LOG.error("Error extracting log sender", e);
}
private static void rewriteProjectData() {
FileIOUtils.writeFileFromString(Environment.PROJECT_DATA_FILE, "/**********************/");
}
@NonNull
@@ -146,4 +163,9 @@ public class ToolsManager {
public static String getCommonAsset(String name) {
return COMMON_ASSET_DATA_DIR + "/" + name;
}
@NonNull
private static String readInitScript() {
return ResourceUtils.readAssets2String(getCommonAsset("androidide.init.gradle"));
}
}
@@ -64,6 +64,8 @@ public final class Environment {
*/
public static File COMPILER_MODULE;
public static File TOOLING_API_JAR;
public static File INIT_SCRIPT;
public static File PROJECT_DATA_FILE;
public static File GRADLE_PROPS;
@@ -85,6 +87,10 @@ public final class Environment {
LIB_DIR = mkdirIfNotExits(new File(SYSROOT, "lib"));
PROJECTS_DIR = mkdirIfNotExits(new File(FileUtil.getExternalStorageDir(), PROJECTS_FOLDER));
COMPILER_MODULE = mkdirIfNotExits(new File(ANDROIDIDE_HOME, "compiler-module"));
TOOLING_API_JAR =
new File(
mkdirIfNotExits(new File(ANDROIDIDE_HOME, "tooling-api")),
"tooling-api-all.jar");
IDE_PROPS_FILE = new File(SYSROOT, "etc/ide-environment.properties");
LIB_HOOK = new File(LIB_DIR, "libhook.so");
@@ -116,10 +122,12 @@ public final class Environment {
System.setProperty("java.home", JAVA_HOME.getAbsolutePath());
}
public static void setExecutable(@NonNull final File file) {
if (!file.setExecutable(true)) {
LOG.error("Unable to set executable permissions to file", file);
public static File mkdirIfNotExits(File in) {
if (in != null && !in.exists()) {
FileUtils.createOrExistsDir(in);
}
return in;
}
@NonNull
@@ -140,6 +148,40 @@ public final class Environment {
return props;
}
public static String readProp(String key, String defaultValue) {
String value = IDE_PROPS.getOrDefault(key, defaultValue);
if (value == null) {
return defaultValue;
}
if (value.contains("$HOME")) {
value = value.replace("$HOME", HOME.getAbsolutePath());
}
if (value.contains("$SYSROOT")) {
value = value.replace("$SYSROOT", SYSROOT.getAbsolutePath());
}
if (value.contains("$PATH")) {
value = value.replace("$PATH", createPath());
}
return value;
}
public static void setExecutable(@NonNull final File file) {
if (!file.setExecutable(true)) {
LOG.error("Unable to set executable permissions to file", file);
}
}
@NonNull
private static String createPath() {
String path = "";
path += String.format("%s/bin", JAVA_HOME.getAbsolutePath());
path += String.format(":%s/cmdline-tools/latest/bin", ANDROID_HOME.getAbsolutePath());
path += String.format(":%s/cmake/bin", ANDROID_HOME.getAbsolutePath());
path += String.format(":%s/bin", SYSROOT.getAbsolutePath());
path += String.format(":%s", System.getenv("PATH"));
return path;
}
public static void setBootClasspath(@NonNull File file) {
BOOTCLASSPATH = new File(file.getAbsolutePath());
}
@@ -205,17 +247,6 @@ public final class Environment {
return ENV_VARS;
}
@NonNull
private static String createPath() {
String path = "";
path += String.format("%s/bin", JAVA_HOME.getAbsolutePath());
path += String.format(":%s/cmdline-tools/latest/bin", ANDROID_HOME.getAbsolutePath());
path += String.format(":%s/cmake/bin", ANDROID_HOME.getAbsolutePath());
path += String.format(":%s/bin", SYSROOT.getAbsolutePath());
path += String.format(":%s", System.getenv("PATH"));
return path;
}
public static void addToEnvIfPresent(Map<String, String> environment, String name) {
String value = System.getenv(name);
if (value != null) {
@@ -223,38 +254,6 @@ public final class Environment {
}
}
public static String readProp(String key, String defaultValue) {
String value = IDE_PROPS.getOrDefault(key, defaultValue);
if (value == null) {
return defaultValue;
}
if (value.contains("$HOME")) {
value = value.replace("$HOME", HOME.getAbsolutePath());
}
if (value.contains("$SYSROOT")) {
value = value.replace("$SYSROOT", SYSROOT.getAbsolutePath());
}
if (value.contains("$PATH")) {
value = value.replace("$PATH", createPath());
}
return value;
}
public static File mkdirIfNotExits(File in) {
if (in != null && !in.exists()) {
FileUtils.createOrExistsDir(in);
}
return in;
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isCompilerModuleInstalled() {
final var modules = new File(COMPILER_MODULE, "lib/modules");
final var release = new File(COMPILER_MODULE, "release");
return modules.exists() && modules.isFile() && release.exists() && release.isFile();
}
private static List<String> blacklistedVariables() {
if (blacklist.isEmpty()) {
blacklist.add("HOME");
@@ -263,4 +262,11 @@ public final class Environment {
}
return blacklist;
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public static boolean isCompilerModuleInstalled() {
final var modules = new File(COMPILER_MODULE, "lib/modules");
final var release = new File(COMPILER_MODULE, "release");
return modules.exists() && modules.isFile() && release.exists() && release.isFile();
}
}