PMS
aospxref.com/android-11.…
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
PackageManagerServiceCompilerMapping.checkProperties();
final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
Trace.TRACE_TAG_PACKAGE_MANAGER);
t.traceBegin("create package manager");
final Object lock = new Object();
final Object installLock = new Object();
Injector injector = new Injector(
context, lock, installer, installLock, new PackageAbiHelperImpl(),
(i, pm) ->
new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
(i, pm) ->
PermissionManagerService.create(context, lock),
(i, pm) ->
new UserManagerService(context, pm,
new UserDataPreparer(installer, installLock, context, onlyCore),
lock),
(i, pm) ->
new Settings(Environment.getDataDirectory(),
i.getPermissionManagerServiceInternal().getPermissionSettings(),
lock),
new Injector.LocalServicesProducer<>(ActivityTaskManagerInternal.class),
new Injector.LocalServicesProducer<>(ActivityManagerInternal.class),
new Injector.LocalServicesProducer<>(DeviceIdleInternal.class),
new Injector.LocalServicesProducer<>(StorageManagerInternal.class),
new Injector.LocalServicesProducer<>(NetworkPolicyManagerInternal.class),
new Injector.LocalServicesProducer<>(PermissionPolicyInternal.class),
new Injector.LocalServicesProducer<>(DeviceStorageMonitorInternal.class),
new Injector.SystemServiceProducer<>(DisplayManager.class),
new Injector.SystemServiceProducer<>(StorageManager.class),
new Injector.SystemServiceProducer<>(AppOpsManager.class),
(i, pm) -> AppsFilter.create(pm.mPmInternal, i),
(i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"));
PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest);
t.traceEnd();
injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
packageName -> {
synchronized (m.mInstallLock) {
final AndroidPackage pkg;
final PackageSetting ps;
final SharedUserSetting sharedUser;
final String oldSeInfo;
synchronized (m.mLock) {
ps = m.mSettings.getPackageLPr(packageName);
if (ps == null) {
Slog.e(TAG, "Failed to find package setting " + packageName);
return;
}
pkg = ps.pkg;
sharedUser = ps.getSharedUser();
oldSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);
}
if (pkg == null) {
Slog.e(TAG, "Failed to find package " + packageName);
return;
}
final String newSeInfo = SELinuxMMAC.getSeInfo(pkg, sharedUser,
m.mInjector.getCompatibility());
if (!newSeInfo.equals(oldSeInfo)) {
Slog.i(TAG, "Updating seInfo for package " + packageName + " from: "
+ oldSeInfo + " to: " + newSeInfo);
ps.getPkgState().setOverrideSeInfo(newSeInfo);
m.prepareAppDataAfterInstallLIF(pkg);
}
}
});
m.installWhitelistedSystemPackages();
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
PackageManagerNative Binder
private class PackageManagerNative extends IPackageManagerNative.Stub {
@Override
public void registerPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
synchronized (mPackageChangeObservers) {
try {
observer.asBinder().linkToDeath(
new PackageChangeObserverDeathRecipient(observer), 0);
} catch (RemoteException e) {
Log.e(TAG, e.getMessage());
}
mPackageChangeObservers.add(observer);
Log.d(TAG, "Size of mPackageChangeObservers after registry is "
+ mPackageChangeObservers.size());
}
}
@Override
public void unregisterPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
synchronized (mPackageChangeObservers) {
mPackageChangeObservers.remove(observer);
Log.d(TAG, "Size of mPackageChangeObservers after unregistry is "
+ mPackageChangeObservers.size());
}
}
@Override
public String[] getAllPackages() {
return PackageManagerService.this.getAllPackages().toArray(new String[0]);
}
@Override
public String[] getNamesForUids(int[] uids) throws RemoteException {
final String[] results = PackageManagerService.this.getNamesForUids(uids);
for (int i = results.length - 1; i >= 0; --i) {
if (results[i] == null) {
results[i] = "";
}
}
return results;
}
@Override
public String getInstallerForPackage(String packageName) throws RemoteException {
final String installerName = getInstallerPackageName(packageName);
if (!TextUtils.isEmpty(installerName)) {
return installerName;
}
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
ApplicationInfo appInfo = getApplicationInfo(packageName,
0,
callingUser);
if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
return "preload";
}
return "";
}
@Override
public long getVersionCodeForPackage(String packageName) throws RemoteException {
try {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
if (pInfo != null) {
return pInfo.getLongVersionCode();
}
} catch (Exception e) {
}
return 0;
}
@Override
public int getTargetSdkVersionForPackage(String packageName)
throws RemoteException {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
ApplicationInfo info = getApplicationInfo(packageName, 0, callingUser);
if (info == null) {
throw new RemoteException(
"Couldn't get ApplicationInfo for package " + packageName);
}
return info.targetSdkVersion;
}
@Override
public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
throws RemoteException {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
boolean[] results = new boolean[packageNames.length];
for (int i = results.length - 1; i >= 0; --i) {
ApplicationInfo appInfo = getApplicationInfo(packageNames[i], 0, callingUser);
results[i] = appInfo == null ? false : appInfo.isAudioPlaybackCaptureAllowed();
}
return results;
}
@Override
public int getLocationFlags(String packageName) throws RemoteException {
int callingUser = UserHandle.getUserId(Binder.getCallingUid());
ApplicationInfo appInfo = getApplicationInfo(packageName,
0,
callingUser);
if (appInfo == null) {
throw new RemoteException(
"Couldn't get ApplicationInfo for package " + packageName);
}
return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
| (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
| (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
}
@Override
public String getModuleMetadataPackageName() throws RemoteException {
return PackageManagerService.this.mModuleInfoProvider.getPackageName();
}
}
/data/app
private static final File sAppInstallDir =
new File(Environment.getDataDirectory(), "app");
scanDirLI
private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags,
long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
try {
scanDirLI(scanDir, parseFlags, scanFlags, currentTime, packageParser, executorService);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,
PackageParser2 packageParser, ExecutorService executorService) {
final File[] files = scanDir.listFiles();
if (ArrayUtils.isEmpty(files)) {
Log.d(TAG, "No files in app dir " + scanDir);
return;
}
if (DEBUG_PACKAGE_SCANNING) {
Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
+ " flags=0x" + Integer.toHexString(parseFlags));
}
ParallelPackageParser parallelPackageParser =
new ParallelPackageParser(packageParser, executorService);
int fileCount = 0;
for (File file : files) {
final boolean isPackage = (isApkFile(file) || file.isDirectory())
&& !PackageInstallerService.isStageName(file.getName());
if (!isPackage) {
continue;
}
parallelPackageParser.submit(file, parseFlags);
fileCount++;
}
for (; fileCount > 0; fileCount--) {
ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
Throwable throwable = parseResult.throwable;
int errorCode = PackageManager.INSTALL_SUCCEEDED;
if (throwable == null) {
if (parseResult.parsedPackage.isStaticSharedLibrary()) {
renameStaticSharedLibraryPackage(parseResult.parsedPackage);
}
try {
addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
currentTime, null);
} catch (PackageManagerException e) {
errorCode = e.error;
Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
}
} else if (throwable instanceof PackageParserException) {
PackageParserException e = (PackageParserException)
throwable;
errorCode = e.error;
Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
} else {
throw new IllegalStateException("Unexpected exception occurred while parsing "
+ parseResult.scanFile, throwable);
}
if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0 && errorCode != INSTALL_SUCCEEDED) {
mApexManager.reportErrorWithApkInApex(scanDir.getAbsolutePath());
}
if ((scanFlags & SCAN_AS_SYSTEM) == 0
&& errorCode != PackageManager.INSTALL_SUCCEEDED) {
logCriticalInfo(Log.WARN,
"Deleting invalid package at " + parseResult.scanFile);
removeCodePathLI(parseResult.scanFile);
}
}
}
parallelPackageParser.submit(file, parseFlags);
public void submit(File scanFile, int parseFlags) {
mExecutorService.submit(() -> {
ParseResult pr = new ParseResult();
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parallel parsePackage [" + scanFile + "]");
try {
pr.scanFile = scanFile;
pr.parsedPackage = parsePackage(scanFile, parseFlags);
} catch (Throwable e) {
pr.throwable = e;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
try {
mQueue.put(pr);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
mInterruptedInThread = Thread.currentThread().getName();
}
});
}
@VisibleForTesting
protected ParsedPackage parsePackage(File scanFile, int parseFlags)
throws PackageParser.PackageParserException {
return mPackageParser.parsePackage(scanFile, parseFlags, true);
}
mPackageParser.parsePackage(scanFile, parseFlags, true);
static class ParseResult {
ParsedPackage parsedPackage;
File scanFile;
Throwable throwable;
@Override
public String toString() {
return "ParseResult{" +
"parsedPackage=" + parsedPackage +
", scanFile=" + scanFile +
", throwable=" + throwable +
'}';
}
}
Android 9
PackageParser
aospxref.com/android-9.0…
public final static class Package implements Parcelable {
public String packageName;
public String manifestPackageName;
public String[] splitNames;
public String volumeUuid;
public String codePath;
public String baseCodePath;
public String[] splitCodePaths;
public int baseRevisionCode;
public int[] splitRevisionCodes;
public int[] splitFlags;
public int[] splitPrivateFlags;
public boolean baseHardwareAccelerated;
public ApplicationInfo applicationInfo = new ApplicationInfo();
public final ArrayList<Permission> permissions = new ArrayList<Permission>(0);
public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0);
public final ArrayList<Activity> activities = new ArrayList<Activity>(0);
public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
public final ArrayList<Service> services = new ArrayList<Service>(0);
public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
public final ArrayList<String> requestedPermissions = new ArrayList<String>();
public ArrayList<String> protectedBroadcasts;
public Package parentPackage;
public ArrayList<Package> childPackages;
public String staticSharedLibName = null;
public long staticSharedLibVersion = 0;
public ArrayList<String> libraryNames = null;
public ArrayList<String> usesLibraries = null;
public ArrayList<String> usesStaticLibraries = null;
public long[] usesStaticLibrariesVersions = null;
public String[][] usesStaticLibrariesCertDigests = null;
public ArrayList<String> usesOptionalLibraries = null;
public String[] usesLibraryFiles = null;
public ArrayList<ActivityIntentInfo> preferredActivityFilters = null;
public ArrayList<String> mOriginalPackages = null;
public String mRealPackage = null;
public ArrayList<String> mAdoptPermissions = null;
public Bundle mAppMetaData = null;
public int mVersionCode;
public int mVersionCodeMajor;
public long getLongVersionCode() {
return PackageInfo.composeLongVersionCode(mVersionCodeMajor, mVersionCode);
}
public String mVersionName;
public String mSharedUserId;
public int mSharedUserLabel;
@NonNull public SigningDetails mSigningDetails = SigningDetails.UNKNOWN;
public int mPreferredOrder = 0;
public long[] mLastPackageUsageTimeInMills =
new long[PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT];
public Object mExtras;
public ArrayList<ConfigurationInfo> configPreferences = null;
public ArrayList<FeatureInfo> reqFeatures = null;
public ArrayList<FeatureGroupInfo> featureGroups = null;
public int installLocation;
public boolean coreApp;
public boolean mRequiredForAllUsers;
public String mRestrictedAccountType;
public String mRequiredAccountType;
public String mOverlayTarget;
public String mOverlayCategory;
public int mOverlayPriority;
public boolean mOverlayIsStatic;
public int mCompileSdkVersion;
public String mCompileSdkVersionCodename;
public ArraySet<String> mUpgradeKeySets;
public ArrayMap<String, ArraySet<PublicKey>> mKeySetMapping;
public String cpuAbiOverride;
public boolean use32bitAbi;
public byte[] restrictUpdateHash;
public boolean visibleToInstantApps;
public boolean isStub;
public Package(String packageName) {
this.packageName = packageName;
this.manifestPackageName = packageName;
applicationInfo.packageName = packageName;
applicationInfo.uid = -1;
}
public void setApplicationVolumeUuid(String volumeUuid) {
final UUID storageUuid = StorageManager.convert(volumeUuid);
this.applicationInfo.volumeUuid = volumeUuid;
this.applicationInfo.storageUuid = storageUuid;
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).applicationInfo.volumeUuid = volumeUuid;
childPackages.get(i).applicationInfo.storageUuid = storageUuid;
}
}
}
public void setApplicationInfoCodePath(String codePath) {
this.applicationInfo.setCodePath(codePath);
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).applicationInfo.setCodePath(codePath);
}
}
}
@Deprecated
public void setApplicationInfoResourcePath(String resourcePath) {
this.applicationInfo.setResourcePath(resourcePath);
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).applicationInfo.setResourcePath(resourcePath);
}
}
}
@Deprecated
public void setApplicationInfoBaseResourcePath(String resourcePath) {
this.applicationInfo.setBaseResourcePath(resourcePath);
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).applicationInfo.setBaseResourcePath(resourcePath);
}
}
}
public void setApplicationInfoBaseCodePath(String baseCodePath) {
this.applicationInfo.setBaseCodePath(baseCodePath);
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).applicationInfo.setBaseCodePath(baseCodePath);
}
}
}
public List<String> getChildPackageNames() {
if (childPackages == null) {
return null;
}
final int childCount = childPackages.size();
final List<String> childPackageNames = new ArrayList<>(childCount);
for (int i = 0; i < childCount; i++) {
String childPackageName = childPackages.get(i).packageName;
childPackageNames.add(childPackageName);
}
return childPackageNames;
}
public boolean hasChildPackage(String packageName) {
final int childCount = (childPackages != null) ? childPackages.size() : 0;
for (int i = 0; i < childCount; i++) {
if (childPackages.get(i).packageName.equals(packageName)) {
return true;
}
}
return false;
}
public void setApplicationInfoSplitCodePaths(String[] splitCodePaths) {
this.applicationInfo.setSplitCodePaths(splitCodePaths);
}
@Deprecated
public void setApplicationInfoSplitResourcePaths(String[] resroucePaths) {
this.applicationInfo.setSplitResourcePaths(resroucePaths);
}
public void setSplitCodePaths(String[] codePaths) {
this.splitCodePaths = codePaths;
}
public void setCodePath(String codePath) {
this.codePath = codePath;
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).codePath = codePath;
}
}
}
public void setBaseCodePath(String baseCodePath) {
this.baseCodePath = baseCodePath;
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).baseCodePath = baseCodePath;
}
}
}
public void setSigningDetails(@NonNull SigningDetails signingDetails) {
mSigningDetails = signingDetails;
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).mSigningDetails = signingDetails;
}
}
}
public void setVolumeUuid(String volumeUuid) {
this.volumeUuid = volumeUuid;
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).volumeUuid = volumeUuid;
}
}
}
public void setApplicationInfoFlags(int mask, int flags) {
applicationInfo.flags = (applicationInfo.flags & ~mask) | (mask & flags);
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).applicationInfo.flags =
(applicationInfo.flags & ~mask) | (mask & flags);
}
}
}
public void setUse32bitAbi(boolean use32bitAbi) {
this.use32bitAbi = use32bitAbi;
if (childPackages != null) {
final int packageCount = childPackages.size();
for (int i = 0; i < packageCount; i++) {
childPackages.get(i).use32bitAbi = use32bitAbi;
}
}
}
public boolean isLibrary() {
return staticSharedLibName != null || !ArrayUtils.isEmpty(libraryNames);
}
public List<String> getAllCodePaths() {
ArrayList<String> paths = new ArrayList<>();
paths.add(baseCodePath);
if (!ArrayUtils.isEmpty(splitCodePaths)) {
Collections.addAll(paths, splitCodePaths);
}
return paths;
}
public List<String> getAllCodePathsExcludingResourceOnly() {
ArrayList<String> paths = new ArrayList<>();
if ((applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
paths.add(baseCodePath);
}
if (!ArrayUtils.isEmpty(splitCodePaths)) {
for (int i = 0; i < splitCodePaths.length; i++) {
if ((splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) {
paths.add(splitCodePaths[i]);
}
}
}
return paths;
}
public void setPackageName(String newName) {
packageName = newName;
applicationInfo.packageName = newName;
for (int i=permissions.size()-1; i>=0; i--) {
permissions.get(i).setPackageName(newName);
}
for (int i=permissionGroups.size()-1; i>=0; i--) {
permissionGroups.get(i).setPackageName(newName);
}
for (int i=activities.size()-1; i>=0; i--) {
activities.get(i).setPackageName(newName);
}
for (int i=receivers.size()-1; i>=0; i--) {
receivers.get(i).setPackageName(newName);
}
for (int i=providers.size()-1; i>=0; i--) {
providers.get(i).setPackageName(newName);
}
for (int i=services.size()-1; i>=0; i--) {
services.get(i).setPackageName(newName);
}
for (int i=instrumentation.size()-1; i>=0; i--) {
instrumentation.get(i).setPackageName(newName);
}
}
public boolean hasComponentClassName(String name) {
for (int i=activities.size()-1; i>=0; i--) {
if (name.equals(activities.get(i).className)) {
return true;
}
}
for (int i=receivers.size()-1; i>=0; i--) {
if (name.equals(receivers.get(i).className)) {
return true;
}
}
for (int i=providers.size()-1; i>=0; i--) {
if (name.equals(providers.get(i).className)) {
return true;
}
}
for (int i=services.size()-1; i>=0; i--) {
if (name.equals(services.get(i).className)) {
return true;
}
}
for (int i=instrumentation.size()-1; i>=0; i--) {
if (name.equals(instrumentation.get(i).className)) {
return true;
}
}
return false;
}
public boolean isExternal() {
return applicationInfo.isExternal();
}
public boolean isForwardLocked() {
return applicationInfo.isForwardLocked();
}
public boolean isOem() {
return applicationInfo.isOem();
}
public boolean isVendor() {
return applicationInfo.isVendor();
}
public boolean isProduct() {
return applicationInfo.isProduct();
}
public boolean isPrivileged() {
return applicationInfo.isPrivilegedApp();
}
public boolean isSystem() {
return applicationInfo.isSystemApp();
}
public boolean isUpdatedSystemApp() {
return applicationInfo.isUpdatedSystemApp();
}
public boolean canHaveOatDir() {
return (!isSystem() || isUpdatedSystemApp())
&& !isForwardLocked() && !applicationInfo.isExternalAsec();
}
public boolean isMatch(int flags) {
if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
return isSystem();
}
return true;
}
public long getLatestPackageUseTimeInMills() {
long latestUse = 0L;
for (long use : mLastPackageUsageTimeInMills) {
latestUse = Math.max(latestUse, use);
}
return latestUse;
}
public long getLatestForegroundPackageUseTimeInMills() {
int[] foregroundReasons = {
PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY,
PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE
};
long latestUse = 0L;
for (int reason : foregroundReasons) {
latestUse = Math.max(latestUse, mLastPackageUsageTimeInMills[reason]);
}
return latestUse;
}
public String toString() {
return "Package{"
+ Integer.toHexString(System.identityHashCode(this))
+ " " + packageName + "}";
}
@Override
public int describeContents() {
return 0;
}
public Package(Parcel dest) {
final ClassLoader boot = Object.class.getClassLoader();
packageName = dest.readString().intern();
manifestPackageName = dest.readString();
splitNames = dest.readStringArray();
volumeUuid = dest.readString();
codePath = dest.readString();
baseCodePath = dest.readString();
splitCodePaths = dest.readStringArray();
baseRevisionCode = dest.readInt();
splitRevisionCodes = dest.createIntArray();
splitFlags = dest.createIntArray();
splitPrivateFlags = dest.createIntArray();
baseHardwareAccelerated = (dest.readInt() == 1);
applicationInfo = dest.readParcelable(boot);
if (applicationInfo.permission != null) {
applicationInfo.permission = applicationInfo.permission.intern();
}
dest.readParcelableList(permissions, boot);
fixupOwner(permissions);
dest.readParcelableList(permissionGroups, boot);
fixupOwner(permissionGroups);
dest.readParcelableList(activities, boot);
fixupOwner(activities);
dest.readParcelableList(receivers, boot);
fixupOwner(receivers);
dest.readParcelableList(providers, boot);
fixupOwner(providers);
dest.readParcelableList(services, boot);
fixupOwner(services);
dest.readParcelableList(instrumentation, boot);
fixupOwner(instrumentation);
dest.readStringList(requestedPermissions);
internStringArrayList(requestedPermissions);
protectedBroadcasts = dest.createStringArrayList();
internStringArrayList(protectedBroadcasts);
parentPackage = dest.readParcelable(boot);
childPackages = new ArrayList<>();
dest.readParcelableList(childPackages, boot);
if (childPackages.size() == 0) {
childPackages = null;
}
staticSharedLibName = dest.readString();
if (staticSharedLibName != null) {
staticSharedLibName = staticSharedLibName.intern();
}
staticSharedLibVersion = dest.readLong();
libraryNames = dest.createStringArrayList();
internStringArrayList(libraryNames);
usesLibraries = dest.createStringArrayList();
internStringArrayList(usesLibraries);
usesOptionalLibraries = dest.createStringArrayList();
internStringArrayList(usesOptionalLibraries);
usesLibraryFiles = dest.readStringArray();
final int libCount = dest.readInt();
if (libCount > 0) {
usesStaticLibraries = new ArrayList<>(libCount);
dest.readStringList(usesStaticLibraries);
internStringArrayList(usesStaticLibraries);
usesStaticLibrariesVersions = new long[libCount];
dest.readLongArray(usesStaticLibrariesVersions);
usesStaticLibrariesCertDigests = new String[libCount][];
for (int i = 0; i < libCount; i++) {
usesStaticLibrariesCertDigests[i] = dest.createStringArray();
}
}
preferredActivityFilters = new ArrayList<>();
dest.readParcelableList(preferredActivityFilters, boot);
if (preferredActivityFilters.size() == 0) {
preferredActivityFilters = null;
}
mOriginalPackages = dest.createStringArrayList();
mRealPackage = dest.readString();
mAdoptPermissions = dest.createStringArrayList();
mAppMetaData = dest.readBundle();
mVersionCode = dest.readInt();
mVersionCodeMajor = dest.readInt();
mVersionName = dest.readString();
if (mVersionName != null) {
mVersionName = mVersionName.intern();
}
mSharedUserId = dest.readString();
if (mSharedUserId != null) {
mSharedUserId = mSharedUserId.intern();
}
mSharedUserLabel = dest.readInt();
mSigningDetails = dest.readParcelable(boot);
mPreferredOrder = dest.readInt();
configPreferences = new ArrayList<>();
dest.readParcelableList(configPreferences, boot);
if (configPreferences.size() == 0) {
configPreferences = null;
}
reqFeatures = new ArrayList<>();
dest.readParcelableList(reqFeatures, boot);
if (reqFeatures.size() == 0) {
reqFeatures = null;
}
featureGroups = new ArrayList<>();
dest.readParcelableList(featureGroups, boot);
if (featureGroups.size() == 0) {
featureGroups = null;
}
installLocation = dest.readInt();
coreApp = (dest.readInt() == 1);
mRequiredForAllUsers = (dest.readInt() == 1);
mRestrictedAccountType = dest.readString();
mRequiredAccountType = dest.readString();
mOverlayTarget = dest.readString();
mOverlayCategory = dest.readString();
mOverlayPriority = dest.readInt();
mOverlayIsStatic = (dest.readInt() == 1);
mCompileSdkVersion = dest.readInt();
mCompileSdkVersionCodename = dest.readString();
mUpgradeKeySets = (ArraySet<String>) dest.readArraySet(boot);
mKeySetMapping = readKeySetMapping(dest);
cpuAbiOverride = dest.readString();
use32bitAbi = (dest.readInt() == 1);
restrictUpdateHash = dest.createByteArray();
visibleToInstantApps = dest.readInt() == 1;
}
private static void internStringArrayList(List<String> list) {
if (list != null) {
final int N = list.size();
for (int i = 0; i < N; ++i) {
list.set(i, list.get(i).intern());
}
}
}
private void fixupOwner(List<? extends Component<?>> list) {
if (list != null) {
for (Component<?> c : list) {
c.owner = this;
if (c instanceof Activity) {
((Activity) c).info.applicationInfo = this.applicationInfo;
} else if (c instanceof Service) {
((Service) c).info.applicationInfo = this.applicationInfo;
} else if (c instanceof Provider) {
((Provider) c).info.applicationInfo = this.applicationInfo;
}
}
}
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(packageName);
dest.writeString(manifestPackageName);
dest.writeStringArray(splitNames);
dest.writeString(volumeUuid);
dest.writeString(codePath);
dest.writeString(baseCodePath);
dest.writeStringArray(splitCodePaths);
dest.writeInt(baseRevisionCode);
dest.writeIntArray(splitRevisionCodes);
dest.writeIntArray(splitFlags);
dest.writeIntArray(splitPrivateFlags);
dest.writeInt(baseHardwareAccelerated ? 1 : 0);
dest.writeParcelable(applicationInfo, flags);
dest.writeParcelableList(permissions, flags);
dest.writeParcelableList(permissionGroups, flags);
dest.writeParcelableList(activities, flags);
dest.writeParcelableList(receivers, flags);
dest.writeParcelableList(providers, flags);
dest.writeParcelableList(services, flags);
dest.writeParcelableList(instrumentation, flags);
dest.writeStringList(requestedPermissions);
dest.writeStringList(protectedBroadcasts);
dest.writeParcelable(parentPackage, flags);
dest.writeParcelableList(childPackages, flags);
dest.writeString(staticSharedLibName);
dest.writeLong(staticSharedLibVersion);
dest.writeStringList(libraryNames);
dest.writeStringList(usesLibraries);
dest.writeStringList(usesOptionalLibraries);
dest.writeStringArray(usesLibraryFiles);
if (ArrayUtils.isEmpty(usesStaticLibraries)) {
dest.writeInt(-1);
} else {
dest.writeInt(usesStaticLibraries.size());
dest.writeStringList(usesStaticLibraries);
dest.writeLongArray(usesStaticLibrariesVersions);
for (String[] usesStaticLibrariesCertDigest : usesStaticLibrariesCertDigests) {
dest.writeStringArray(usesStaticLibrariesCertDigest);
}
}
dest.writeParcelableList(preferredActivityFilters, flags);
dest.writeStringList(mOriginalPackages);
dest.writeString(mRealPackage);
dest.writeStringList(mAdoptPermissions);
dest.writeBundle(mAppMetaData);
dest.writeInt(mVersionCode);
dest.writeInt(mVersionCodeMajor);
dest.writeString(mVersionName);
dest.writeString(mSharedUserId);
dest.writeInt(mSharedUserLabel);
dest.writeParcelable(mSigningDetails, flags);
dest.writeInt(mPreferredOrder);
dest.writeParcelableList(configPreferences, flags);
dest.writeParcelableList(reqFeatures, flags);
dest.writeParcelableList(featureGroups, flags);
dest.writeInt(installLocation);
dest.writeInt(coreApp ? 1 : 0);
dest.writeInt(mRequiredForAllUsers ? 1 : 0);
dest.writeString(mRestrictedAccountType);
dest.writeString(mRequiredAccountType);
dest.writeString(mOverlayTarget);
dest.writeString(mOverlayCategory);
dest.writeInt(mOverlayPriority);
dest.writeInt(mOverlayIsStatic ? 1 : 0);
dest.writeInt(mCompileSdkVersion);
dest.writeString(mCompileSdkVersionCodename);
dest.writeArraySet(mUpgradeKeySets);
writeKeySetMapping(dest, mKeySetMapping);
dest.writeString(cpuAbiOverride);
dest.writeInt(use32bitAbi ? 1 : 0);
dest.writeByteArray(restrictUpdateHash);
dest.writeInt(visibleToInstantApps ? 1 : 0);
}
private static void writeKeySetMapping(
Parcel dest, ArrayMap<String, ArraySet<PublicKey>> keySetMapping) {
if (keySetMapping == null) {
dest.writeInt(-1);
return;
}
final int N = keySetMapping.size();
dest.writeInt(N);
for (int i = 0; i < N; i++) {
dest.writeString(keySetMapping.keyAt(i));
ArraySet<PublicKey> keys = keySetMapping.valueAt(i);
if (keys == null) {
dest.writeInt(-1);
continue;
}
final int M = keys.size();
dest.writeInt(M);
for (int j = 0; j < M; j++) {
dest.writeSerializable(keys.valueAt(j));
}
}
}
private static ArrayMap<String, ArraySet<PublicKey>> readKeySetMapping(Parcel in) {
final int N = in.readInt();
if (N == -1) {
return null;
}
ArrayMap<String, ArraySet<PublicKey>> keySetMapping = new ArrayMap<>();
for (int i = 0; i < N; ++i) {
String key = in.readString();
final int M = in.readInt();
if (M == -1) {
keySetMapping.put(key, null);
continue;
}
ArraySet<PublicKey> keys = new ArraySet<>(M);
for (int j = 0; j < M; ++j) {
PublicKey pk = (PublicKey) in.readSerializable();
keys.add(pk);
}
keySetMapping.put(key, keys);
}
return keySetMapping;
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Package>() {
public Package createFromParcel(Parcel in) {
return new Package(in);
}
public Package[] newArray(int size) {
return new Package[size];
}
};
}
DexFile
