diff --git a/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java b/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java index a8eeec3c2f240..80030f7a7a47f 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java @@ -50,10 +50,6 @@ final class GenerationRegistry { @GuardedBy("mLock") private final ArrayMap> mKeyToIndexMapMap = new ArrayMap<>(); - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) - // Maximum number of backing stores allowed - static final int NUM_MAX_BACKING_STORE = 8; - @GuardedBy("mLock") private int mNumBackingStore = 0; @@ -65,8 +61,24 @@ final class GenerationRegistry { // The generation number is only increased when a new non-predefined setting is inserted private static final String DEFAULT_MAP_KEY_FOR_UNSET_SETTINGS = ""; - public GenerationRegistry(Object lock) { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) + // Minimum number of backing stores; supports 3 users + static final int MIN_NUM_BACKING_STORE = 8; + // Maximum number of backing stores; supports 18 users + static final int MAX_NUM_BACKING_STORE = 38; + + private final int mMaxNumBackingStore; + + GenerationRegistry(Object lock, int maxNumUsers) { mLock = lock; + // Add some buffer to maxNumUsers to accommodate corner cases when the actual number of + // users in the system exceeds the limit + maxNumUsers = maxNumUsers + 2; + // Number of backing stores needed for N users is (N + N + 1 + 1) = N * 2 + 2 + // N Secure backing stores and N System backing stores, 1 Config and 1 Global for all users + // However, we always make sure that at least 3 users and at most 18 users are supported. + mMaxNumBackingStore = Math.min(Math.max(maxNumUsers * 2 + 2, MIN_NUM_BACKING_STORE), + MAX_NUM_BACKING_STORE); } /** @@ -195,7 +207,7 @@ final class GenerationRegistry { } if (backingStore == null) { try { - if (mNumBackingStore >= NUM_MAX_BACKING_STORE) { + if (mNumBackingStore >= mMaxNumBackingStore) { if (DEBUG) { Slog.e(LOG_TAG, "Error creating backing store - at capacity"); } @@ -275,4 +287,9 @@ final class GenerationRegistry { } return -1; } + + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE) + int getMaxNumBackingStores() { + return mMaxNumBackingStore; + } } \ No newline at end of file diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 7e89bfce7255c..721b3c49b17c5 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -2831,7 +2831,7 @@ public class SettingsProvider extends ContentProvider { public SettingsRegistry() { mHandler = new MyHandler(getContext().getMainLooper()); - mGenerationRegistry = new GenerationRegistry(mLock); + mGenerationRegistry = new GenerationRegistry(mLock, UserManager.getMaxSupportedUsers()); mBackupManager = new BackupManager(getContext()); } diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/GenerationRegistryTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/GenerationRegistryTest.java index 586d6f73baad6..12865f452e22a 100644 --- a/packages/SettingsProvider/test/src/com/android/providers/settings/GenerationRegistryTest.java +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/GenerationRegistryTest.java @@ -36,7 +36,7 @@ import java.io.IOException; public class GenerationRegistryTest { @Test public void testGenerationsWithRegularSetting() throws IOException { - final GenerationRegistry generationRegistry = new GenerationRegistry(new Object()); + final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 2); final int secureKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, 0); final String testSecureSetting = "test_secure_setting"; Bundle b = new Bundle(); @@ -93,7 +93,7 @@ public class GenerationRegistryTest { @Test public void testGenerationsWithConfigSetting() throws IOException { - final GenerationRegistry generationRegistry = new GenerationRegistry(new Object()); + final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 1); final String prefix = "test_namespace/"; final int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0); @@ -110,10 +110,10 @@ public class GenerationRegistryTest { @Test public void testMaxNumBackingStores() throws IOException { - final GenerationRegistry generationRegistry = new GenerationRegistry(new Object()); + final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 2); final String testSecureSetting = "test_secure_setting"; Bundle b = new Bundle(); - for (int i = 0; i < GenerationRegistry.NUM_MAX_BACKING_STORE; i++) { + for (int i = 0; i < generationRegistry.getMaxNumBackingStores(); i++) { b.clear(); final int key = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, i); generationRegistry.addGenerationData(b, key, testSecureSetting); @@ -121,7 +121,7 @@ public class GenerationRegistryTest { } b.clear(); final int key = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, - GenerationRegistry.NUM_MAX_BACKING_STORE + 1); + generationRegistry.getMaxNumBackingStores() + 1); generationRegistry.addGenerationData(b, key, testSecureSetting); // Should fail to add generation because the number of backing stores has reached limit checkBundle(b, -1, -1, true); @@ -133,7 +133,7 @@ public class GenerationRegistryTest { @Test public void testMaxSizeBackingStore() throws IOException { - final GenerationRegistry generationRegistry = new GenerationRegistry(new Object()); + final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 1); final int secureKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, 0); final String testSecureSetting = "test_secure_setting"; Bundle b = new Bundle(); @@ -153,7 +153,7 @@ public class GenerationRegistryTest { @Test public void testUnsetSettings() throws IOException { - final GenerationRegistry generationRegistry = new GenerationRegistry(new Object()); + final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 1); final int secureKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, 0); final String testSecureSetting = "test_secure_setting"; Bundle b = new Bundle(); @@ -172,7 +172,7 @@ public class GenerationRegistryTest { @Test public void testGlobalSettings() throws IOException { - final GenerationRegistry generationRegistry = new GenerationRegistry(new Object()); + final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 2); final int globalKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_GLOBAL, 0); final String testGlobalSetting = "test_global_setting"; final Bundle b = new Bundle(); @@ -188,6 +188,18 @@ public class GenerationRegistryTest { assertThat(array).isEqualTo(array2); } + @Test + public void testNumberOfBackingStores() { + GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 0); + // Test that the capacity of the backing stores is always valid + assertThat(generationRegistry.getMaxNumBackingStores()).isEqualTo( + GenerationRegistry.MIN_NUM_BACKING_STORE); + generationRegistry = new GenerationRegistry(new Object(), 100); + // Test that the capacity of the backing stores is always valid + assertThat(generationRegistry.getMaxNumBackingStores()).isEqualTo( + GenerationRegistry.MAX_NUM_BACKING_STORE); + } + private void checkBundle(Bundle b, int expectedIndex, int expectedGeneration, boolean isNull) throws IOException { final MemoryIntArray array = getArray(b);