Loading services/core/java/com/android/server/pm/Settings.java +38 −8 Original line number Diff line number Diff line Loading @@ -164,6 +164,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.function.Consumer; Loading Loading @@ -633,8 +634,8 @@ public final class Settings implements Watchable, Snappable { runtimePermissionsPersistence, new Consumer<Integer>() { @Override public void accept(Integer userId) { mRuntimePermissionsPersistence.writeStateForUser(userId, mPermissionDataProvider, mPackages, mSharedUsers, mHandler, mLock); mRuntimePermissionsPersistence.writeStateForUser(userId, mPermissionDataProvider, mPackages, mSharedUsers, mHandler, mLock, /*sync=*/false); } }); mPermissionDataProvider = permissionDataProvider; Loading Loading @@ -5292,7 +5293,7 @@ public final class Settings implements Watchable, Snappable { public void writePermissionStateForUserLPr(int userId, boolean sync) { if (sync) { mRuntimePermissionsPersistence.writeStateForUser(userId, mPermissionDataProvider, mPackages, mSharedUsers, /*handler=*/null, mLock); mPackages, mSharedUsers, /*handler=*/null, mLock, /*sync=*/true); } else { mRuntimePermissionsPersistence.writeStateForUserAsync(userId); } Loading Loading @@ -5370,12 +5371,17 @@ public final class Settings implements Watchable, Snappable { } private static final class RuntimePermissionPersistence { private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200; // 200-400ms delay to avoid monopolizing PMS lock when written for multiple users. private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 300; private static final double WRITE_PERMISSIONS_DELAY_JITTER = 0.3; private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000; private static final int UPGRADE_VERSION = -1; private static final int INITIAL_VERSION = 0; private static final Random sRandom = new Random(); private String mExtendedFingerprint; @GuardedBy("mPersistenceLock") Loading @@ -5396,6 +5402,11 @@ public final class Settings implements Watchable, Snappable { // The mapping keys are user ids. private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray(); @GuardedBy("mLock") // Tracking the mutations that haven't yet been written to legacy state. // This avoids unnecessary work when writing settings for multiple users. private boolean mIsLegacyPermissionStateStale = false; @GuardedBy("mLock") // The mapping keys are user ids. private final SparseIntArray mVersions = new SparseIntArray(); Loading Loading @@ -5472,9 +5483,22 @@ public final class Settings implements Watchable, Snappable { return PackagePartitions.FINGERPRINT + "?pc_version=" + version; } private static long uniformRandom(double low, double high) { double mag = high - low; return (long) (sRandom.nextDouble() * mag + low); } private static long nextWritePermissionDelayMillis() { final long delay = WRITE_PERMISSIONS_DELAY_MILLIS; final double jitter = WRITE_PERMISSIONS_DELAY_JITTER; return delay + uniformRandom(-jitter * delay, jitter * delay); } public void writeStateForUserAsync(int userId) { synchronized (mLock) { mIsLegacyPermissionStateStale = true; final long currentTimeMillis = SystemClock.uptimeMillis(); final long writePermissionDelayMillis = nextWritePermissionDelayMillis(); if (mWriteScheduled.get(userId)) { mAsyncHandler.removeMessages(userId); Loading @@ -5493,7 +5517,7 @@ public final class Settings implements Watchable, Snappable { // Hold off a bit more as settings are frequently changing. final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0); final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS, final long writeDelayMillis = Math.min(writePermissionDelayMillis, maxDelayMillis); Message message = mAsyncHandler.obtainMessage(userId); Loading @@ -5501,7 +5525,7 @@ public final class Settings implements Watchable, Snappable { } else { mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis); Message message = mAsyncHandler.obtainMessage(userId); mAsyncHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS); mAsyncHandler.sendMessageDelayed(message, writePermissionDelayMillis); mWriteScheduled.put(userId, true); } } Loading @@ -5511,21 +5535,27 @@ public final class Settings implements Watchable, Snappable { legacyPermissionDataProvider, @NonNull WatchedArrayMap<String, ? extends PackageStateInternal> packageStates, @NonNull WatchedArrayMap<String, SharedUserSetting> sharedUsers, @Nullable Handler pmHandler, @NonNull Object pmLock) { @Nullable Handler pmHandler, @NonNull Object pmLock, boolean sync) { final int version; final String fingerprint; final boolean isLegacyPermissionStateStale; synchronized (mLock) { mAsyncHandler.removeMessages(userId); mWriteScheduled.delete(userId); version = mVersions.get(userId, INITIAL_VERSION); fingerprint = mFingerprints.get(userId); isLegacyPermissionStateStale = mIsLegacyPermissionStateStale; mIsLegacyPermissionStateStale = false; } Runnable writer = () -> { final RuntimePermissionsState runtimePermissions; synchronized (pmLock) { if (sync || isLegacyPermissionStateStale) { legacyPermissionDataProvider.writeLegacyPermissionStateTEMP(); } Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions = new ArrayMap<>(); Loading Loading
services/core/java/com/android/server/pm/Settings.java +38 −8 Original line number Diff line number Diff line Loading @@ -164,6 +164,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.function.Consumer; Loading Loading @@ -633,8 +634,8 @@ public final class Settings implements Watchable, Snappable { runtimePermissionsPersistence, new Consumer<Integer>() { @Override public void accept(Integer userId) { mRuntimePermissionsPersistence.writeStateForUser(userId, mPermissionDataProvider, mPackages, mSharedUsers, mHandler, mLock); mRuntimePermissionsPersistence.writeStateForUser(userId, mPermissionDataProvider, mPackages, mSharedUsers, mHandler, mLock, /*sync=*/false); } }); mPermissionDataProvider = permissionDataProvider; Loading Loading @@ -5292,7 +5293,7 @@ public final class Settings implements Watchable, Snappable { public void writePermissionStateForUserLPr(int userId, boolean sync) { if (sync) { mRuntimePermissionsPersistence.writeStateForUser(userId, mPermissionDataProvider, mPackages, mSharedUsers, /*handler=*/null, mLock); mPackages, mSharedUsers, /*handler=*/null, mLock, /*sync=*/true); } else { mRuntimePermissionsPersistence.writeStateForUserAsync(userId); } Loading Loading @@ -5370,12 +5371,17 @@ public final class Settings implements Watchable, Snappable { } private static final class RuntimePermissionPersistence { private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 200; // 200-400ms delay to avoid monopolizing PMS lock when written for multiple users. private static final long WRITE_PERMISSIONS_DELAY_MILLIS = 300; private static final double WRITE_PERMISSIONS_DELAY_JITTER = 0.3; private static final long MAX_WRITE_PERMISSIONS_DELAY_MILLIS = 2000; private static final int UPGRADE_VERSION = -1; private static final int INITIAL_VERSION = 0; private static final Random sRandom = new Random(); private String mExtendedFingerprint; @GuardedBy("mPersistenceLock") Loading @@ -5396,6 +5402,11 @@ public final class Settings implements Watchable, Snappable { // The mapping keys are user ids. private final SparseLongArray mLastNotWrittenMutationTimesMillis = new SparseLongArray(); @GuardedBy("mLock") // Tracking the mutations that haven't yet been written to legacy state. // This avoids unnecessary work when writing settings for multiple users. private boolean mIsLegacyPermissionStateStale = false; @GuardedBy("mLock") // The mapping keys are user ids. private final SparseIntArray mVersions = new SparseIntArray(); Loading Loading @@ -5472,9 +5483,22 @@ public final class Settings implements Watchable, Snappable { return PackagePartitions.FINGERPRINT + "?pc_version=" + version; } private static long uniformRandom(double low, double high) { double mag = high - low; return (long) (sRandom.nextDouble() * mag + low); } private static long nextWritePermissionDelayMillis() { final long delay = WRITE_PERMISSIONS_DELAY_MILLIS; final double jitter = WRITE_PERMISSIONS_DELAY_JITTER; return delay + uniformRandom(-jitter * delay, jitter * delay); } public void writeStateForUserAsync(int userId) { synchronized (mLock) { mIsLegacyPermissionStateStale = true; final long currentTimeMillis = SystemClock.uptimeMillis(); final long writePermissionDelayMillis = nextWritePermissionDelayMillis(); if (mWriteScheduled.get(userId)) { mAsyncHandler.removeMessages(userId); Loading @@ -5493,7 +5517,7 @@ public final class Settings implements Watchable, Snappable { // Hold off a bit more as settings are frequently changing. final long maxDelayMillis = Math.max(lastNotWrittenMutationTimeMillis + MAX_WRITE_PERMISSIONS_DELAY_MILLIS - currentTimeMillis, 0); final long writeDelayMillis = Math.min(WRITE_PERMISSIONS_DELAY_MILLIS, final long writeDelayMillis = Math.min(writePermissionDelayMillis, maxDelayMillis); Message message = mAsyncHandler.obtainMessage(userId); Loading @@ -5501,7 +5525,7 @@ public final class Settings implements Watchable, Snappable { } else { mLastNotWrittenMutationTimesMillis.put(userId, currentTimeMillis); Message message = mAsyncHandler.obtainMessage(userId); mAsyncHandler.sendMessageDelayed(message, WRITE_PERMISSIONS_DELAY_MILLIS); mAsyncHandler.sendMessageDelayed(message, writePermissionDelayMillis); mWriteScheduled.put(userId, true); } } Loading @@ -5511,21 +5535,27 @@ public final class Settings implements Watchable, Snappable { legacyPermissionDataProvider, @NonNull WatchedArrayMap<String, ? extends PackageStateInternal> packageStates, @NonNull WatchedArrayMap<String, SharedUserSetting> sharedUsers, @Nullable Handler pmHandler, @NonNull Object pmLock) { @Nullable Handler pmHandler, @NonNull Object pmLock, boolean sync) { final int version; final String fingerprint; final boolean isLegacyPermissionStateStale; synchronized (mLock) { mAsyncHandler.removeMessages(userId); mWriteScheduled.delete(userId); version = mVersions.get(userId, INITIAL_VERSION); fingerprint = mFingerprints.get(userId); isLegacyPermissionStateStale = mIsLegacyPermissionStateStale; mIsLegacyPermissionStateStale = false; } Runnable writer = () -> { final RuntimePermissionsState runtimePermissions; synchronized (pmLock) { if (sync || isLegacyPermissionStateStale) { legacyPermissionDataProvider.writeLegacyPermissionStateTEMP(); } Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions = new ArrayMap<>(); Loading