You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
add support for loading framework-res.apk for system resources
This commit is contained in:
@@ -21,6 +21,8 @@ import android.os.ParcelFileDescriptor;
|
|||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
|
||||||
|
import com.reandroid.arsc.chunk.PackageBlock;
|
||||||
import com.reandroid.arsc.chunk.TableBlock;
|
import com.reandroid.arsc.chunk.TableBlock;
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
|
||||||
import com.reandroid.arsc.chunk.xml.ResXmlPullParser;
|
import com.reandroid.arsc.chunk.xml.ResXmlPullParser;
|
||||||
@@ -33,6 +35,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@@ -107,9 +110,14 @@ public final class AssetManager {
|
|||||||
*/
|
*/
|
||||||
public AssetManager() {
|
public AssetManager() {
|
||||||
try {
|
try {
|
||||||
// NOTE: this enforces a particular order when specifying the MicroG .apk in classpath
|
tableBlock = new TableBlock();
|
||||||
InputStream inFile = ClassLoader.getSystemClassLoader().getResourceAsStream("resources.arsc");
|
Enumeration<URL> resources = ClassLoader.getSystemClassLoader().getResources("resources.arsc");
|
||||||
tableBlock = TableBlock.load(inFile);
|
while (resources.hasMoreElements()) {
|
||||||
|
URL resource = resources.nextElement();
|
||||||
|
if (!resource.getFile().contains("com.google.android.gms")) { // ignore MicroG .apk
|
||||||
|
tableBlock.merge(TableBlock.load(resource.openStream()));
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(TAG, "failed to load resources.arsc" + e);
|
Log.e(TAG, "failed to load resources.arsc" + e);
|
||||||
}
|
}
|
||||||
@@ -751,8 +759,14 @@ public final class AssetManager {
|
|||||||
*/
|
*/
|
||||||
/*package*/ /*native*/ final int getResourceIdentifier(String name, String type, String defPackage) {
|
/*package*/ /*native*/ final int getResourceIdentifier(String name, String type, String defPackage) {
|
||||||
System.out.println("getResourceIdentifier(" + name + "," + type + "," + defPackage + ") called");
|
System.out.println("getResourceIdentifier(" + name + "," + type + "," + defPackage + ") called");
|
||||||
|
for (PackageBlock packageBlock : tableBlock.listPackages()) {
|
||||||
|
if (packageBlock.getName().equals(defPackage)) {
|
||||||
|
return packageBlock.getEntry("", type, name).getResourceId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return tableBlock.pickOne().getEntry("", type, name).getResourceId();
|
// package not found
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ native final String getResourceName(int resid);
|
/*package*/ native final String getResourceName(int resid);
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ char *construct_classpath(char *prefix, char **cp_array, size_t len)
|
|||||||
|
|
||||||
#define JDWP_ARG "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address="
|
#define JDWP_ARG "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address="
|
||||||
|
|
||||||
JNIEnv* create_vm(char *api_impl_jar, char *apk_classpath, char *microg_apk, char *api_impl_natives_dir, char *app_lib_dir) {
|
JNIEnv* create_vm(char *api_impl_jar, char *apk_classpath, char *microg_apk, char *framework_res_apk, char *api_impl_natives_dir, char *app_lib_dir) {
|
||||||
JavaVM* jvm;
|
JavaVM* jvm;
|
||||||
JNIEnv* env;
|
JNIEnv* env;
|
||||||
JavaVMInitArgs args;
|
JavaVMInitArgs args;
|
||||||
@@ -106,7 +106,7 @@ JNIEnv* create_vm(char *api_impl_jar, char *apk_classpath, char *microg_apk, cha
|
|||||||
|
|
||||||
// microg is purposefully after the apk, so that we get the correct resources.arsc
|
// microg is purposefully after the apk, so that we get the correct resources.arsc
|
||||||
// TODO: request resources.arsc from concrete apk instead of taking the first one in classpath
|
// TODO: request resources.arsc from concrete apk instead of taking the first one in classpath
|
||||||
options[1].optionString = construct_classpath("-Djava.class.path=", (char *[]){api_impl_jar, apk_classpath, microg_apk}, 3);
|
options[1].optionString = construct_classpath("-Djava.class.path=", (char *[]){api_impl_jar, apk_classpath, microg_apk, framework_res_apk}, 4);
|
||||||
options[2].optionString = "-verbose:jni";
|
options[2].optionString = "-verbose:jni";
|
||||||
if(jdwp_port) {
|
if(jdwp_port) {
|
||||||
strncat(jdwp_option_string, jdwp_port, 5); // 5 chars is enough for a port number, and won't overflow our array
|
strncat(jdwp_option_string, jdwp_port, 5); // 5 chars is enough for a port number, and won't overflow our array
|
||||||
@@ -147,9 +147,11 @@ void dl_parse_library_path(const char *path, char *delim);
|
|||||||
#define REL_API_IMPL_JAR_INSTALL_PATH "/android_translation_layer/api-impl.jar"
|
#define REL_API_IMPL_JAR_INSTALL_PATH "/android_translation_layer/api-impl.jar"
|
||||||
#define REL_API_IMPL_NATIVES_INSTALL_PATH "/android_translation_layer/natives"
|
#define REL_API_IMPL_NATIVES_INSTALL_PATH "/android_translation_layer/natives"
|
||||||
#define REL_MICROG_APK_INSTALL_PATH "/microg/com.google.android.gms.apk"
|
#define REL_MICROG_APK_INSTALL_PATH "/microg/com.google.android.gms.apk"
|
||||||
|
#define REL_FRAMEWORK_RES_INSTALL_PATH "/android/framework-res.apk"
|
||||||
|
|
||||||
#define API_IMPL_JAR_PATH_LOCAL "./api-impl.jar"
|
#define API_IMPL_JAR_PATH_LOCAL "./api-impl.jar"
|
||||||
#define MICROG_APK_PATH_LOCAL "./com.google.android.gms.apk"
|
#define MICROG_APK_PATH_LOCAL "./com.google.android.gms.apk"
|
||||||
|
#define FRAMEWORK_RES_PATH_LOCAL "./framework-res.apk"
|
||||||
|
|
||||||
struct jni_callback_data { char *apk_main_activity_class; uint32_t window_width; uint32_t window_height;};
|
struct jni_callback_data { char *apk_main_activity_class; uint32_t window_width; uint32_t window_height;};
|
||||||
static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* hint, struct jni_callback_data *d)
|
static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* hint, struct jni_callback_data *d)
|
||||||
@@ -164,6 +166,7 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h
|
|||||||
char *dex_install_dir;
|
char *dex_install_dir;
|
||||||
char *api_impl_jar;
|
char *api_impl_jar;
|
||||||
char *microg_apk = NULL;
|
char *microg_apk = NULL;
|
||||||
|
char *framework_res_apk = NULL;
|
||||||
int errno_libdir;
|
int errno_libdir;
|
||||||
int errno_localdir;
|
int errno_localdir;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -273,6 +276,28 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = stat(FRAMEWORK_RES_PATH_LOCAL, &dont_care);
|
||||||
|
errno_localdir = errno;
|
||||||
|
if(!ret) {
|
||||||
|
framework_res_apk = strdup(FRAMEWORK_RES_PATH_LOCAL); // for running out of builddir; using strdup so we can always safely call free on this
|
||||||
|
} else {
|
||||||
|
char *framework_res_install_dir = malloc(strlen(dex_install_dir) + strlen(REL_FRAMEWORK_RES_INSTALL_PATH) + 1); // +1 for NULL
|
||||||
|
strcpy(framework_res_install_dir, dex_install_dir);
|
||||||
|
strcat(framework_res_install_dir, REL_FRAMEWORK_RES_INSTALL_PATH);
|
||||||
|
|
||||||
|
ret = stat(framework_res_install_dir, &dont_care);
|
||||||
|
errno_libdir = errno;
|
||||||
|
if(!ret) {
|
||||||
|
framework_res_apk = framework_res_install_dir;
|
||||||
|
} else {
|
||||||
|
printf("warning: can't stat framework-res.apk; tried:\n"
|
||||||
|
"\t\"" FRAMEWORK_RES_PATH_LOCAL "\", got - %s\n"
|
||||||
|
"\t\"%s\", got - %s\n",
|
||||||
|
strerror(errno_localdir),
|
||||||
|
framework_res_install_dir, strerror(errno_libdir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *api_impl_natives_dir = malloc(strlen(dex_install_dir) + strlen(REL_API_IMPL_NATIVES_INSTALL_PATH) + 1); // +1 for NULL
|
char *api_impl_natives_dir = malloc(strlen(dex_install_dir) + strlen(REL_API_IMPL_NATIVES_INSTALL_PATH) + 1); // +1 for NULL
|
||||||
strcpy(api_impl_natives_dir, dex_install_dir);
|
strcpy(api_impl_natives_dir, dex_install_dir);
|
||||||
strcat(api_impl_natives_dir, REL_API_IMPL_NATIVES_INSTALL_PATH);
|
strcat(api_impl_natives_dir, REL_API_IMPL_NATIVES_INSTALL_PATH);
|
||||||
@@ -286,7 +311,7 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h
|
|||||||
// calling directly into the shim bionic linker to whitelist the app's lib dir as containing bionic-linked libraries
|
// calling directly into the shim bionic linker to whitelist the app's lib dir as containing bionic-linked libraries
|
||||||
dl_parse_library_path(app_lib_dir, ":");
|
dl_parse_library_path(app_lib_dir, ":");
|
||||||
|
|
||||||
JNIEnv* env = create_vm(api_impl_jar, apk_classpath, microg_apk, api_impl_natives_dir, app_lib_dir);
|
JNIEnv* env = create_vm(api_impl_jar, apk_classpath, microg_apk, framework_res_apk, api_impl_natives_dir, app_lib_dir);
|
||||||
|
|
||||||
free(app_lib_dir);
|
free(app_lib_dir);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user