From 3709e30f64d266f191f479c957ebdf8cf33266eb Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Sat, 20 May 2023 12:38:34 +0200 Subject: [PATCH] load layout XMLs directly from apk file --- README.md | 3 --- src/api-impl/android/app/Activity.java | 11 ++--------- .../android/content/res/AssetManager.java | 16 +++++++++------- src/api-impl/android/view/View.java | 2 +- src/main-executable/main.c | 5 +---- 5 files changed, 13 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 736f9bd0..be5a6d81 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,6 @@ example with custom width/height: `android-translation-layer path/to/org.happysa NOTE: you might need to copy some files out from the apk under `ANDROID_APP_DATA_DIR` (defaults to `~/.local/share/android_translation_layer/`), e.g the `assets` folder; -additionally, resources (`res`) currently need to be "decompiled" (e.g. by apktool, though this -additionally replaces hex IDs with string names, which then needs to be manually reversed; -android studio's `inspect apk` feature is known to keep the integers) NOTE: on X11, Gtk might decide to use GLX, which completely messes up our EGL-dependent code. If you have a debug build of Gtk, you can use GDK_DEBUG=gl-egl to force the use of EGL NOTE: we don't currently handle signed apks; simply remove the META-INF folder from an apk to skip signature verification diff --git a/src/api-impl/android/app/Activity.java b/src/api-impl/android/app/Activity.java index df17b857..3b583c98 100644 --- a/src/api-impl/android/app/Activity.java +++ b/src/api-impl/android/app/Activity.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.ComponentName; import android.content.Intent; import android.content.res.Configuration; +import android.content.res.XmlResourceParser; import android.os.Bundle; import android.widget.TextView; @@ -136,15 +137,7 @@ public class Activity extends Context { public void setContentView(int layoutResID) throws Exception { System.out.println("- setContentView - yay!"); - String layout_xml_file = android.os.Environment.getExternalStorageDirectory().getPath() + "/" + getString(layoutResID); - - System.out.println("loading layout from: " + layout_xml_file); - - XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); - factory.setNamespaceAware(true); - XmlPullParser xpp = factory.newPullParser(); - - xpp.setInput( new FileReader(layout_xml_file) ); + XmlResourceParser xpp = Context.this_application.getResources().getLayout(layoutResID); root_view = layout_inflater.inflate(xpp, null, false); diff --git a/src/api-impl/android/content/res/AssetManager.java b/src/api-impl/android/content/res/AssetManager.java index 6a21dfaf..3741ec95 100644 --- a/src/api-impl/android/content/res/AssetManager.java +++ b/src/api-impl/android/content/res/AssetManager.java @@ -19,6 +19,9 @@ package android.content.res; import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.value.ResValueMap; +import com.reandroid.arsc.chunk.xml.ResXmlPullParser; +import com.reandroid.arsc.chunk.xml.ResXmlDocument; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; @@ -479,13 +482,12 @@ public final class AssetManager { block.close(); return rp;*/ - XmlPullParserFactory factory = XmlPullParserFactory.newInstance("android.util.DecompiledXmlResourceParser", this.getClass()); - factory.setNamespaceAware(true); - XmlPullParser xpp = factory.newPullParser(); - - xpp.setInput( new FileReader(android.os.Environment.getExternalStorageDirectory().getPath() + "/" + fileName) ); - - return (XmlResourceParser)xpp; + InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream(fileName); + ResXmlDocument resXmlDocument = new ResXmlDocument(); + resXmlDocument.readBytes(inStream); + ResXmlPullParser xpp = new ResXmlPullParser(); + xpp.setResXmlDocument(resXmlDocument); + return xpp; } /** diff --git a/src/api-impl/android/view/View.java b/src/api-impl/android/view/View.java index 287f2d2b..95401ec7 100644 --- a/src/api-impl/android/view/View.java +++ b/src/api-impl/android/view/View.java @@ -692,7 +692,7 @@ public class View extends Object { public View() {} // FIXME public View(AttributeSet attrs) { - id = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "id", 0); + id = attrs.getAttributeResourceValue("http://schemas.android.com/apk/res/android", "id", 0); if(id != 0) view_by_id.put(id, this); diff --git a/src/main-executable/main.c b/src/main-executable/main.c index 5d9e754e..5ff6b384 100644 --- a/src/main-executable/main.c +++ b/src/main-executable/main.c @@ -213,11 +213,8 @@ static void open(GtkApplication *app, GFile** files, gint nfiles, const gchar* h if(ret) { printf("can't stat %s (%s); we don't currently support parsing certain resources from the apk file, " "so you will need to create this directory and put in those resources\n" - "some of these resources need to be preprocessed, apktool is mostly fine except it replaces " - "the numeric values in the layout xml files with what it assumes was in the source xml; " - "android studio's apk anylyzer (for example) leaves the 'compiled' integer values that our code expects\n" "NOTE: if the app you're trying to run doesn't use any such resources, simply create the directory " - "and leave it empty (this will be done automatically once the maunal preprocessing step is not required)\n", + "and leave it empty (this will be done automatically once the maunal extraction step is not required)\n", app_data_dir, strerror(errno)); exit(1); }