From b15bf203a7e35401cc99e2e6009098dec05713cc Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Mon, 10 Jun 2024 23:24:29 +0200 Subject: [PATCH] remove custom AndroidManifest.xml parsing and instead use PackageParser This has the advantage, that AndroidManifest.xml is only parsed once. --- src/api-impl/android/app/Activity.java | 44 +++------- src/api-impl/android/app/Application.java | 22 +---- src/api-impl/android/app/NativeActivity.java | 36 +++------ .../android/content/ContentProvider.java | 13 +-- src/api-impl/android/content/Context.java | 47 +++-------- .../android/content/pm/PackageInfo.java | 58 ------------- .../android/content/pm/PackageManager.java | 57 +++---------- .../android/content/pm/PackageParser.java | 81 +++++++++++++++++-- 8 files changed, 126 insertions(+), 232 deletions(-) diff --git a/src/api-impl/android/app/Activity.java b/src/api-impl/android/app/Activity.java index e5db1ded..8e591a28 100644 --- a/src/api-impl/android/app/Activity.java +++ b/src/api-impl/android/app/Activity.java @@ -3,13 +3,11 @@ package android.app; import android.R; import android.content.BroadcastReceiver; import android.content.ComponentName; -import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageParser; import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -53,23 +51,16 @@ public class Activity extends ContextWrapper implements Window.Callback { */ private static Activity createMainActivity(String className, long native_window) throws Exception { if (className == null) { - 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"))) { + for (PackageParser.Activity activity: pkg.activities) { + for (PackageParser.IntentInfo intent: activity.intents) { + if (intent.matchAction("android.intent.action.MAIN")) { + className = activity.className; break; } } + if (className != null) + break; } - parser.close(); - if(className.indexOf('.') == -1) - className = "." + className; - if (className.startsWith(".")) - className = Context.this_application.getPackageName() + className; } else { className = className.replace('/', '.'); } @@ -87,24 +78,13 @@ public class Activity extends ContextWrapper implements Window.Callback { 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; - } - } + for (PackageParser.Activity activity: pkg.activities) { + if (getClass().getName().equals(activity.className)) { + label = getText(activity.info.labelRes); + break; } - } catch (Exception e) { - e.printStackTrace(); } + app_label = getText(pkg.applicationInfo.labelRes); if (label != null) { setTitle(label); } else if (app_label != null) { diff --git a/src/api-impl/android/app/Application.java b/src/api-impl/android/app/Application.java index b470ac2d..1da8c672 100644 --- a/src/api-impl/android/app/Application.java +++ b/src/api-impl/android/app/Application.java @@ -2,23 +2,18 @@ package android.app; import android.os.Bundle; import android.content.res.Configuration; -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() { - return app_icon_path; + return getString(pkg.applicationInfo.icon); } private String get_app_label() { - return app_label; + return getString(pkg.applicationInfo.labelRes); } public interface ActivityLifecycleCallbacks { @@ -47,19 +42,6 @@ public class Application extends ContextWrapper { public Application() { super(new Context()); - /* TODO: is this the right place to put this? */ - 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(); - } } /** * Called when the application is starting, before any activity, service, diff --git a/src/api-impl/android/app/NativeActivity.java b/src/api-impl/android/app/NativeActivity.java index 4dc3ba16..1addd3df 100644 --- a/src/api-impl/android/app/NativeActivity.java +++ b/src/api-impl/android/app/NativeActivity.java @@ -18,23 +18,19 @@ package android.app; import android.content.Context; import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; +import android.content.pm.PackageParser; 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; -import android.os.Looper; import android.os.MessageQueue; import android.util.AttributeSet; import android.view.InputQueue; import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; -import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.view.WindowManager; // import android.view.inputmethod.InputMethodManager; import java.io.File; @@ -161,30 +157,16 @@ public class NativeActivity extends Activity implements SurfaceHolder.Callback, throw new RuntimeException("Error getting activity info", e); }*/ - // parse AndroidManifest.xml to get name and entry of native lib - 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; - } - 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; + for (PackageParser.Activity activity : pkg.activities) { + if (getClass().getName().equals(activity.className)) { + if (activity.metaData != null) { + String ln = activity.metaData.getString(META_DATA_LIB_NAME); + if (ln != null) libname = ln; + ln = activity.metaData.getString(META_DATA_FUNC_NAME); + if (ln != null) funcname = ln; } + break; } - } catch (Exception e) { - e.printStackTrace(); } String path = null; diff --git a/src/api-impl/android/content/ContentProvider.java b/src/api-impl/android/content/ContentProvider.java index cfb49b6e..a1dca394 100644 --- a/src/api-impl/android/content/ContentProvider.java +++ b/src/api-impl/android/content/ContentProvider.java @@ -1,24 +1,17 @@ package android.content; -import android.content.res.XmlResourceParser; +import android.content.pm.PackageParser; public class ContentProvider { 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.this_application.getPackageName() + providerName; - } + for (PackageParser.Provider provider_parsed : Context.pkg.providers) { + String providerName = provider_parsed.className; 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 8f548655..7253e774 100644 --- a/src/api-impl/android/content/Context.java +++ b/src/api-impl/android/content/Context.java @@ -12,6 +12,7 @@ import android.app.SharedPreferencesImpl; import android.app.UiModeManager; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageParser; import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -76,6 +77,7 @@ public class Context extends Object { static ApplicationInfo application_info; static Resources.Theme theme; private static Map,Service> runningServices = new HashMap<>(); + public static PackageParser.Package pkg; static String apk_path = "/tmp/APK_PATH_SHOULD_HAVE_BEEN_FILLED_IN_BY_CODE_IN_main.c/"; @@ -100,14 +102,8 @@ public class Context extends Object { application_info = new ApplicationInfo(); application_info.dataDir = Environment.getExternalStorageDirectory().getAbsolutePath(); 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"); - } - } + pkg = new PackageParser(null).parsePackage(r, parser, 0, new String[1]); + application_info = pkg.applicationInfo; } catch (Exception e) { e.printStackTrace(); } @@ -117,33 +113,16 @@ public class Context extends Object { static Application createApplication(long native_window) throws Exception { Application 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 = packageName + className; - Class cls = Class.forName(className).asSubclass(Application.class); - Constructor constructor = cls.getConstructor(); - application = constructor.newInstance(); - if (application_theme != 0) - application.setTheme(application_theme); + if (pkg.applicationInfo.className != null) { + Class cls = Class.forName(pkg.applicationInfo.className).asSubclass(Application.class); + Constructor constructor = cls.getConstructor(); + application = constructor.newInstance(); + } else { + application = new Application(); + } + if (pkg.applicationInfo.theme != 0) + application.setTheme(pkg.applicationInfo.theme); application.native_window = native_window; this_application = application; return application; diff --git a/src/api-impl/android/content/pm/PackageInfo.java b/src/api-impl/android/content/pm/PackageInfo.java index 402bad55..dbb094f5 100644 --- a/src/api-impl/android/content/pm/PackageInfo.java +++ b/src/api-impl/android/content/pm/PackageInfo.java @@ -16,12 +16,6 @@ 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; - /** * Overall information about the contents of a package. This corresponds * to all of the information collected from AndroidManifest.xml. @@ -237,58 +231,6 @@ public class PackageInfo { */ public String requiredAccountType; - public PackageInfo() { - applicationInfo = new ApplicationInfo(); - try { - 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(); - } - System.out.println("PackageInfo(): packageName: >"+packageName+"<, versionCode: >"+versionCode+"<, versionName: >"+versionName+"<"); - } - public String toString() { return "PackageInfo{" + Integer.toHexString(System.identityHashCode(this)) + " " + packageName + "}"; } diff --git a/src/api-impl/android/content/pm/PackageManager.java b/src/api-impl/android/content/pm/PackageManager.java index 5e28e561..396d3455 100644 --- a/src/api-impl/android/content/pm/PackageManager.java +++ b/src/api-impl/android/content/pm/PackageManager.java @@ -27,7 +27,6 @@ import android.content.res.Resources; import android.content.res.XmlResourceParser; // import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.Bundle; import android.os.Environment; import android.os.UserHandle; import android.util.AndroidException; @@ -36,6 +35,7 @@ import android.util.Slog; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; class IPackageInstallObserver {} @@ -1374,7 +1374,7 @@ public class PackageManager { public PackageManager() { - package_info = new PackageInfo(); + package_info = PackageParser.generatePackageInfo(Context.pkg, new int[0], 0, 0, 0, new HashSet<>(), new PackageUserState()); } /** @@ -1696,32 +1696,12 @@ public class PackageManager { */ public ProviderInfo getProviderInfo(ComponentName component, int flags) throws Exception { - ProviderInfo providerInfo = new ProviderInfo(); - if ((flags & GET_META_DATA) == GET_META_DATA) { - String cls = component.getClassName(); - 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; - } + for (PackageParser.Provider p : Context.pkg.providers) { + if (p.className.equals(component.getClassName())) { + return p.info; } - parser.close(); } - return providerInfo; + throw new NameNotFoundException(); } /** @@ -2428,27 +2408,12 @@ public class PackageManager { * @throws Exception */ public ProviderInfo resolveContentProvider(String authority, int flags) throws Exception { - ProviderInfo providerInfo = new ProviderInfo(); - 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; - } + for (PackageParser.Provider p : Context.pkg.providers) { + if (p.info.authority.equals(authority)) + return p.info; } - parser.close(); - return providerInfo; + + throw new Exception("Provider not found: " + authority); } /** diff --git a/src/api-impl/android/content/pm/PackageParser.java b/src/api-impl/android/content/pm/PackageParser.java index 6b56d0bb..dbdabc99 100644 --- a/src/api-impl/android/content/pm/PackageParser.java +++ b/src/api-impl/android/content/pm/PackageParser.java @@ -17,6 +17,7 @@ package android.content.pm; import android.content.ComponentName; +import android.content.Intent; import android.content.IntentFilter; import android.content.res.AssetManager; import android.content.res.Configuration; @@ -936,7 +937,7 @@ public class PackageParser { return new Signature(sig); } - private Package parsePackage( + public Package parsePackage( Resources res, XmlResourceParser parser, int flags, String[] outError) throws XmlPullParserException, IOException { AttributeSet attrs = parser; @@ -1162,9 +1163,9 @@ public class PackageParser { return null; } } else if (minVers > SDK_VERSION) { - outError[0] = "Requires newer sdk version #" + minVers + " (current version is #" + SDK_VERSION + ")"; - mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; - return null; + // outError[0] = "Requires newer sdk version #" + minVers + " (current version is #" + SDK_VERSION + ")"; + // mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; + // return null; } if (targetCode != null) { @@ -2203,6 +2204,62 @@ public class PackageParser { return true; } + private boolean parseIntent(Resources res, XmlPullParser parser, AttributeSet attrs, boolean allowGlobs, + boolean allowAutoVerify, IntentInfo outInfo, String[] outError) + throws XmlPullParserException, IOException { + TypedArray sa = res.obtainAttributes(attrs, + com.android.internal.R.styleable.AndroidManifestIntentFilter); + TypedValue v = sa.peekValue( + com.android.internal.R.styleable.AndroidManifestIntentFilter_label); + if (v != null && (outInfo.labelRes=v.resourceId) == 0) { + outInfo.nonLocalizedLabel = v.coerceToString(); + } + outInfo.icon = sa.getResourceId( + com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0); + + outInfo.logo = sa.getResourceId( + com.android.internal.R.styleable.AndroidManifestIntentFilter_logo, 0); + sa.recycle(); + int outerDepth = parser.getDepth(); + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + continue; + } + String nodeName = parser.getName(); + if (nodeName.equals("action")) { + String value = parser.getAttributeValue( + ANDROID_RESOURCES, "name"); + if (value == null || value == "") { + outError[0] = "No value supplied for "; + return false; + } + XmlUtils.skipCurrentTag(parser); + outInfo.addAction(value); + } else if (nodeName.equals("category")) { + String value = parser.getAttributeValue( + ANDROID_RESOURCES, "name"); + if (value == null || value == "") { + outError[0] = "No value supplied for "; + return false; + } + XmlUtils.skipCurrentTag(parser); + } else if (nodeName.equals("data")) { + XmlUtils.skipCurrentTag(parser); + } else if (!RIGID_PARSER) { + Slog.w(TAG, "Unknown element under : " + + parser.getName() + " at " + mArchiveSourcePath + " " + + parser.getPositionDescription()); + XmlUtils.skipCurrentTag(parser); + } else { + outError[0] = "Bad element under : " + parser.getName(); + return false; + } + } + return true; + } + private Activity parseActivity(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs, int flags, String[] outError, boolean receiver, boolean hardwareAccelerated) @@ -2405,7 +2462,20 @@ public class PackageParser { continue; } - if (parser.getName().equals("meta-data")) { + if (parser.getName().equals("intent-filter")) { + ActivityIntentInfo intent = new ActivityIntentInfo(a); + if (!parseIntent(res, parser, attrs, true /*allowGlobs*/, true /*allowAutoVerify*/, + intent, outError)) { + return null; + } + if (intent.countActions() == 0) { + Slog.w(TAG, "No actions in intent filter at " + + mArchiveSourcePath + " " + + parser.getPositionDescription()); + } else { + a.intents.add(intent); + } + } else if (parser.getName().equals("meta-data")) { if ((a.metaData = parseMetaData(res, parser, attrs, a.metaData, outError)) == null) { return null; @@ -2721,6 +2791,7 @@ public class PackageParser { outInfo.metaData, outError)) == null) { return false; } + outInfo.info.metaData = outInfo.metaData; } else if (parser.getName().equals("grant-uri-permission")) { TypedArray sa = res.obtainAttributes(attrs,