From 778d19f2685a562b743ef909f03ae10450494307 Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Wed, 22 May 2024 23:38:54 +0200 Subject: [PATCH] remove remaining dependencies on ARSClib --- src/api-impl/android/app/Activity.java | 58 ++++++--- src/api-impl/android/app/Application.java | 30 ++--- src/api-impl/android/app/NativeActivity.java | 38 +++--- .../android/content/ContentProvider.java | 19 ++- src/api-impl/android/content/Context.java | 54 ++++++--- .../android/content/pm/PackageInfo.java | 112 ++++++++---------- .../android/content/pm/PackageManager.java | 67 ++++++----- .../android/content/res/AssetManager.java | 41 +++---- .../android/content/res/Resources.java | 2 - .../android/content/res/TypedArray.java | 24 +--- src/api-impl/meson.build | 3 - 11 files changed, 225 insertions(+), 223 deletions(-) diff --git a/src/api-impl/android/app/Activity.java b/src/api-impl/android/app/Activity.java index 979837ec..e5db1ded 100644 --- a/src/api-impl/android/app/Activity.java +++ b/src/api-impl/android/app/Activity.java @@ -8,6 +8,7 @@ import android.content.ContextWrapper; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.net.Uri; import android.os.Bundle; @@ -22,10 +23,7 @@ import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; -import com.reandroid.arsc.chunk.xml.ResXmlAttribute; -import java.io.IOException; -import java.io.InputStream; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -51,16 +49,27 @@ public class Activity extends ContextWrapper implements Window.Callback { * * @param className class name of activity or null * @return instance of main activity class + * @throws Exception */ - private static Activity createMainActivity(String className, long native_window) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException { + private static Activity createMainActivity(String className, long native_window) throws Exception { if (className == null) { - InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml"); - AndroidManifestBlock block = AndroidManifestBlock.load(inStream); - className = block.getMainActivity().searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString(); + XmlResourceParser parser = Context.this_application.getAssets().openXmlResourceParser("AndroidManifest.xml"); + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "activity".equals(parser.getName())) { + className = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"); + } + // check if it is the main activity + if (parser.getEventType() == XmlResourceParser.START_TAG && "action".equals(parser.getName())) { + if ("android.intent.action.MAIN".equals(parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"))) { + break; + } + } + } + parser.close(); if(className.indexOf('.') == -1) className = "." + className; if (className.startsWith(".")) - className = block.getPackageName() + className; + className = Context.this_application.getPackageName() + className; } else { className = className.replace('/', '.'); } @@ -76,13 +85,30 @@ public class Activity extends ContextWrapper implements Window.Callback { layout_inflater = new LayoutInflater(); intent = new Intent(); - ResXmlAttribute label; - if((label = manifest.getActivityByName(getClass().getName()).searchAttributeByResourceId(AndroidManifestBlock.ID_label)) != null - || (label = manifest.getApplicationElement().searchAttributeByResourceId(AndroidManifestBlock.ID_label)) != null) { - if(label.getValueType() == com.reandroid.arsc.value.ValueType.STRING) - setTitle(label.getValueAsString()); - else - setTitle(getString(label.getData())); + CharSequence label = null; + CharSequence app_label = null; + try (XmlResourceParser parser = getAssets().openXmlResourceParser("AndroidManifest.xml")) { + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "application".equals(parser.getName())) { + TypedArray a = obtainStyledAttributes(parser, R.styleable.AndroidManifestApplication); + app_label = a.getText(R.styleable.AndroidManifestApplication_label); + a.recycle(); + } else if (parser.getEventType() == XmlResourceParser.START_TAG && "activity".equals(parser.getName())) { + if (getClass().getName().equals(parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"))) { + TypedArray a = obtainStyledAttributes(parser, R.styleable.AndroidManifestActivity); + label = a.getText(R.styleable.AndroidManifestActivity_label); + a.recycle(); + break; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + if (label != null) { + setTitle(label); + } else if (app_label != null) { + setTitle(app_label); } } diff --git a/src/api-impl/android/app/Application.java b/src/api-impl/android/app/Application.java index 55a0c100..b470ac2d 100644 --- a/src/api-impl/android/app/Application.java +++ b/src/api-impl/android/app/Application.java @@ -2,18 +2,15 @@ package android.app; import android.os.Bundle; import android.content.res.Configuration; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import com.reandroid.apk.AndroidFrameworks; -import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; -import java.io.InputStream; -import java.io.IOException; - +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.R; import android.content.Context; import android.content.ContextWrapper; public class Application extends ContextWrapper { private String app_icon_path = null; + private String app_label = null; public long native_window; private String get_app_icon_path() { @@ -21,8 +18,7 @@ public class Application extends ContextWrapper { } private String get_app_label() { - int app_label_resid = manifest.getApplicationElement().searchAttributeByResourceId(AndroidManifestBlock.ID_label).getData(); - return getResources().getString(app_label_resid); + return app_label; } public interface ActivityLifecycleCallbacks { @@ -52,12 +48,16 @@ public class Application extends ContextWrapper { public Application() { super(new Context()); /* TODO: is this the right place to put this? */ - InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml"); - try { - AndroidManifestBlock manifest = AndroidManifestBlock.load(inStream); - int app_icon_resid = manifest.getIconResourceId(); - app_icon_path = r.getString(app_icon_resid); - } catch (IOException e) { + try (XmlResourceParser parser = getAssets().openXmlResourceParser("AndroidManifest.xml")) { + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "application".equals(parser.getName())) { + TypedArray a = getResources().obtainAttributes(parser, R.styleable.AndroidManifestApplication); + app_icon_path = a.getString(R.styleable.AndroidManifestApplication_icon); + app_label = a.getString(R.styleable.AndroidManifestApplication_label); + a.recycle(); + } + } + } catch (Exception e) { e.printStackTrace(); } } diff --git a/src/api-impl/android/app/NativeActivity.java b/src/api-impl/android/app/NativeActivity.java index b6280216..4dc3ba16 100644 --- a/src/api-impl/android/app/NativeActivity.java +++ b/src/api-impl/android/app/NativeActivity.java @@ -21,6 +21,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.content.res.Configuration; +import android.content.res.XmlResourceParser; // import android.graphics.PixelFormat; import android.os.Build; import android.os.Bundle; @@ -34,13 +35,8 @@ import android.view.SurfaceView; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowManager; -import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; -import com.reandroid.arsc.chunk.xml.ResXmlAttribute; -import com.reandroid.arsc.chunk.xml.ResXmlElement; // import android.view.inputmethod.InputMethodManager; import java.io.File; -import java.io.IOException; -import java.io.InputStream; /** * Convenience for implementing an activity that will be implemented @@ -166,26 +162,28 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback, }*/ // parse AndroidManifest.xml to get name and entry of native lib - try (InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml")) { - for (ResXmlElement activity : AndroidManifestBlock.load(inStream).listActivities()) { - if (!getClass().getName().equals(activity.searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString())) { - continue; - } - for (ResXmlElement metaData : activity.listElements(AndroidManifestBlock.TAG_meta_data)) { - ResXmlAttribute name = metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_name); - ResXmlAttribute value = metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_value); - if (name == null || value == null) { + try (XmlResourceParser parser = getAssets().openXmlResourceParser("AndroidManifest.xml")) { + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "activity".equals(parser.getName())) { + if (!getClass().getName().equals(parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"))) { continue; } - if (META_DATA_LIB_NAME.equals(name.getValueAsString())) { - libname = value.getValueAsString(); - } - if (META_DATA_FUNC_NAME.equals(name.getValueAsString())) { - funcname = value.getValueAsString(); + for (; !(parser.getEventType() == XmlResourceParser.END_TAG && "activity".equals(parser.getName())); parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "meta-data".equals(parser.getName())) { + String name = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"); + String value = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "value"); + if (META_DATA_LIB_NAME.equals(name)) { + libname = value; + } + if (META_DATA_FUNC_NAME.equals(name)) { + funcname = value; + } + } } + break; } } - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } diff --git a/src/api-impl/android/content/ContentProvider.java b/src/api-impl/android/content/ContentProvider.java index 232208eb..cfb49b6e 100644 --- a/src/api-impl/android/content/ContentProvider.java +++ b/src/api-impl/android/content/ContentProvider.java @@ -1,25 +1,24 @@ package android.content; -import java.util.List; - -import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; -import com.reandroid.arsc.chunk.xml.ResXmlElement; +import android.content.res.XmlResourceParser; public class ContentProvider { - static void createContentProviders() throws ReflectiveOperationException { - List providers = Context.manifest.getApplicationElement().listElements(AndroidManifestBlock.TAG_provider); - System.out.println(providers); - for (ResXmlElement providerElement : providers) { - String providerName = providerElement.searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString(); + static void createContentProviders() throws Exception { + XmlResourceParser parser = Context.this_application.getAssets().openXmlResourceParser("AndroidManifest.xml"); + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() != XmlResourceParser.START_TAG || !"provider".equals(parser.getName())) + continue; + String providerName = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"); if (providerName.startsWith(".")) { - providerName = Context.manifest.getPackageName() + providerName; + providerName = Context.this_application.getPackageName() + providerName; } System.out.println("creating " + providerName); Class providerCls = Class.forName(providerName).asSubclass(ContentProvider.class); ContentProvider provider = providerCls.getConstructor().newInstance(); provider.onCreate(); } + parser.close(); } public boolean onCreate() {return false;} diff --git a/src/api-impl/android/content/Context.java b/src/api-impl/android/content/Context.java index b50f0b1f..8f548655 100644 --- a/src/api-impl/android/content/Context.java +++ b/src/api-impl/android/content/Context.java @@ -1,5 +1,6 @@ package android.content; +import android.R; import android.app.Activity; import android.app.ActivityManager; import android.app.AlarmManager; @@ -15,6 +16,7 @@ import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import android.graphics.drawable.Drawable; @@ -43,9 +45,6 @@ import android.view.WindowManagerImpl; import android.view.accessibility.AccessibilityManager; import android.view.inputmethod.InputMethodManager; -import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; -import com.reandroid.arsc.chunk.xml.ResXmlAttribute; - import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -68,7 +67,6 @@ public class Context extends Object { public static final String WINDOW_SERVICE = "window"; public static final String INPUT_METHOD_SERVICE = "input"; public static final String POWER_SERVICE = "power"; - public static AndroidManifestBlock manifest = null; public static Vibrator vibrator; @@ -101,33 +99,51 @@ public class Context extends Object { theme = r.newTheme(); application_info = new ApplicationInfo(); application_info.dataDir = Environment.getExternalStorageDirectory().getAbsolutePath(); - InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml"); - try { - manifest = AndroidManifestBlock.load(inStream); - Integer targetSdkVersion = manifest.getTargetSdkVersion(); - if (targetSdkVersion != null) - application_info.targetSdkVersion = targetSdkVersion; - } catch (IOException e) { + try (XmlResourceParser parser = assets.openXmlResourceParser("AndroidManifest.xml")) { + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "uses-sdk".equals(parser.getName())) { + application_info.targetSdkVersion = parser.getAttributeIntValue(null, "targetSdkVersion", 0); + } + if (parser.getEventType() == XmlResourceParser.START_TAG && "manifest".equals(parser.getName())) { + application_info.packageName = parser.getAttributeValue(null, "package"); + } + } + } catch (Exception e) { e.printStackTrace(); } } protected static native void native_updateConfig(Configuration config); - static Application createApplication(long native_window) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException { + static Application createApplication(long native_window) throws Exception { Application application; - ResXmlAttribute application_name = manifest.getApplicationElement().searchAttributeByResourceId(AndroidManifestBlock.ID_name); - String className = (application_name != null) ? application_name.getValueAsString() : "android.app.Application"; + CharSequence application_name = null; + int application_theme = 0; + String packageName = null; + XmlResourceParser parser = assets.openXmlResourceParser("AndroidManifest.xml"); + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "manifest".equals(parser.getName())) { + packageName = parser.getAttributeValue(null, "package"); + } + if (parser.getEventType() == XmlResourceParser.START_TAG && "application".equals(parser.getName())) { + TypedArray a = r.obtainAttributes(parser, R.styleable.AndroidManifestApplication); + application_name = a.getText(R.styleable.AndroidManifestApplication_name); + application_theme = a.getResourceId(R.styleable.AndroidManifestApplication_theme, 0); + a.recycle(); + } + } + parser.close(); + + String className = (application_name != null) ? application_name.toString() : "android.app.Application"; if(className.indexOf('.') == -1) className = "." + className; if (className.startsWith(".")) - className = manifest.getPackageName() + className; + className = packageName + className; Class cls = Class.forName(className).asSubclass(Application.class); Constructor constructor = cls.getConstructor(); application = constructor.newInstance(); - ResXmlAttribute application_theme = manifest.getApplicationElement().searchAttributeByResourceId(AndroidManifestBlock.ID_theme); - if (application_theme != null) - application.setTheme(application_theme.getData()); + if (application_theme != 0) + application.setTheme(application_theme); application.native_window = native_window; this_application = application; return application; @@ -228,7 +244,7 @@ public class Context extends Object { } public String getPackageName() { - return manifest.getPackageName(); + return application_info.packageName; } public String getPackageCodePath() { diff --git a/src/api-impl/android/content/pm/PackageInfo.java b/src/api-impl/android/content/pm/PackageInfo.java index b4a67798..402bad55 100644 --- a/src/api-impl/android/content/pm/PackageInfo.java +++ b/src/api-impl/android/content/pm/PackageInfo.java @@ -16,22 +16,17 @@ package android.content.pm; +import android.R; import android.content.Context; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; import android.util.TypedValue; -import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; -import com.reandroid.arsc.chunk.xml.ResXmlAttribute; -import com.reandroid.arsc.chunk.xml.ResXmlElement; - -import java.io.InputStream; -import java.io.IOException; - /** * Overall information about the contents of a package. This corresponds * to all of the information collected from AndroidManifest.xml. */ public class PackageInfo { - private static AndroidManifestBlock manifest = null; // TODO: only ever load this once, in one place /** * The name of this package. From the <manifest> tag's "name" @@ -242,64 +237,55 @@ public class PackageInfo { */ public String requiredAccountType; - static { - InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream("AndroidManifest.xml"); + public PackageInfo() { + applicationInfo = new ApplicationInfo(); try { - manifest = AndroidManifestBlock.load(inStream); - } catch (IOException e) { + XmlResourceParser parser = Context.this_application.getAssets().openXmlResourceParser("AndroidManifest.xml"); + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "manifest".equals(parser.getName())) { + packageName = parser.getAttributeValue(null, "package"); + versionCode = parser.getAttributeIntValue("http://schemas.android.com/apk/res/android", "versionCode", -1); + versionName = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "versionName"); + } + if (parser.getEventType() == XmlResourceParser.START_TAG && "application".equals(parser.getName())) { + for (; !(parser.getEventType() == XmlResourceParser.END_TAG && "application".equals(parser.getName())); parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "meta-data".equals(parser.getName())) { + TypedArray a = Context.this_application.getResources().obtainAttributes(parser, R.styleable.AndroidManifestMetaData); + String metadata_name = a.getString(R.styleable.AndroidManifestMetaData_name); + if (metadata_name == null || !a.hasValue(R.styleable.AndroidManifestMetaData_value)) { + a.recycle(); + continue; + } + + TypedValue metadata_value = new TypedValue(); + a.getValue(R.styleable.AndroidManifestMetaData_value, metadata_value); + a.recycle(); + + switch(metadata_value.type) { + case TypedValue.TYPE_STRING: + System.out.println("PackageInfo(): applicationInfo.metaData.putString("+metadata_name+", "+metadata_value.string+")"); + applicationInfo.metaData.putString(metadata_name, metadata_value.string.toString()); + break; + case TypedValue.TYPE_INT_BOOLEAN: + System.out.println("PackageInfo(): applicationInfo.metaData.putBoolean("+metadata_name+", "+(metadata_value.data != 0)+")"); + applicationInfo.metaData.putBoolean(metadata_name, metadata_value.data != 0); + break; + case TypedValue.TYPE_INT_DEC: + case TypedValue.TYPE_INT_HEX: + System.out.println("PackageInfo(): applicationInfo.metaData.putInt("+metadata_name+", "+metadata_value.data+")"); + applicationInfo.metaData.putInt(metadata_name, metadata_value.data); + break; + default: + System.out.println("PackageInfo(): metaData: "+metadata_name+": type "+metadata_value.type+" not handled!"); + break; + } + } + } + } + } + } catch (Exception e) { e.printStackTrace(); } - } - - public PackageInfo() { - packageName = manifest.getPackageName(); - versionCode = manifest.getVersionCode(); - versionName = manifest.getVersionName(); - - System.out.println("PackageInfo()"); - - applicationInfo = new ApplicationInfo(); - - ResXmlElement application = manifest.getApplicationElement(); - for (ResXmlElement metaData : application.listElements(AndroidManifestBlock.TAG_meta_data)) { - ResXmlAttribute name = metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_name); - ResXmlAttribute value = metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_value); - if (name == null || value == null) { - continue; - } - - String metadata_name = name.getValueAsString(); - TypedValue metadata_value = new TypedValue(); - int data = value.getData(); - - try { - Context.r.getValue(data, metadata_value, true); - } catch (android.content.res.Resources.NotFoundException e) { - System.out.println("PackageInfo(): error getting value for '"+metadata_name+"'"); - e.printStackTrace(); - continue; - } - - switch(metadata_value.type) { - case TypedValue.TYPE_STRING: - System.out.println("PackageInfo(): applicationInfo.metaData.putString("+metadata_name+", "+metadata_value.string+")"); - applicationInfo.metaData.putString(metadata_name, value.getValueAsString()); - break; - case TypedValue.TYPE_INT_BOOLEAN: - System.out.println("PackageInfo(): applicationInfo.metaData.putBoolean("+metadata_name+", "+metadata_value.data != 0+")"); - applicationInfo.metaData.putBoolean(metadata_name, metadata_value.data != 0); - break; - case TypedValue.TYPE_INT_DEC: - case TypedValue.TYPE_INT_HEX: - System.out.println("PackageInfo(): applicationInfo.metaData.putInt("+metadata_name+", "+metadata_value.data+")"); - applicationInfo.metaData.putInt(metadata_name, metadata_value.data); - break; - default: - System.out.println("PackageInfo(): metaData: "+metadata_name+": type "+metadata_value.type+" not handled!"); - break; - } - } - System.out.println("PackageInfo(): packageName: >"+packageName+"<, versionCode: >"+versionCode+"<, versionName: >"+versionName+"<"); } diff --git a/src/api-impl/android/content/pm/PackageManager.java b/src/api-impl/android/content/pm/PackageManager.java index 1e340975..5e28e561 100644 --- a/src/api-impl/android/content/pm/PackageManager.java +++ b/src/api-impl/android/content/pm/PackageManager.java @@ -38,10 +38,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; -import com.reandroid.arsc.chunk.xml.ResXmlAttribute; -import com.reandroid.arsc.chunk.xml.ResXmlElement; - class IPackageInstallObserver {} class VerificationParams {} class ContainerEncryptionParams {} @@ -1693,32 +1689,37 @@ public class PackageManager { * to modify the data returned. * * @return ProviderInfo containing information about the service. + * @throws Exception * * @see #GET_META_DATA * @see #GET_SHARED_LIBRARY_FILES */ public ProviderInfo getProviderInfo(ComponentName component, - int flags) throws NameNotFoundException { + int flags) throws Exception { ProviderInfo providerInfo = new ProviderInfo(); if ((flags & GET_META_DATA) == GET_META_DATA) { String cls = component.getClassName(); - List providers = Context.manifest.getApplicationElement().listElements(AndroidManifestBlock.TAG_provider); - for (ResXmlElement providerElement : providers) { - String providerName = providerElement.searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString(); - if (providerName.startsWith(".")) { - providerName = Context.manifest.getPackageName() + providerName; - } - if (providerName.equals(cls)) { - List metaDatas = providerElement.listElements(AndroidManifestBlock.TAG_meta_data); - Bundle bundle = new Bundle(metaDatas.size()); - for (ResXmlElement metaData : metaDatas) { - bundle.putString(metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_name).getValueAsString(), - metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_value).getValueAsString()); + XmlResourceParser parser = Context.this_application.getAssets().openXmlResourceParser("AndroidManifest.xml"); + for(; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "provider".equals(parser.getName())) { + String providerName = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"); + if (providerName.startsWith(".")) + providerName = Context.this_application.getPackageName() + providerName; + if (!providerName.equals(cls)) + continue; + Bundle bundle = new Bundle(); + for (; !(parser.getEventType() == XmlResourceParser.END_TAG && "provider".equals(parser.getName())); parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "meta-data".equals(parser.getName())) { + String metaName = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"); + String metaValue = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "value"); + bundle.putString(metaName, metaValue); + } } providerInfo.metaData = bundle; break; } } + parser.close(); } return providerInfo; } @@ -2424,23 +2425,29 @@ public class PackageManager { * * @return ContentProviderInfo Information about the provider, if found, * else null. + * @throws Exception */ - public ProviderInfo resolveContentProvider(String authority, int flags) { + public ProviderInfo resolveContentProvider(String authority, int flags) throws Exception { ProviderInfo providerInfo = new ProviderInfo(); - List providers = Context.manifest.getApplicationElement().listElements(AndroidManifestBlock.TAG_provider); - for (ResXmlElement providerElement : providers) { - String providerAuthority = providerElement.searchAttributeByResourceId(AndroidManifestBlock.ID_authorities).getValueAsString(); - if (providerAuthority.startsWith(".")) - providerAuthority = Context.manifest.getPackageName() + providerAuthority; - if (!providerAuthority.equals(authority)) - continue; - for (ResXmlElement metaData : providerElement.listElements(AndroidManifestBlock.TAG_meta_data)) { - ResXmlAttribute metaName = metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_name); - ResXmlAttribute metaRes = metaData.searchAttributeByResourceId(AndroidManifestBlock.ID_resource); - providerInfo.metaData.putInt(metaName.getValueAsString(), metaRes.getData()); + XmlResourceParser parser = Context.this_application.getAssets().openXmlResourceParser("AndroidManifest.xml"); + for (; parser.getEventType() != XmlResourceParser.END_DOCUMENT; parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "provider".equals(parser.getName())) { + String providerAuthority = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "authorities"); + if (providerAuthority.startsWith(".")) + providerAuthority = Context.this_application.getPackageName() + providerAuthority; + if (!providerAuthority.equals(authority)) + continue; + for (; !(parser.getEventType() == XmlResourceParser.END_TAG && "provider".equals(parser.getName())); parser.next()) { + if (parser.getEventType() == XmlResourceParser.START_TAG && "meta-data".equals(parser.getName())) { + String metaName = parser.getAttributeValue("http://schemas.android.com/apk/res/android", "name"); + int metaRes = parser.getAttributeResourceValue("http://schemas.android.com/apk/res/android", "resource", -1); + providerInfo.metaData.putInt(metaName, metaRes); + } + } + break; } - break; } + parser.close(); return providerInfo; } diff --git a/src/api-impl/android/content/res/AssetManager.java b/src/api-impl/android/content/res/AssetManager.java index b00735b8..e4f44415 100644 --- a/src/api-impl/android/content/res/AssetManager.java +++ b/src/api-impl/android/content/res/AssetManager.java @@ -22,10 +22,6 @@ import android.util.AttributeSet; import android.util.Log; import android.util.TypedValue; -import com.reandroid.arsc.chunk.xml.ResXmlDocument; -import com.reandroid.arsc.chunk.xml.ResXmlPullParser; -import com.reandroid.arsc.value.ValueItem; - import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; @@ -34,6 +30,7 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; @@ -112,10 +109,17 @@ public final class AssetManager { // ensureSystemAssets() try { Enumeration resources = ClassLoader.getSystemClassLoader().getResources("resources.arsc"); + ArrayList paths = new ArrayList(); + paths.add(null); // reserve first slot for framework-res.apk while (resources.hasMoreElements()) { - URL resource = resources.nextElement(); - String path = resource.getPath(); - if (!path.contains("com.google.android.gms")) { // ignore MicroG .apk + String path = resources.nextElement().getPath(); + if (path.contains("framework-res.apk")) // needs to be first, so it can be overridden + paths.set(0, path); + else if (!path.contains("com.google.android.gms")) // microg resources can not be merged + paths.add(path); + } + for (String path : paths) { + if (path != null) { path = path.substring(path.indexOf("file:") + 5, path.indexOf("!/resources.arsc")); addAssetPath(path); } @@ -759,18 +763,7 @@ public final class AssetManager { if (defStyleRes == 0 && theme != 0 && loadThemeAttributeValue(theme, defStyleAttr, value, true) >= 0) defStyleRes = value.data; if (defStyleRes == 0 && set != null) { - if (parser instanceof ResXmlPullParser) { - ValueItem valueItem = ((ResXmlPullParser)parser).getAttribute(null, "style"); - if (valueItem != null) { - value.type = valueItem.getType(); - value.data = valueItem.getData(); - if (theme != 0 && (value.type == TypedValue.TYPE_ATTRIBUTE)) - loadThemeAttributeValue(theme, value.data, value, true); - defStyleRes = value.data; - } - } else { - defStyleRes = parser.getStyleAttribute(); - } + defStyleRes = parser.getStyleAttribute(); } outIndices[0] = 0; @@ -798,14 +791,8 @@ public final class AssetManager { value.assetCookie = -1; found = true; } else if (xmlCache.containsKey(resId)) { - if (parser instanceof ResXmlPullParser) { - ValueItem valueItem = ((ResXmlPullParser)parser).getResXmlAttributeAt(xmlCache.get(resId)); - value.type = valueItem.getType(); - value.data = valueItem.getData(); - } else { - value.type = XmlBlock.nativeGetAttributeDataType(((XmlBlock.Parser)parser).mParseState, xmlCache.get(resId)); - value.data = XmlBlock.nativeGetAttributeData(((XmlBlock.Parser)parser).mParseState, xmlCache.get(resId)); - } + value.type = XmlBlock.nativeGetAttributeDataType(((XmlBlock.Parser)parser).mParseState, xmlCache.get(resId)); + value.data = XmlBlock.nativeGetAttributeData(((XmlBlock.Parser)parser).mParseState, xmlCache.get(resId)); value.resourceId = 0; value.assetCookie = -1; if (value.type != TypedValue.TYPE_ATTRIBUTE) diff --git a/src/api-impl/android/content/res/Resources.java b/src/api-impl/android/content/res/Resources.java index aedaead1..3bf64293 100644 --- a/src/api-impl/android/content/res/Resources.java +++ b/src/api-impl/android/content/res/Resources.java @@ -34,8 +34,6 @@ import android.util.LongSparseArray; import android.util.Slog; import android.util.TypedValue; import com.android.internal.util.XmlUtils; -import com.reandroid.arsc.chunk.xml.ResXmlPullParser; -import com.reandroid.arsc.value.ValueItem; // import android.view.DisplayAdjustments; import java.io.IOException; import java.io.InputStream; diff --git a/src/api-impl/android/content/res/TypedArray.java b/src/api-impl/android/content/res/TypedArray.java index b7cf1bf0..c5b6aaa8 100644 --- a/src/api-impl/android/content/res/TypedArray.java +++ b/src/api-impl/android/content/res/TypedArray.java @@ -16,15 +16,12 @@ package android.content.res; -import android.content.pm.ActivityInfo; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; import com.android.internal.util.XmlUtils; -import com.reandroid.arsc.chunk.xml.ResXmlPullParser; -import com.reandroid.arsc.item.ResXmlString; import java.util.Arrays; @@ -156,12 +153,9 @@ public class TypedArray { if (type == TypedValue.TYPE_STRING) { final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE]; if (cookie < 0) { - if (mXml instanceof ResXmlPullParser) - return ((ResXmlPullParser )mXml).getResXmlDocument().getStringPool().get(data[index + AssetManager.STYLE_DATA]).get(); - else { - Thread.dumpStack(); - System.exit(-1); - } + CharSequence string = ((XmlBlock.Parser)mXml).getPooledString(data[index + AssetManager.STYLE_DATA]); + if (string != null) + return string.toString(); } } return null; @@ -700,15 +694,9 @@ public class TypedArray { final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE]; if (cookie < 0) { if (mXml != null) { - if (mXml instanceof ResXmlPullParser) { - ResXmlString xmlString = ((ResXmlPullParser)mXml).getResXmlDocument().getStringPool().get(data[index + AssetManager.STYLE_DATA]); - if (xmlString != null) - return xmlString.get(); - } else { - CharSequence string = ((XmlBlock.Parser)mXml).getPooledString(data[index + AssetManager.STYLE_DATA]); - if (string != null) - return string; - } + CharSequence string = ((XmlBlock.Parser)mXml).getPooledString(data[index + AssetManager.STYLE_DATA]); + if (string != null) + return string; } if (data[index + AssetManager.STYLE_RESOURCE_ID] != 0) { return mResources.mAssets.getResourceText(data[index + AssetManager.STYLE_RESOURCE_ID]); diff --git a/src/api-impl/meson.build b/src/api-impl/meson.build index e8f8bed3..f78da713 100644 --- a/src/api-impl/meson.build +++ b/src/api-impl/meson.build @@ -514,9 +514,6 @@ hax_jar = jar('hax', [ 'javax/microedition/khronos/opengles/GL11ExtensionPack.java', 'org/apache/harmony/xnet/provider/jsse/SSLParametersImpl.java', ], - dependencies: [ - declare_dependency(link_with: hax_arsc_lib_jar) - ], java_args: [ '-bootclasspath', bootclasspath, '-source', '1.8', '-target', '1.8',