Loading core/java/android/os/IpcDataCache.java +55 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.os; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringDef; Loading Loading @@ -551,13 +552,21 @@ public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query, } /** * An interface suitable for a lambda expression instead of a QueryHandler. * An interface suitable for a lambda expression instead of a QueryHandler applying remote call. * @hide */ public interface RemoteCall<Query, Result> { Result apply(Query query) throws RemoteException; } /** * An interface suitable for a lambda expression instead of a QueryHandler bypassing the cache. * @hide */ public interface BypassCall<Query> { Boolean apply(Query query); } /** * This is a query handler that is created with a lambda expression that is invoked * every time the handler is called. The handler is specifically meant for services Loading @@ -580,11 +589,54 @@ public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query, } } /** * Create a cache using a config and a lambda expression. * @param config The configuration for the cache. * @param remoteCall The lambda expression that will be invoked to fetch the data. * @hide */ public IpcDataCache(@NonNull Config config, @NonNull RemoteCall<Query, Result> remoteCall) { this(config, android.multiuser.Flags.cachingDevelopmentImprovements() ? new QueryHandler<Query, Result>() { @Override public Result apply(Query query) { try { return remoteCall.apply(query); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } : new SystemServerCallHandler<>(remoteCall)); } /** * Create a cache using a config and a lambda expression. * @param config The configuration for the cache. * @param remoteCall The lambda expression that will be invoked to fetch the data. * @param bypass The lambda expression that will be invoked to determine if the cache should be * bypassed. * @hide */ public IpcDataCache(@NonNull Config config, @NonNull RemoteCall<Query, Result> computer) { this(config, new SystemServerCallHandler<>(computer)); @FlaggedApi(android.multiuser.Flags.FLAG_CACHING_DEVELOPMENT_IMPROVEMENTS) public IpcDataCache(@NonNull Config config, @NonNull RemoteCall<Query, Result> remoteCall, @NonNull BypassCall<Query> bypass) { this(config, new QueryHandler<Query, Result>() { @Override public Result apply(Query query) { try { return remoteCall.apply(query); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override public boolean shouldBypassCache(Query query) { return bypass.apply(query); } }); } } core/tests/coretests/src/android/os/IpcDataCacheTest.java +40 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package android.os; import static org.junit.Assert.assertEquals; import android.multiuser.Flags; import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; Loading Loading @@ -151,8 +153,6 @@ public class IpcDataCacheTest { tester.verify(9); } // This test is disabled pending an sepolicy change that allows any app to set the // test property. @Test public void testRemoteCall() { Loading Loading @@ -192,6 +192,44 @@ public class IpcDataCacheTest { tester.verify(4); } @Test @RequiresFlagsEnabled(Flags.FLAG_CACHING_DEVELOPMENT_IMPROVEMENTS) public void testRemoteCallBypass() { // A stand-in for the binder. The test verifies that calls are passed through to // this class properly. ServerProxy tester = new ServerProxy(); // Create a cache that uses simple arithmetic to computer its values. IpcDataCache.Config config = new IpcDataCache.Config(4, MODULE, API, "testCache3"); IpcDataCache<Integer, Boolean> testCache = new IpcDataCache<>(config, (x) -> tester.query(x), (x) -> x % 9 == 0); IpcDataCache.setTestMode(true); testCache.testPropertyName(); tester.verify(0); assertEquals(tester.value(3), testCache.query(3)); tester.verify(1); assertEquals(tester.value(3), testCache.query(3)); tester.verify(2); testCache.invalidateCache(); assertEquals(tester.value(3), testCache.query(3)); tester.verify(3); assertEquals(tester.value(5), testCache.query(5)); tester.verify(4); assertEquals(tester.value(5), testCache.query(5)); tester.verify(4); assertEquals(tester.value(3), testCache.query(3)); tester.verify(4); assertEquals(tester.value(9), testCache.query(9)); tester.verify(5); assertEquals(tester.value(3), testCache.query(3)); tester.verify(5); assertEquals(tester.value(5), testCache.query(5)); tester.verify(5); } @Test public void testDisableCache() { Loading Loading
core/java/android/os/IpcDataCache.java +55 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.os; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringDef; Loading Loading @@ -551,13 +552,21 @@ public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query, } /** * An interface suitable for a lambda expression instead of a QueryHandler. * An interface suitable for a lambda expression instead of a QueryHandler applying remote call. * @hide */ public interface RemoteCall<Query, Result> { Result apply(Query query) throws RemoteException; } /** * An interface suitable for a lambda expression instead of a QueryHandler bypassing the cache. * @hide */ public interface BypassCall<Query> { Boolean apply(Query query); } /** * This is a query handler that is created with a lambda expression that is invoked * every time the handler is called. The handler is specifically meant for services Loading @@ -580,11 +589,54 @@ public class IpcDataCache<Query, Result> extends PropertyInvalidatedCache<Query, } } /** * Create a cache using a config and a lambda expression. * @param config The configuration for the cache. * @param remoteCall The lambda expression that will be invoked to fetch the data. * @hide */ public IpcDataCache(@NonNull Config config, @NonNull RemoteCall<Query, Result> remoteCall) { this(config, android.multiuser.Flags.cachingDevelopmentImprovements() ? new QueryHandler<Query, Result>() { @Override public Result apply(Query query) { try { return remoteCall.apply(query); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } : new SystemServerCallHandler<>(remoteCall)); } /** * Create a cache using a config and a lambda expression. * @param config The configuration for the cache. * @param remoteCall The lambda expression that will be invoked to fetch the data. * @param bypass The lambda expression that will be invoked to determine if the cache should be * bypassed. * @hide */ public IpcDataCache(@NonNull Config config, @NonNull RemoteCall<Query, Result> computer) { this(config, new SystemServerCallHandler<>(computer)); @FlaggedApi(android.multiuser.Flags.FLAG_CACHING_DEVELOPMENT_IMPROVEMENTS) public IpcDataCache(@NonNull Config config, @NonNull RemoteCall<Query, Result> remoteCall, @NonNull BypassCall<Query> bypass) { this(config, new QueryHandler<Query, Result>() { @Override public Result apply(Query query) { try { return remoteCall.apply(query); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } @Override public boolean shouldBypassCache(Query query) { return bypass.apply(query); } }); } }
core/tests/coretests/src/android/os/IpcDataCacheTest.java +40 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,9 @@ package android.os; import static org.junit.Assert.assertEquals; import android.multiuser.Flags; import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; Loading Loading @@ -151,8 +153,6 @@ public class IpcDataCacheTest { tester.verify(9); } // This test is disabled pending an sepolicy change that allows any app to set the // test property. @Test public void testRemoteCall() { Loading Loading @@ -192,6 +192,44 @@ public class IpcDataCacheTest { tester.verify(4); } @Test @RequiresFlagsEnabled(Flags.FLAG_CACHING_DEVELOPMENT_IMPROVEMENTS) public void testRemoteCallBypass() { // A stand-in for the binder. The test verifies that calls are passed through to // this class properly. ServerProxy tester = new ServerProxy(); // Create a cache that uses simple arithmetic to computer its values. IpcDataCache.Config config = new IpcDataCache.Config(4, MODULE, API, "testCache3"); IpcDataCache<Integer, Boolean> testCache = new IpcDataCache<>(config, (x) -> tester.query(x), (x) -> x % 9 == 0); IpcDataCache.setTestMode(true); testCache.testPropertyName(); tester.verify(0); assertEquals(tester.value(3), testCache.query(3)); tester.verify(1); assertEquals(tester.value(3), testCache.query(3)); tester.verify(2); testCache.invalidateCache(); assertEquals(tester.value(3), testCache.query(3)); tester.verify(3); assertEquals(tester.value(5), testCache.query(5)); tester.verify(4); assertEquals(tester.value(5), testCache.query(5)); tester.verify(4); assertEquals(tester.value(3), testCache.query(3)); tester.verify(4); assertEquals(tester.value(9), testCache.query(9)); tester.verify(5); assertEquals(tester.value(3), testCache.query(3)); tester.verify(5); assertEquals(tester.value(5), testCache.query(5)); tester.verify(5); } @Test public void testDisableCache() { Loading