Loading services/core/java/com/android/server/pm/PackageHandler.java +1 −5 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import static com.android.server.pm.PackageManagerService.PRUNE_UNUSED_STATIC_SH import static com.android.server.pm.PackageManagerService.SEND_PENDING_BROADCAST; import static com.android.server.pm.PackageManagerService.TAG; import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_LIST; import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_RESTRICTIONS; import static com.android.server.pm.PackageManagerService.WRITE_SETTINGS; import android.content.Intent; Loading Loading @@ -119,10 +118,7 @@ final class PackageHandler extends Handler { } } break; case WRITE_SETTINGS: { mPm.writeSettings(); } break; case WRITE_PACKAGE_RESTRICTIONS: { mPm.writePendingRestrictions(); mPm.writeSettings(/*sync=*/false); } break; case WRITE_PACKAGE_LIST: { mPm.writePackageList(msg.arg1); Loading services/core/java/com/android/server/pm/PackageManagerService.java +52 −16 Original line number Diff line number Diff line Loading @@ -558,6 +558,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final char RANDOM_CODEPATH_PREFIX = '-'; final Handler mHandler; final Handler mBackgroundHandler; final ProcessLoggingHandler mProcessLoggingHandler; Loading Loading @@ -873,7 +874,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService // public static final int UNUSED = 5; static final int POST_INSTALL = 9; static final int WRITE_SETTINGS = 13; static final int WRITE_PACKAGE_RESTRICTIONS = 14; static final int WRITE_DIRTY_PACKAGE_RESTRICTIONS = 14; static final int PACKAGE_VERIFIED = 15; static final int CHECK_PENDING_VERIFICATION = 16; // public static final int UNUSED = 17; Loading @@ -890,6 +891,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28; static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER = 29; static final int WRITE_USER_PACKAGE_RESTRICTIONS = 30; static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000; private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500; private static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS = 1000; Loading Loading @@ -1397,28 +1400,33 @@ public class PackageManagerService implements PackageSender, TestUtilityService mDirtyUsers.add(userId); } } if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); if (!mBackgroundHandler.hasMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS)) { mBackgroundHandler.sendMessageDelayed( mBackgroundHandler.obtainMessage(WRITE_DIRTY_PACKAGE_RESTRICTIONS, this), WRITE_SETTINGS_DELAY); } } void writePendingRestrictions() { final Integer[] dirtyUsers; synchronized (mLock) { mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS); synchronized (mDirtyUsers) { for (int userId : mDirtyUsers) { mSettings.writePackageRestrictionsLPr(userId); if (mDirtyUsers.isEmpty()) { return; } dirtyUsers = mDirtyUsers.toArray(Integer[]::new); mDirtyUsers.clear(); } } mSettings.writePackageRestrictions(dirtyUsers); } void writeSettings() { void writeSettings(boolean sync) { synchronized (mLock) { mHandler.removeMessages(WRITE_SETTINGS); mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); writeSettingsLPrTEMP(); mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS); writeSettingsLPrTEMP(sync); synchronized (mDirtyUsers) { mDirtyUsers.clear(); } Loading @@ -1432,6 +1440,25 @@ public class PackageManagerService implements PackageSender, TestUtilityService } } private static final Handler.Callback BACKGROUND_HANDLER_CALLBACK = new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { switch (msg.what) { case WRITE_DIRTY_PACKAGE_RESTRICTIONS: { PackageManagerService pm = (PackageManagerService) msg.obj; pm.writePendingRestrictions(); return true; } case WRITE_USER_PACKAGE_RESTRICTIONS: { final Runnable r = (Runnable) msg.obj; r.run(); return true; } } return false; } }; public static Pair<PackageManagerService, IPackageManager> main(Context context, Installer installer, @NonNull DomainVerificationService domainVerificationService, boolean factoryTest) { Loading @@ -1446,7 +1473,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService HandlerThread backgroundThread = new ServiceThread("PackageManagerBg", Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); backgroundThread.start(); Handler backgroundHandler = new Handler(backgroundThread.getLooper()); Handler backgroundHandler = new Handler(backgroundThread.getLooper(), BACKGROUND_HANDLER_CALLBACK); PackageManagerServiceInjector injector = new PackageManagerServiceInjector( context, lock, installer, installLock, new PackageAbiHelperImpl(), Loading @@ -1460,7 +1488,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService (i, pm) -> new Settings(Environment.getDataDirectory(), RuntimePermissionsPersistence.createInstance(), i.getPermissionManagerServiceInternal(), domainVerificationService, backgroundHandler, lock), domainVerificationService, backgroundHandler, lock), (i, pm) -> AppsFilterImpl.create(i, i.getLocalService(PackageManagerInternal.class)), (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"), Loading Loading @@ -1638,6 +1667,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager); mDomainVerificationManager = injector.getDomainVerificationManagerInternal(); mHandler = injector.getHandler(); mBackgroundHandler = injector.getBackgroundHandler(); mSharedLibraries = injector.getSharedLibrariesImpl(); mApexManager = testParams.apexManager; Loading Loading @@ -1828,6 +1858,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper()); mViewCompiler = injector.getViewCompiler(); mSharedLibraries = mInjector.getSharedLibrariesImpl(); mBackgroundHandler = injector.getBackgroundHandler(); mContext.getSystemService(DisplayManager.class) .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics); Loading Loading @@ -2902,9 +2933,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService mPackageUsage.writeNow(mSettings.getPackagesLocked()); if (mHandler.hasMessages(WRITE_SETTINGS) || mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS) || mBackgroundHandler.hasMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS) || mHandler.hasMessages(WRITE_PACKAGE_LIST)) { writeSettings(); writeSettings(/*sync=*/true); } } } Loading Loading @@ -3968,7 +3999,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService synchronized (mDirtyUsers) { mDirtyUsers.remove(userId); if (mDirtyUsers.isEmpty()) { mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS); } } } Loading Loading @@ -6867,9 +6898,14 @@ public class PackageManagerService implements PackageSender, TestUtilityService * TODO: In the meantime, can this be moved to a schedule call? * TODO(b/182523293): This should be removed once we finish migration of permission storage. */ void writeSettingsLPrTEMP() { void writeSettingsLPrTEMP(boolean sync) { mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions); mSettings.writeLPr(mLiveComputer); mSettings.writeLPr(mLiveComputer, sync); } // Default async version. void writeSettingsLPrTEMP() { writeSettingsLPrTEMP(/*sync=*/false); } @Override Loading services/core/java/com/android/server/pm/Settings.java +316 −209 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static android.os.Process.PACKAGE_INFO_GID; import static android.os.Process.SYSTEM_UID; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.WRITE_USER_PACKAGE_RESTRICTIONS; import static com.android.server.pm.SharedUidMigration.BEST_EFFORT; import android.annotation.NonNull; Loading Loading @@ -56,7 +57,6 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.CreateAppDataArgs; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; import android.os.Message; Loading Loading @@ -376,6 +376,13 @@ public final class Settings implements Watchable, Snappable { /** The top level directory in configfs for sdcardfs to push the package->uid,userId mappings */ private final File mKernelMappingFilename; // Lock for user package restrictions operations. private final Object mPackageRestrictionsLock = new Object(); // Pending write operations. @GuardedBy("mPackageRestrictionsLock") private final SparseIntArray mPendingAsyncPackageRestrictionsWrites = new SparseIntArray(); /** Map from package name to settings */ @Watched @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Loading Loading @@ -1476,31 +1483,46 @@ public final class Settings implements Watchable, Snappable { return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.removeReturnOld(userId); } private File getUserPackagesStateFile(int userId) { // TODO: Implement a cleaner solution when adding tests. private File getUserSystemDirectory(int userId) { // This instead of Environment.getUserSystemDirectory(userId) to support testing. File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId)); return new File(userDir, "package-restrictions.xml"); return new File(new File(mSystemDir, "users"), Integer.toString(userId)); } private File getUserRuntimePermissionsFile(int userId) { // TODO: Implement a cleaner solution when adding tests. // This instead of Environment.getUserSystemDirectory(userId) to support testing. File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId)); return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME); // The method itself does not have to be guarded, but the file does. @GuardedBy("mPackageRestrictionsLock") private File getUserPackagesStateFile(int userId) { return new File(getUserSystemDirectory(userId), "package-restrictions.xml"); } // The method itself does not have to be guarded, but the file does. @GuardedBy("mPackageRestrictionsLock") private File getUserPackagesStateBackupFile(int userId) { return new File(Environment.getUserSystemDirectory(userId), "package-restrictions-backup.xml"); return new File(getUserSystemDirectory(userId), "package-restrictions-backup.xml"); } private File getUserRuntimePermissionsFile(int userId) { return new File(getUserSystemDirectory(userId), RUNTIME_PERMISSIONS_FILE_NAME); } // Default version is writing restrictions asynchronously. void writeAllUsersPackageRestrictionsLPr() { writeAllUsersPackageRestrictionsLPr(/*sync=*/false); } void writeAllUsersPackageRestrictionsLPr(boolean sync) { List<UserInfo> users = getAllUsers(UserManagerService.getInstance()); if (users == null) return; if (sync) { // Cancel all pending per-user writes. synchronized (mPackageRestrictionsLock) { mPendingAsyncPackageRestrictionsWrites.clear(); } mHandler.removeMessages(WRITE_USER_PACKAGE_RESTRICTIONS); } for (UserInfo user : users) { writePackageRestrictionsLPr(user.id); writePackageRestrictionsLPr(user.id, sync); } } Loading Loading @@ -1691,6 +1713,8 @@ public final class Settings implements Watchable, Snappable { Log.i(TAG, "Reading package restrictions for user=" + userId); } FileInputStream str = null; synchronized (mPackageRestrictionsLock) { File userPackagesStateFile = getUserPackagesStateFile(userId); File backupFile = getUserPackagesStateBackupFile(userId); if (backupFile.exists()) { Loading @@ -1712,9 +1736,20 @@ public final class Settings implements Watchable, Snappable { } } if (str == null && userPackagesStateFile.exists()) { try { str = new FileInputStream(userPackagesStateFile); if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile); } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); Slog.wtf(TAG, "Error reading package manager stopped packages", e); } } } if (str == null) { if (!userPackagesStateFile.exists()) { mReadMessages.append("No stopped packages file found\n"); PackageManagerService.reportSettingsProblem(Log.INFO, "No stopped packages file; " Loading Loading @@ -1745,9 +1780,8 @@ public final class Settings implements Watchable, Snappable { } return; } str = new FileInputStream(userPackagesStateFile); if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile); } try { final TypedXmlPullParser parser = Xml.resolvePullParser(str); int type; Loading Loading @@ -2070,18 +2104,62 @@ public final class Settings implements Watchable, Snappable { } } // Default version is writing restrictions asynchronously. void writePackageRestrictionsLPr(int userId) { writePackageRestrictionsLPr(userId, /*sync=*/false); } void writePackageRestrictionsLPr(int userId, boolean sync) { invalidatePackageCache(); final long startTime = SystemClock.uptimeMillis(); if (sync) { writePackageRestrictions(userId, startTime, sync); } else { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); Log.i(TAG, "Scheduling deferred IO sync for user=" + userId); } synchronized (mPackageRestrictionsLock) { int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) + 1; mPendingAsyncPackageRestrictionsWrites.put(userId, pending); } Runnable r = () -> writePackageRestrictions(userId, startTime, sync); mHandler.obtainMessage(WRITE_USER_PACKAGE_RESTRICTIONS, r).sendToTarget(); } } void writePackageRestrictions(Integer[] userIds) { invalidatePackageCache(); final long startTime = SystemClock.uptimeMillis(); for (int userId : userIds) { writePackageRestrictions(userId, startTime, /*sync=*/true); } } void writePackageRestrictions(int userId, long startTime, boolean sync) { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); } final File userPackagesStateFile; final File backupFile; final FileOutputStream fstr; synchronized (mPackageRestrictionsLock) { if (!sync) { int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) - 1; if (pending < 0) { Log.i(TAG, "Cancel writing package restrictions for user=" + userId); return; } mPendingAsyncPackageRestrictionsWrites.put(userId, pending); } // Keep the old stopped packages around until we know the new ones have // been successfully written. File userPackagesStateFile = getUserPackagesStateFile(userId); File backupFile = getUserPackagesStateBackupFile(userId); userPackagesStateFile = getUserPackagesStateFile(userId); backupFile = getUserPackagesStateBackupFile(userId); new File(userPackagesStateFile.getParent()).mkdirs(); if (userPackagesStateFile.exists()) { // Presence of backup settings file indicates that we failed Loading @@ -2102,10 +2180,26 @@ public final class Settings implements Watchable, Snappable { } try { final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile); fstr = new FileOutputStream(userPackagesStateFile); // File is created, set permissions. FileUtils.setPermissions(userPackagesStateFile.toString(), FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); } catch (java.io.IOException e) { Slog.wtf(PackageManagerService.TAG, "Unable to write package manager user packages state, " + " current changes will be lost at reboot", e); return; } } try { synchronized (mLock) { final TypedXmlSerializer serializer = Xml.resolveSerializer(fstr); serializer.startDocument(null, true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS); Loading Loading @@ -2224,18 +2318,26 @@ public final class Settings implements Watchable, Snappable { serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); serializer.endDocument(); } fstr.flush(); FileUtils.sync(fstr); fstr.close(); IoUtils.closeQuietly(fstr); // New settings successfully written, old ones are no longer // needed. backupFile.delete(); synchronized (mPackageRestrictionsLock) { // File is created, set permissions. FileUtils.setPermissions(userPackagesStateFile.toString(), FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); // New settings successfully written, old ones are no longer needed. backupFile.delete(); } if (DEBUG_MU) { Log.i(TAG, "New settings successfully written for user=" + userId + ": " + userPackagesStateFile); } com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( "package-user-" + userId, SystemClock.uptimeMillis() - startTime); Loading Loading @@ -2453,7 +2555,7 @@ public final class Settings implements Watchable, Snappable { } } void writeLPr(@NonNull Computer computer) { void writeLPr(@NonNull Computer computer, boolean sync) { //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024); final long startTime = SystemClock.uptimeMillis(); Loading Loading @@ -2578,7 +2680,7 @@ public final class Settings implements Watchable, Snappable { writeKernelMappingLPr(); writePackageListLPr(); writeAllUsersPackageRestrictionsLPr(); writeAllUsersPackageRestrictionsLPr(sync); writeAllRuntimePermissionsLPr(); com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( "package", SystemClock.uptimeMillis() - startTime); Loading Loading @@ -3213,7 +3315,7 @@ public final class Settings implements Watchable, Snappable { mBackupStoppedPackagesFilename.delete(); mStoppedPackagesFilename.delete(); // Migrate to new file format writePackageRestrictionsLPr(UserHandle.USER_SYSTEM); writePackageRestrictionsLPr(UserHandle.USER_SYSTEM, /*sync=*/true); } else { for (UserInfo user : users) { readPackageRestrictionsLPr(user.id, originalFirstInstallTimes); Loading Loading @@ -4284,10 +4386,15 @@ public final class Settings implements Watchable, Snappable { entry.getValue().removeUser(userId); } mPreferredActivities.remove(userId); synchronized (mPackageRestrictionsLock) { File file = getUserPackagesStateFile(userId); file.delete(); file = getUserPackagesStateBackupFile(userId); file.delete(); mPendingAsyncPackageRestrictionsWrites.delete(userId); } removeCrossProfileIntentFiltersLPw(userId); mRuntimePermissionsPersistence.onUserRemoved(userId); Loading Loading @@ -4332,7 +4439,7 @@ public final class Settings implements Watchable, Snappable { if (mVerifierDeviceIdentity == null) { mVerifierDeviceIdentity = VerifierDeviceIdentity.generate(); writeLPr(computer); writeLPr(computer, /*sync=*/false); } return mVerifierDeviceIdentity; Loading services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +221 −25 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/pm/PackageHandler.java +1 −5 Original line number Diff line number Diff line Loading @@ -36,7 +36,6 @@ import static com.android.server.pm.PackageManagerService.PRUNE_UNUSED_STATIC_SH import static com.android.server.pm.PackageManagerService.SEND_PENDING_BROADCAST; import static com.android.server.pm.PackageManagerService.TAG; import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_LIST; import static com.android.server.pm.PackageManagerService.WRITE_PACKAGE_RESTRICTIONS; import static com.android.server.pm.PackageManagerService.WRITE_SETTINGS; import android.content.Intent; Loading Loading @@ -119,10 +118,7 @@ final class PackageHandler extends Handler { } } break; case WRITE_SETTINGS: { mPm.writeSettings(); } break; case WRITE_PACKAGE_RESTRICTIONS: { mPm.writePendingRestrictions(); mPm.writeSettings(/*sync=*/false); } break; case WRITE_PACKAGE_LIST: { mPm.writePackageList(msg.arg1); Loading
services/core/java/com/android/server/pm/PackageManagerService.java +52 −16 Original line number Diff line number Diff line Loading @@ -558,6 +558,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final char RANDOM_CODEPATH_PREFIX = '-'; final Handler mHandler; final Handler mBackgroundHandler; final ProcessLoggingHandler mProcessLoggingHandler; Loading Loading @@ -873,7 +874,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService // public static final int UNUSED = 5; static final int POST_INSTALL = 9; static final int WRITE_SETTINGS = 13; static final int WRITE_PACKAGE_RESTRICTIONS = 14; static final int WRITE_DIRTY_PACKAGE_RESTRICTIONS = 14; static final int PACKAGE_VERIFIED = 15; static final int CHECK_PENDING_VERIFICATION = 16; // public static final int UNUSED = 17; Loading @@ -890,6 +891,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28; static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER = 29; static final int WRITE_USER_PACKAGE_RESTRICTIONS = 30; static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000; private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500; private static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS = 1000; Loading Loading @@ -1397,28 +1400,33 @@ public class PackageManagerService implements PackageSender, TestUtilityService mDirtyUsers.add(userId); } } if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) { mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY); if (!mBackgroundHandler.hasMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS)) { mBackgroundHandler.sendMessageDelayed( mBackgroundHandler.obtainMessage(WRITE_DIRTY_PACKAGE_RESTRICTIONS, this), WRITE_SETTINGS_DELAY); } } void writePendingRestrictions() { final Integer[] dirtyUsers; synchronized (mLock) { mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS); synchronized (mDirtyUsers) { for (int userId : mDirtyUsers) { mSettings.writePackageRestrictionsLPr(userId); if (mDirtyUsers.isEmpty()) { return; } dirtyUsers = mDirtyUsers.toArray(Integer[]::new); mDirtyUsers.clear(); } } mSettings.writePackageRestrictions(dirtyUsers); } void writeSettings() { void writeSettings(boolean sync) { synchronized (mLock) { mHandler.removeMessages(WRITE_SETTINGS); mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); writeSettingsLPrTEMP(); mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS); writeSettingsLPrTEMP(sync); synchronized (mDirtyUsers) { mDirtyUsers.clear(); } Loading @@ -1432,6 +1440,25 @@ public class PackageManagerService implements PackageSender, TestUtilityService } } private static final Handler.Callback BACKGROUND_HANDLER_CALLBACK = new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { switch (msg.what) { case WRITE_DIRTY_PACKAGE_RESTRICTIONS: { PackageManagerService pm = (PackageManagerService) msg.obj; pm.writePendingRestrictions(); return true; } case WRITE_USER_PACKAGE_RESTRICTIONS: { final Runnable r = (Runnable) msg.obj; r.run(); return true; } } return false; } }; public static Pair<PackageManagerService, IPackageManager> main(Context context, Installer installer, @NonNull DomainVerificationService domainVerificationService, boolean factoryTest) { Loading @@ -1446,7 +1473,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService HandlerThread backgroundThread = new ServiceThread("PackageManagerBg", Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); backgroundThread.start(); Handler backgroundHandler = new Handler(backgroundThread.getLooper()); Handler backgroundHandler = new Handler(backgroundThread.getLooper(), BACKGROUND_HANDLER_CALLBACK); PackageManagerServiceInjector injector = new PackageManagerServiceInjector( context, lock, installer, installLock, new PackageAbiHelperImpl(), Loading @@ -1460,7 +1488,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService (i, pm) -> new Settings(Environment.getDataDirectory(), RuntimePermissionsPersistence.createInstance(), i.getPermissionManagerServiceInternal(), domainVerificationService, backgroundHandler, lock), domainVerificationService, backgroundHandler, lock), (i, pm) -> AppsFilterImpl.create(i, i.getLocalService(PackageManagerInternal.class)), (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"), Loading Loading @@ -1638,6 +1667,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager); mDomainVerificationManager = injector.getDomainVerificationManagerInternal(); mHandler = injector.getHandler(); mBackgroundHandler = injector.getBackgroundHandler(); mSharedLibraries = injector.getSharedLibrariesImpl(); mApexManager = testParams.apexManager; Loading Loading @@ -1828,6 +1858,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper()); mViewCompiler = injector.getViewCompiler(); mSharedLibraries = mInjector.getSharedLibrariesImpl(); mBackgroundHandler = injector.getBackgroundHandler(); mContext.getSystemService(DisplayManager.class) .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics); Loading Loading @@ -2902,9 +2933,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService mPackageUsage.writeNow(mSettings.getPackagesLocked()); if (mHandler.hasMessages(WRITE_SETTINGS) || mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS) || mBackgroundHandler.hasMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS) || mHandler.hasMessages(WRITE_PACKAGE_LIST)) { writeSettings(); writeSettings(/*sync=*/true); } } } Loading Loading @@ -3968,7 +3999,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService synchronized (mDirtyUsers) { mDirtyUsers.remove(userId); if (mDirtyUsers.isEmpty()) { mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS); mBackgroundHandler.removeMessages(WRITE_DIRTY_PACKAGE_RESTRICTIONS); } } } Loading Loading @@ -6867,9 +6898,14 @@ public class PackageManagerService implements PackageSender, TestUtilityService * TODO: In the meantime, can this be moved to a schedule call? * TODO(b/182523293): This should be removed once we finish migration of permission storage. */ void writeSettingsLPrTEMP() { void writeSettingsLPrTEMP(boolean sync) { mPermissionManager.writeLegacyPermissionsTEMP(mSettings.mPermissions); mSettings.writeLPr(mLiveComputer); mSettings.writeLPr(mLiveComputer, sync); } // Default async version. void writeSettingsLPrTEMP() { writeSettingsLPrTEMP(/*sync=*/false); } @Override Loading
services/core/java/com/android/server/pm/Settings.java +316 −209 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static android.os.Process.PACKAGE_INFO_GID; import static android.os.Process.SYSTEM_UID; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.pm.PackageManagerService.WRITE_USER_PACKAGE_RESTRICTIONS; import static com.android.server.pm.SharedUidMigration.BEST_EFFORT; import android.annotation.NonNull; Loading Loading @@ -56,7 +57,6 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.CreateAppDataArgs; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; import android.os.Message; Loading Loading @@ -376,6 +376,13 @@ public final class Settings implements Watchable, Snappable { /** The top level directory in configfs for sdcardfs to push the package->uid,userId mappings */ private final File mKernelMappingFilename; // Lock for user package restrictions operations. private final Object mPackageRestrictionsLock = new Object(); // Pending write operations. @GuardedBy("mPackageRestrictionsLock") private final SparseIntArray mPendingAsyncPackageRestrictionsWrites = new SparseIntArray(); /** Map from package name to settings */ @Watched @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) Loading Loading @@ -1476,31 +1483,46 @@ public final class Settings implements Watchable, Snappable { return (userId == UserHandle.USER_ALL) ? null : mDefaultBrowserApp.removeReturnOld(userId); } private File getUserPackagesStateFile(int userId) { // TODO: Implement a cleaner solution when adding tests. private File getUserSystemDirectory(int userId) { // This instead of Environment.getUserSystemDirectory(userId) to support testing. File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId)); return new File(userDir, "package-restrictions.xml"); return new File(new File(mSystemDir, "users"), Integer.toString(userId)); } private File getUserRuntimePermissionsFile(int userId) { // TODO: Implement a cleaner solution when adding tests. // This instead of Environment.getUserSystemDirectory(userId) to support testing. File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId)); return new File(userDir, RUNTIME_PERMISSIONS_FILE_NAME); // The method itself does not have to be guarded, but the file does. @GuardedBy("mPackageRestrictionsLock") private File getUserPackagesStateFile(int userId) { return new File(getUserSystemDirectory(userId), "package-restrictions.xml"); } // The method itself does not have to be guarded, but the file does. @GuardedBy("mPackageRestrictionsLock") private File getUserPackagesStateBackupFile(int userId) { return new File(Environment.getUserSystemDirectory(userId), "package-restrictions-backup.xml"); return new File(getUserSystemDirectory(userId), "package-restrictions-backup.xml"); } private File getUserRuntimePermissionsFile(int userId) { return new File(getUserSystemDirectory(userId), RUNTIME_PERMISSIONS_FILE_NAME); } // Default version is writing restrictions asynchronously. void writeAllUsersPackageRestrictionsLPr() { writeAllUsersPackageRestrictionsLPr(/*sync=*/false); } void writeAllUsersPackageRestrictionsLPr(boolean sync) { List<UserInfo> users = getAllUsers(UserManagerService.getInstance()); if (users == null) return; if (sync) { // Cancel all pending per-user writes. synchronized (mPackageRestrictionsLock) { mPendingAsyncPackageRestrictionsWrites.clear(); } mHandler.removeMessages(WRITE_USER_PACKAGE_RESTRICTIONS); } for (UserInfo user : users) { writePackageRestrictionsLPr(user.id); writePackageRestrictionsLPr(user.id, sync); } } Loading Loading @@ -1691,6 +1713,8 @@ public final class Settings implements Watchable, Snappable { Log.i(TAG, "Reading package restrictions for user=" + userId); } FileInputStream str = null; synchronized (mPackageRestrictionsLock) { File userPackagesStateFile = getUserPackagesStateFile(userId); File backupFile = getUserPackagesStateBackupFile(userId); if (backupFile.exists()) { Loading @@ -1712,9 +1736,20 @@ public final class Settings implements Watchable, Snappable { } } if (str == null && userPackagesStateFile.exists()) { try { str = new FileInputStream(userPackagesStateFile); if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile); } catch (java.io.IOException e) { mReadMessages.append("Error reading: " + e.toString()); PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e); Slog.wtf(TAG, "Error reading package manager stopped packages", e); } } } if (str == null) { if (!userPackagesStateFile.exists()) { mReadMessages.append("No stopped packages file found\n"); PackageManagerService.reportSettingsProblem(Log.INFO, "No stopped packages file; " Loading Loading @@ -1745,9 +1780,8 @@ public final class Settings implements Watchable, Snappable { } return; } str = new FileInputStream(userPackagesStateFile); if (DEBUG_MU) Log.i(TAG, "Reading " + userPackagesStateFile); } try { final TypedXmlPullParser parser = Xml.resolvePullParser(str); int type; Loading Loading @@ -2070,18 +2104,62 @@ public final class Settings implements Watchable, Snappable { } } // Default version is writing restrictions asynchronously. void writePackageRestrictionsLPr(int userId) { writePackageRestrictionsLPr(userId, /*sync=*/false); } void writePackageRestrictionsLPr(int userId, boolean sync) { invalidatePackageCache(); final long startTime = SystemClock.uptimeMillis(); if (sync) { writePackageRestrictions(userId, startTime, sync); } else { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); Log.i(TAG, "Scheduling deferred IO sync for user=" + userId); } synchronized (mPackageRestrictionsLock) { int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) + 1; mPendingAsyncPackageRestrictionsWrites.put(userId, pending); } Runnable r = () -> writePackageRestrictions(userId, startTime, sync); mHandler.obtainMessage(WRITE_USER_PACKAGE_RESTRICTIONS, r).sendToTarget(); } } void writePackageRestrictions(Integer[] userIds) { invalidatePackageCache(); final long startTime = SystemClock.uptimeMillis(); for (int userId : userIds) { writePackageRestrictions(userId, startTime, /*sync=*/true); } } void writePackageRestrictions(int userId, long startTime, boolean sync) { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); } final File userPackagesStateFile; final File backupFile; final FileOutputStream fstr; synchronized (mPackageRestrictionsLock) { if (!sync) { int pending = mPendingAsyncPackageRestrictionsWrites.get(userId, 0) - 1; if (pending < 0) { Log.i(TAG, "Cancel writing package restrictions for user=" + userId); return; } mPendingAsyncPackageRestrictionsWrites.put(userId, pending); } // Keep the old stopped packages around until we know the new ones have // been successfully written. File userPackagesStateFile = getUserPackagesStateFile(userId); File backupFile = getUserPackagesStateBackupFile(userId); userPackagesStateFile = getUserPackagesStateFile(userId); backupFile = getUserPackagesStateBackupFile(userId); new File(userPackagesStateFile.getParent()).mkdirs(); if (userPackagesStateFile.exists()) { // Presence of backup settings file indicates that we failed Loading @@ -2102,10 +2180,26 @@ public final class Settings implements Watchable, Snappable { } try { final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile); fstr = new FileOutputStream(userPackagesStateFile); // File is created, set permissions. FileUtils.setPermissions(userPackagesStateFile.toString(), FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); } catch (java.io.IOException e) { Slog.wtf(PackageManagerService.TAG, "Unable to write package manager user packages state, " + " current changes will be lost at reboot", e); return; } } try { synchronized (mLock) { final TypedXmlSerializer serializer = Xml.resolveSerializer(fstr); serializer.startDocument(null, true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS); Loading Loading @@ -2224,18 +2318,26 @@ public final class Settings implements Watchable, Snappable { serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); serializer.endDocument(); } fstr.flush(); FileUtils.sync(fstr); fstr.close(); IoUtils.closeQuietly(fstr); // New settings successfully written, old ones are no longer // needed. backupFile.delete(); synchronized (mPackageRestrictionsLock) { // File is created, set permissions. FileUtils.setPermissions(userPackagesStateFile.toString(), FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP, -1, -1); // New settings successfully written, old ones are no longer needed. backupFile.delete(); } if (DEBUG_MU) { Log.i(TAG, "New settings successfully written for user=" + userId + ": " + userPackagesStateFile); } com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( "package-user-" + userId, SystemClock.uptimeMillis() - startTime); Loading Loading @@ -2453,7 +2555,7 @@ public final class Settings implements Watchable, Snappable { } } void writeLPr(@NonNull Computer computer) { void writeLPr(@NonNull Computer computer, boolean sync) { //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024); final long startTime = SystemClock.uptimeMillis(); Loading Loading @@ -2578,7 +2680,7 @@ public final class Settings implements Watchable, Snappable { writeKernelMappingLPr(); writePackageListLPr(); writeAllUsersPackageRestrictionsLPr(); writeAllUsersPackageRestrictionsLPr(sync); writeAllRuntimePermissionsLPr(); com.android.internal.logging.EventLogTags.writeCommitSysConfigFile( "package", SystemClock.uptimeMillis() - startTime); Loading Loading @@ -3213,7 +3315,7 @@ public final class Settings implements Watchable, Snappable { mBackupStoppedPackagesFilename.delete(); mStoppedPackagesFilename.delete(); // Migrate to new file format writePackageRestrictionsLPr(UserHandle.USER_SYSTEM); writePackageRestrictionsLPr(UserHandle.USER_SYSTEM, /*sync=*/true); } else { for (UserInfo user : users) { readPackageRestrictionsLPr(user.id, originalFirstInstallTimes); Loading Loading @@ -4284,10 +4386,15 @@ public final class Settings implements Watchable, Snappable { entry.getValue().removeUser(userId); } mPreferredActivities.remove(userId); synchronized (mPackageRestrictionsLock) { File file = getUserPackagesStateFile(userId); file.delete(); file = getUserPackagesStateBackupFile(userId); file.delete(); mPendingAsyncPackageRestrictionsWrites.delete(userId); } removeCrossProfileIntentFiltersLPw(userId); mRuntimePermissionsPersistence.onUserRemoved(userId); Loading Loading @@ -4332,7 +4439,7 @@ public final class Settings implements Watchable, Snappable { if (mVerifierDeviceIdentity == null) { mVerifierDeviceIdentity = VerifierDeviceIdentity.generate(); writeLPr(computer); writeLPr(computer, /*sync=*/false); } return mVerifierDeviceIdentity; Loading
services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +221 −25 File changed.Preview size limit exceeded, changes collapsed. Show changes