Loading services/core/java/com/android/server/pm/PackageManagerService.java +206 −75 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; import static android.content.pm.PackageParser.isApkFile; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.storage.StorageManager.FLAG_STORAGE_CE; import static android.os.storage.StorageManager.FLAG_STORAGE_DE; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDWR; Loading Loading @@ -19771,6 +19773,10 @@ public class PackageManagerService extends IPackageManager.Stub // writer synchronized (mPackages) { // NOTE: The system package always needs to be enabled; even if it's for // a compressed stub. If we don't, installing the system package fails // during scan [scanning checks the disabled packages]. We will reverse // this later, after we've "installed" the stub. // Reinstate the old system package enableSystemPackageLPw(disabledPs.pkg); // Remove any native libraries from the upgraded package. Loading @@ -19779,23 +19785,38 @@ public class PackageManagerService extends IPackageManager.Stub // Install the system package if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); try { installPackageFromSystemLIF(disabledPs.codePath, false /*isPrivileged*/, allUserHandles, outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " + e.getMessage()); return false; } finally { if (disabledPs.pkg.isStub) { mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/); } } return true; } /** * Installs a package that's already on the system partition. */ private PackageParser.Package installPackageFromSystemLIF(@NonNull File codePath, boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles, @Nullable PermissionsState origPermissionState, boolean writeSettings) throws PackageManagerException { int parseFlags = mDefParseFlags | PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR; if (locationIsPrivileged(disabledPs.codePath)) { if (isPrivileged || locationIsPrivileged(codePath)) { parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; } final PackageParser.Package newPkg; try { newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */, 0 /* currentTime */, null); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " + e.getMessage()); return false; } final PackageParser.Package newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null); try { // update shared libraries for the newly re-installed system package Loading @@ -19813,17 +19834,21 @@ public class PackageManagerService extends IPackageManager.Stub // Propagate the permissions state as we do not want to drop on the floor // runtime permissions. The update permissions method below will take // care of removing obsolete permissions and grant install permissions. ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); if (origPermissionState != null) { ps.getPermissionsState().copyFrom(origPermissionState); } updatePermissionsLPw(newPkg.packageName, newPkg, UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); final boolean applyUserRestrictions = (allUserHandles != null) && (origUserHandles != null); if (applyUserRestrictions) { boolean installedStateChanged = false; if (DEBUG_REMOVE) { Slog.d(TAG, "Propagating install state across reinstall"); } for (int userId : allUserHandles) { final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); final boolean installed = ArrayUtils.contains(origUserHandles, userId); if (DEBUG_REMOVE) { Slog.d(TAG, " user " + userId + " => " + installed); } Loading @@ -19846,7 +19871,7 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writeLPr(); } } return true; return newPkg; } private boolean deleteInstalledPackageLIF(PackageSetting ps, Loading Loading @@ -21779,7 +21804,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } synchronized (mPackages) { if (callingUid == Process.SHELL_UID && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { // Shell can only change whole packages between ENABLED and DISABLED_USER states Loading Loading @@ -21807,13 +21831,119 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); // Nothing to do return; } // If we're enabling a system stub, there's a little more work to do. // Prior to enabling the package, we need to decompress the APK(s) to the // data partition and then replace the version on the system partition. final PackageParser.Package deletedPkg = pkgSetting.pkg; final boolean isSystemStub = deletedPkg.isStub && deletedPkg.isSystemApp(); if (isSystemStub && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) { final File codePath = decompressPackage(deletedPkg); if (codePath == null) { Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name); return; } // TODO remove direct parsing of the package object during internal cleanup // of scan package // We need to call parse directly here for no other reason than we need // the new package in order to disable the old one [we use the information // for some internal optimization to optionally create a new package setting // object on replace]. However, we can't get the package from the scan // because the scan modifies live structures and we need to remove the // old [system] package from the system before a scan can be attempted. // Once scan is indempotent we can remove this parse and use the package // object we scanned, prior to adding it to package settings. final PackageParser pp = new PackageParser(); pp.setSeparateProcesses(mSeparateProcesses); pp.setDisplayMetrics(mMetrics); pp.setCallback(mPackageParserCallback); final PackageParser.Package tmpPkg; try { final int parseFlags = mDefParseFlags | PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR; tmpPkg = pp.parsePackage(codePath, parseFlags); } catch (PackageParserException e) { Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e); return; } synchronized (mInstallLock) { // Disable the stub and remove any package entries removePackageLI(deletedPkg, true); synchronized (mPackages) { disableSystemPackageLPw(deletedPkg, tmpPkg); } final PackageParser.Package newPkg; try (PackageFreezer freezer = freezePackage(deletedPkg.packageName, "setEnabledSetting")) { final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | PackageParser.PARSE_ENFORCE_CODE; newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null /*user*/); prepareAppDataAfterInstallLIF(newPkg); synchronized (mPackages) { try { updateSharedLibrariesLPr(newPkg, null); } catch (PackageManagerException e) { Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e); } updatePermissionsLPw(newPkg.packageName, newPkg, UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); mSettings.writeLPr(); } } catch (PackageManagerException e) { // Whoops! Something went wrong; try to roll back to the stub Slog.w(TAG, "Failed to install compressed system package:" + pkgSetting.name, e); // Remove the failed install removeCodePathLI(codePath); // Install the system package try (PackageFreezer freezer = freezePackage(deletedPkg.packageName, "setEnabledSetting")) { synchronized (mPackages) { // NOTE: The system package always needs to be enabled; even // if it's for a compressed stub. If we don't, installing the // system package fails during scan [scanning checks the disabled // packages]. We will reverse this later, after we've "installed" // the stub. // This leaves us in a fragile state; the stub should never be // enabled, so, cross your fingers and hope nothing goes wrong // until we can disable the package later. enableSystemPackageLPw(deletedPkg); } installPackageFromSystemLIF(new File(deletedPkg.codePath), false /*isPrivileged*/, null /*allUserHandles*/, null /*origUserHandles*/, null /*origPermissionsState*/, true /*writeSettings*/); } catch (PackageManagerException pme) { Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName, pme); } finally { synchronized (mPackages) { mSettings.disableSystemPackageLPw( deletedPkg.packageName, true /*replaced*/); mSettings.writeLPr(); } } return; } clearAppDataLIF(newPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); clearAppProfilesLIF(newPkg, UserHandle.USER_ALL); mDexManager.notifyPackageUpdated(newPkg.packageName, newPkg.baseCodePath, newPkg.splitCodePaths); } } if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { // Don't care about who enables an app. callingPackage = null; } pkgSetting.setEnabled(newState, userId, callingPackage); // pkgSetting.pkg.mSetEnabled = newState; } else { // We're dealing with a component level state change // First, verify that this is a valid class name. Loading Loading @@ -21850,6 +21980,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); return; } } synchronized (mPackages) { scheduleWritePackageRestrictionsLocked(userId); updateSequenceNumberLP(pkgSetting, new int[] { userId }); final long callingId = Binder.clearCallingIdentity(); Loading
services/core/java/com/android/server/pm/PackageManagerService.java +206 −75 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; import static android.content.pm.PackageParser.isApkFile; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.storage.StorageManager.FLAG_STORAGE_CE; import static android.os.storage.StorageManager.FLAG_STORAGE_DE; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDWR; Loading Loading @@ -19771,6 +19773,10 @@ public class PackageManagerService extends IPackageManager.Stub // writer synchronized (mPackages) { // NOTE: The system package always needs to be enabled; even if it's for // a compressed stub. If we don't, installing the system package fails // during scan [scanning checks the disabled packages]. We will reverse // this later, after we've "installed" the stub. // Reinstate the old system package enableSystemPackageLPw(disabledPs.pkg); // Remove any native libraries from the upgraded package. Loading @@ -19779,23 +19785,38 @@ public class PackageManagerService extends IPackageManager.Stub // Install the system package if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs); try { installPackageFromSystemLIF(disabledPs.codePath, false /*isPrivileged*/, allUserHandles, outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " + e.getMessage()); return false; } finally { if (disabledPs.pkg.isStub) { mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/); } } return true; } /** * Installs a package that's already on the system partition. */ private PackageParser.Package installPackageFromSystemLIF(@NonNull File codePath, boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles, @Nullable PermissionsState origPermissionState, boolean writeSettings) throws PackageManagerException { int parseFlags = mDefParseFlags | PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR; if (locationIsPrivileged(disabledPs.codePath)) { if (isPrivileged || locationIsPrivileged(codePath)) { parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; } final PackageParser.Package newPkg; try { newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */, 0 /* currentTime */, null); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": " + e.getMessage()); return false; } final PackageParser.Package newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null); try { // update shared libraries for the newly re-installed system package Loading @@ -19813,17 +19834,21 @@ public class PackageManagerService extends IPackageManager.Stub // Propagate the permissions state as we do not want to drop on the floor // runtime permissions. The update permissions method below will take // care of removing obsolete permissions and grant install permissions. ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState()); if (origPermissionState != null) { ps.getPermissionsState().copyFrom(origPermissionState); } updatePermissionsLPw(newPkg.packageName, newPkg, UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); final boolean applyUserRestrictions = (allUserHandles != null) && (origUserHandles != null); if (applyUserRestrictions) { boolean installedStateChanged = false; if (DEBUG_REMOVE) { Slog.d(TAG, "Propagating install state across reinstall"); } for (int userId : allUserHandles) { final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId); final boolean installed = ArrayUtils.contains(origUserHandles, userId); if (DEBUG_REMOVE) { Slog.d(TAG, " user " + userId + " => " + installed); } Loading @@ -19846,7 +19871,7 @@ public class PackageManagerService extends IPackageManager.Stub mSettings.writeLPr(); } } return true; return newPkg; } private boolean deleteInstalledPackageLIF(PackageSetting ps, Loading Loading @@ -21779,7 +21804,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } synchronized (mPackages) { if (callingUid == Process.SHELL_UID && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { // Shell can only change whole packages between ENABLED and DISABLED_USER states Loading Loading @@ -21807,13 +21831,119 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); // Nothing to do return; } // If we're enabling a system stub, there's a little more work to do. // Prior to enabling the package, we need to decompress the APK(s) to the // data partition and then replace the version on the system partition. final PackageParser.Package deletedPkg = pkgSetting.pkg; final boolean isSystemStub = deletedPkg.isStub && deletedPkg.isSystemApp(); if (isSystemStub && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) { final File codePath = decompressPackage(deletedPkg); if (codePath == null) { Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name); return; } // TODO remove direct parsing of the package object during internal cleanup // of scan package // We need to call parse directly here for no other reason than we need // the new package in order to disable the old one [we use the information // for some internal optimization to optionally create a new package setting // object on replace]. However, we can't get the package from the scan // because the scan modifies live structures and we need to remove the // old [system] package from the system before a scan can be attempted. // Once scan is indempotent we can remove this parse and use the package // object we scanned, prior to adding it to package settings. final PackageParser pp = new PackageParser(); pp.setSeparateProcesses(mSeparateProcesses); pp.setDisplayMetrics(mMetrics); pp.setCallback(mPackageParserCallback); final PackageParser.Package tmpPkg; try { final int parseFlags = mDefParseFlags | PackageParser.PARSE_MUST_BE_APK | PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR; tmpPkg = pp.parsePackage(codePath, parseFlags); } catch (PackageParserException e) { Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e); return; } synchronized (mInstallLock) { // Disable the stub and remove any package entries removePackageLI(deletedPkg, true); synchronized (mPackages) { disableSystemPackageLPw(deletedPkg, tmpPkg); } final PackageParser.Package newPkg; try (PackageFreezer freezer = freezePackage(deletedPkg.packageName, "setEnabledSetting")) { final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY | PackageParser.PARSE_ENFORCE_CODE; newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null /*user*/); prepareAppDataAfterInstallLIF(newPkg); synchronized (mPackages) { try { updateSharedLibrariesLPr(newPkg, null); } catch (PackageManagerException e) { Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e); } updatePermissionsLPw(newPkg.packageName, newPkg, UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG); mSettings.writeLPr(); } } catch (PackageManagerException e) { // Whoops! Something went wrong; try to roll back to the stub Slog.w(TAG, "Failed to install compressed system package:" + pkgSetting.name, e); // Remove the failed install removeCodePathLI(codePath); // Install the system package try (PackageFreezer freezer = freezePackage(deletedPkg.packageName, "setEnabledSetting")) { synchronized (mPackages) { // NOTE: The system package always needs to be enabled; even // if it's for a compressed stub. If we don't, installing the // system package fails during scan [scanning checks the disabled // packages]. We will reverse this later, after we've "installed" // the stub. // This leaves us in a fragile state; the stub should never be // enabled, so, cross your fingers and hope nothing goes wrong // until we can disable the package later. enableSystemPackageLPw(deletedPkg); } installPackageFromSystemLIF(new File(deletedPkg.codePath), false /*isPrivileged*/, null /*allUserHandles*/, null /*origUserHandles*/, null /*origPermissionsState*/, true /*writeSettings*/); } catch (PackageManagerException pme) { Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName, pme); } finally { synchronized (mPackages) { mSettings.disableSystemPackageLPw( deletedPkg.packageName, true /*replaced*/); mSettings.writeLPr(); } } return; } clearAppDataLIF(newPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY); clearAppProfilesLIF(newPkg, UserHandle.USER_ALL); mDexManager.notifyPackageUpdated(newPkg.packageName, newPkg.baseCodePath, newPkg.splitCodePaths); } } if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) { // Don't care about who enables an app. callingPackage = null; } pkgSetting.setEnabled(newState, userId, callingPackage); // pkgSetting.pkg.mSetEnabled = newState; } else { // We're dealing with a component level state change // First, verify that this is a valid class name. Loading Loading @@ -21850,6 +21980,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); return; } } synchronized (mPackages) { scheduleWritePackageRestrictionsLocked(userId); updateSequenceNumberLP(pkgSetting, new int[] { userId }); final long callingId = Binder.clearCallingIdentity();