Loading core/java/android/app/PropertyInvalidatedCache.java +12 −8 Original line number Diff line number Diff line Loading @@ -2321,12 +2321,14 @@ public class PropertyInvalidatedCache<Query, Result> { @GuardedBy("mLock") private int mBlockHash = 0; // The number of nonces that the native layer can hold. This is maintained for debug and // logging. private final int mMaxNonce; // The number of nonces that the native layer can hold. This is maintained for debug, // logging, and testing. @VisibleForTesting public final int mMaxNonce; // The size of the native byte block. private final int mMaxByte; @VisibleForTesting public final int mMaxByte; /** @hide */ @VisibleForTesting Loading Loading @@ -2483,18 +2485,20 @@ public class PropertyInvalidatedCache<Query, Result> { } } static final AtomicLong sStoreCount = new AtomicLong(); // Add a string to the local copy of the block and write the block to shared memory. // Return the index of the new string. If the string has already been recorded, the // shared memory is not updated but the index of the existing string is returned. // shared memory is not updated but the index of the existing string is returned. Only // mMaxNonce strings can be stored; if mMaxNonce strings have already been allocated, // the method throws. public int storeName(@NonNull String str) { synchronized (mLock) { Integer handle = mStringHandle.get(str); if (handle == null) { throwIfImmutable(); throwIfBadString(str); if (mHighestIndex + 1 >= mMaxNonce) { throw new RuntimeException("nonce limit exceeded"); } byte[] block = new byte[mMaxByte]; nativeGetByteBlock(mPtr, 0, block); appendStringToMapLocked(str, block); Loading core/jni/android_app_PropertyInvalidatedCache.h +7 −5 Original line number Diff line number Diff line Loading @@ -147,10 +147,12 @@ template<int maxNonce, size_t maxByte> class CacheNonce : public NonceStore { } }; // The CacheNonce for system server holds 64 nonces with a string block of 8192 bytes. This is // more than enough for system_server PropertyInvalidatedCache support. The configuration // values are not defined as visible constants. Clients should use the accessors on the // SystemCacheNonce instance if they need the sizing parameters. typedef CacheNonce</* max nonce */ 64, /* byte block size */ 8192> SystemCacheNonce; // The CacheNonce for system server. The configuration values are not defined as visible // constants. Clients should use the accessors on the SystemCacheNonce instance if they need // the sizing parameters. // LINT.IfChange(system_nonce_config) typedef CacheNonce</* max nonce */ 128, /* byte block size */ 8192> SystemCacheNonce; // LINT.ThenChange(/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java:system_nonce_config) } // namespace android.app.PropertyInvalidatedCache core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java +47 −4 Original line number Diff line number Diff line Loading @@ -37,8 +37,10 @@ import android.app.PropertyInvalidatedCache.Args; import android.app.PropertyInvalidatedCache.NonceWatcher; import android.app.PropertyInvalidatedCache.NonceStore; import android.os.Binder; import android.util.Log; import com.android.internal.os.ApplicationSharedMemory; import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; Loading Loading @@ -410,8 +412,7 @@ public class PropertyInvalidatedCacheTests { // Verify that invalidating the cache from an app process would fail due to lack of permissions. @Test @android.platform.test.annotations.DisabledOnRavenwood( reason = "SystemProperties doesn't have permission check") @DisabledOnRavenwood(reason = "SystemProperties doesn't have permission check") public void testPermissionFailure() { // Create a cache that will write a system nonce. TestCache sysCache = new TestCache(MODULE_SYSTEM, "mode1"); Loading Loading @@ -556,8 +557,7 @@ public class PropertyInvalidatedCacheTests { // storing nonces in shared memory. @RequiresFlagsEnabled(FLAG_APPLICATION_SHARED_MEMORY_ENABLED) @Test @android.platform.test.annotations.DisabledOnRavenwood( reason = "PIC doesn't use SharedMemory on Ravenwood") @DisabledOnRavenwood(reason = "PIC doesn't use SharedMemory on Ravenwood") public void testSharedMemoryStorage() { // Fetch a shared memory instance for testing. ApplicationSharedMemory shmem = ApplicationSharedMemory.create(); Loading Loading @@ -602,6 +602,49 @@ public class PropertyInvalidatedCacheTests { shmem.close(); } // Verify that the configured number of nonce slots is actually available. This test // hard-codes the configured number of slots, which means that this test must be changed // whenever the shared memory configuration changes. @RequiresFlagsEnabled(FLAG_APPLICATION_SHARED_MEMORY_ENABLED) @Test @DisabledOnRavenwood(reason = "PIC doesn't use SharedMemory on Ravenwood") public void testSharedMemoryNonceConfig() { // The two configured constants. These are private to this method since they are only // used here. // LINT.IfChange(system_nonce_config) final int maxNonce = 128; final int maxByte = 8192; // LINT.ThenChange(/core/jni/android_app_PropertyInvalidatedCache.h:system_nonce_config) // Fetch a shared memory instance for testing. ApplicationSharedMemory shmem = ApplicationSharedMemory.create(); // Create a server-side store. NonceStore server = new NonceStore(shmem.getSystemNonceBlock(), true); // Verify that the configured limits are as expected. assertEquals(server.mMaxNonce, maxNonce); assertEquals(server.mMaxByte, maxByte); // Create mMaxNonce nonces. These all succeed. for (int i = 0; i < server.mMaxNonce; i++) { String name = String.format("name_%03d", i); assertEquals(i, server.storeName(name)); } // Verify that we cannot create a nonce over the limit. try { int i = server.mMaxNonce; String name = String.format("name_%03d", i); server.storeName(name); fail("expected a RuntimeException"); } catch (RuntimeException e) { // Okay } shmem.close(); } // Verify that an invalid module causes an exception. private void testInvalidModule(String module) { try { Loading Loading
core/java/android/app/PropertyInvalidatedCache.java +12 −8 Original line number Diff line number Diff line Loading @@ -2321,12 +2321,14 @@ public class PropertyInvalidatedCache<Query, Result> { @GuardedBy("mLock") private int mBlockHash = 0; // The number of nonces that the native layer can hold. This is maintained for debug and // logging. private final int mMaxNonce; // The number of nonces that the native layer can hold. This is maintained for debug, // logging, and testing. @VisibleForTesting public final int mMaxNonce; // The size of the native byte block. private final int mMaxByte; @VisibleForTesting public final int mMaxByte; /** @hide */ @VisibleForTesting Loading Loading @@ -2483,18 +2485,20 @@ public class PropertyInvalidatedCache<Query, Result> { } } static final AtomicLong sStoreCount = new AtomicLong(); // Add a string to the local copy of the block and write the block to shared memory. // Return the index of the new string. If the string has already been recorded, the // shared memory is not updated but the index of the existing string is returned. // shared memory is not updated but the index of the existing string is returned. Only // mMaxNonce strings can be stored; if mMaxNonce strings have already been allocated, // the method throws. public int storeName(@NonNull String str) { synchronized (mLock) { Integer handle = mStringHandle.get(str); if (handle == null) { throwIfImmutable(); throwIfBadString(str); if (mHighestIndex + 1 >= mMaxNonce) { throw new RuntimeException("nonce limit exceeded"); } byte[] block = new byte[mMaxByte]; nativeGetByteBlock(mPtr, 0, block); appendStringToMapLocked(str, block); Loading
core/jni/android_app_PropertyInvalidatedCache.h +7 −5 Original line number Diff line number Diff line Loading @@ -147,10 +147,12 @@ template<int maxNonce, size_t maxByte> class CacheNonce : public NonceStore { } }; // The CacheNonce for system server holds 64 nonces with a string block of 8192 bytes. This is // more than enough for system_server PropertyInvalidatedCache support. The configuration // values are not defined as visible constants. Clients should use the accessors on the // SystemCacheNonce instance if they need the sizing parameters. typedef CacheNonce</* max nonce */ 64, /* byte block size */ 8192> SystemCacheNonce; // The CacheNonce for system server. The configuration values are not defined as visible // constants. Clients should use the accessors on the SystemCacheNonce instance if they need // the sizing parameters. // LINT.IfChange(system_nonce_config) typedef CacheNonce</* max nonce */ 128, /* byte block size */ 8192> SystemCacheNonce; // LINT.ThenChange(/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java:system_nonce_config) } // namespace android.app.PropertyInvalidatedCache
core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java +47 −4 Original line number Diff line number Diff line Loading @@ -37,8 +37,10 @@ import android.app.PropertyInvalidatedCache.Args; import android.app.PropertyInvalidatedCache.NonceWatcher; import android.app.PropertyInvalidatedCache.NonceStore; import android.os.Binder; import android.util.Log; import com.android.internal.os.ApplicationSharedMemory; import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; Loading Loading @@ -410,8 +412,7 @@ public class PropertyInvalidatedCacheTests { // Verify that invalidating the cache from an app process would fail due to lack of permissions. @Test @android.platform.test.annotations.DisabledOnRavenwood( reason = "SystemProperties doesn't have permission check") @DisabledOnRavenwood(reason = "SystemProperties doesn't have permission check") public void testPermissionFailure() { // Create a cache that will write a system nonce. TestCache sysCache = new TestCache(MODULE_SYSTEM, "mode1"); Loading Loading @@ -556,8 +557,7 @@ public class PropertyInvalidatedCacheTests { // storing nonces in shared memory. @RequiresFlagsEnabled(FLAG_APPLICATION_SHARED_MEMORY_ENABLED) @Test @android.platform.test.annotations.DisabledOnRavenwood( reason = "PIC doesn't use SharedMemory on Ravenwood") @DisabledOnRavenwood(reason = "PIC doesn't use SharedMemory on Ravenwood") public void testSharedMemoryStorage() { // Fetch a shared memory instance for testing. ApplicationSharedMemory shmem = ApplicationSharedMemory.create(); Loading Loading @@ -602,6 +602,49 @@ public class PropertyInvalidatedCacheTests { shmem.close(); } // Verify that the configured number of nonce slots is actually available. This test // hard-codes the configured number of slots, which means that this test must be changed // whenever the shared memory configuration changes. @RequiresFlagsEnabled(FLAG_APPLICATION_SHARED_MEMORY_ENABLED) @Test @DisabledOnRavenwood(reason = "PIC doesn't use SharedMemory on Ravenwood") public void testSharedMemoryNonceConfig() { // The two configured constants. These are private to this method since they are only // used here. // LINT.IfChange(system_nonce_config) final int maxNonce = 128; final int maxByte = 8192; // LINT.ThenChange(/core/jni/android_app_PropertyInvalidatedCache.h:system_nonce_config) // Fetch a shared memory instance for testing. ApplicationSharedMemory shmem = ApplicationSharedMemory.create(); // Create a server-side store. NonceStore server = new NonceStore(shmem.getSystemNonceBlock(), true); // Verify that the configured limits are as expected. assertEquals(server.mMaxNonce, maxNonce); assertEquals(server.mMaxByte, maxByte); // Create mMaxNonce nonces. These all succeed. for (int i = 0; i < server.mMaxNonce; i++) { String name = String.format("name_%03d", i); assertEquals(i, server.storeName(name)); } // Verify that we cannot create a nonce over the limit. try { int i = server.mMaxNonce; String name = String.format("name_%03d", i); server.storeName(name); fail("expected a RuntimeException"); } catch (RuntimeException e) { // Okay } shmem.close(); } // Verify that an invalid module causes an exception. private void testInvalidModule(String module) { try { Loading