private boolean parsePackage(Resources res, XmlResourceParser parser) { AttributeSet attrs = parser; mPackageInfo = new PackageInfo(); try { int type; while ((type = parser.next()) != XmlResourceParser.START_TAG && type != XmlResourceParser.END_DOCUMENT) ; // <manifest ... mPackageInfo.packageName = parser.getAttributeValue(null, "package").intern(); // After gradle-small 0.9.0, we roll out // `The Small exclusive flags` // F F F F F F F F // 1111 1111 1111 1111 1111 1111 1111 1111 // ^^^^ ^^^^ ^^^^ ^^^^ ^^^^ // ABI Flags (20) // ^ // nonResources Flag (1) // ^^^ ^^^^ ^^^^ // platformBuildVersionCode (11) => MAX=0x7FF=4095 int flags = parser.getAttributeIntValue(null, "platformBuildVersionCode", 0); int abiFlags = (flags & 0xFFFFF000) >> 12; mNonResources = (flags & 0x800) != 0; TypedArray sa = res.obtainAttributes(attrs, R.styleable.AndroidManifest); mPackageInfo.versionCode = sa.getInteger(R.styleable.AndroidManifest_versionCode, 0); String versionName = sa.getString(R.styleable.AndroidManifest_versionName); if (versionName != null) { mPackageInfo.versionName = versionName.intern(); } // <application ... while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT) { if (type == XmlResourceParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName.equals("application")) { ApplicationInfo app = new ApplicationInfo(Small.getContext().getApplicationInfo()); sa = res.obtainAttributes(attrs, R.styleable.AndroidManifestApplication); String name = sa.getString(R.styleable.AndroidManifestApplication_name); if (name != null) { app.className = name.intern(); } else { app.className = null; } // Get the label value which used as ABI flags. // This is depreciated, we read it from the `platformBuildVersionCode` instead. // TODO: Remove this if the gradle-small 0.9.0 or above being widely used. if (abiFlags == 0) { TypedValue label = new TypedValue(); if (sa.getValue(R.styleable.AndroidManifestApplication_label, label)) { if (label.type == TypedValue.TYPE_STRING) { abiFlags = Integer.parseInt(label.string.toString()); } else { abiFlags = label.data; } } } app.theme = sa.getResourceId(R.styleable.AndroidManifestApplication_theme, 0); mPackageInfo.applicationInfo = app; break; } } if (abiFlags != 0) { String abi = JNIUtils.getExtractABI(abiFlags, Bundle.is64bit()); if (abi != null) { mLibDir = "lib/" + abi + "/"; } } sa.recycle(); return true; } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; }
@Override public void addManifest(AndroidManifest androidManifest) { androidManifests.put(androidManifest.getPackageName(), androidManifest); // first opportunity to access a resource index for this manifest, use it to init the references androidManifest.initMetaData(RuntimeEnvironment.getAppResourceLoader()); PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = androidManifest.getPackageName(); packageInfo.versionName = androidManifest.getVersionName(); packageInfo.versionCode = androidManifest.getVersionCode(); ContentProviderData[] cpdata = androidManifest.getContentProviders().toArray(new ContentProviderData[] {}); if (cpdata.length == 0) { packageInfo.providers = null; } else { packageInfo.providers = new ProviderInfo[cpdata.length]; for (int i = 0; i < cpdata.length; i++) { ProviderInfo info = new ProviderInfo(); info.authority = cpdata[i].getAuthority(); info.name = cpdata[i].getClassName(); info.packageName = androidManifest.getPackageName(); packageInfo.providers[i] = info; } } // Populate information related to BroadcastReceivers. Broadcast receivers can be queried in two // possible ways, // 1. PackageManager#getPackageInfo(...), // 2. PackageManager#queryBroadcastReceivers(...) // The following piece of code will let you enable querying receivers through both the methods. List<ActivityInfo> receiverActivityInfos = new ArrayList<>(); for (int i = 0; i < androidManifest.getBroadcastReceivers().size(); ++i) { ActivityInfo activityInfo = new ActivityInfo(); activityInfo.name = androidManifest.getBroadcastReceivers().get(i).getClassName(); activityInfo.permission = androidManifest.getBroadcastReceivers().get(i).getPermission(); receiverActivityInfos.add(activityInfo); ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.activityInfo = activityInfo; IntentFilter filter = new IntentFilter(); for (String action : androidManifest.getBroadcastReceivers().get(i).getActions()) { filter.addAction(action); } resolveInfo.filter = filter; for (String action : androidManifest.getBroadcastReceivers().get(i).getActions()) { Intent intent = new Intent(action); intent.setPackage(androidManifest.getPackageName()); addResolveInfoForIntent(intent, resolveInfo); } } packageInfo.receivers = receiverActivityInfos.toArray(new ActivityInfo[0]); String[] usedPermissions = androidManifest.getUsedPermissions().toArray(new String[] {}); if (usedPermissions.length == 0) { packageInfo.requestedPermissions = null; } else { packageInfo.requestedPermissions = usedPermissions; } ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.flags = androidManifest.getApplicationFlags(); applicationInfo.targetSdkVersion = androidManifest.getTargetSdkVersion(); applicationInfo.packageName = androidManifest.getPackageName(); applicationInfo.processName = androidManifest.getProcessName(); applicationInfo.name = androidManifest.getApplicationName(); applicationInfo.metaData = metaDataToBundle(androidManifest.getApplicationMetaData()); applicationInfo.sourceDir = new File(".").getAbsolutePath(); applicationInfo.dataDir = TempDirectory.create().toAbsolutePath().toString(); ResourceIndex resourceIndex = RuntimeEnvironment.getAppResourceLoader().getResourceIndex(); if (androidManifest.getLabelRef() != null && resourceIndex != null) { Integer id = ResName.getResourceId( resourceIndex, androidManifest.getLabelRef(), androidManifest.getPackageName()); applicationInfo.labelRes = id != null ? id : 0; } packageInfo.applicationInfo = applicationInfo; addPackage(packageInfo); }