Loading services/core/java/com/android/server/PinnerService.java +27 −4 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; import android.provider.DeviceConfigInterface; import android.provider.MediaStore; import android.provider.Settings; import android.system.ErrnoException; Loading @@ -61,6 +62,7 @@ import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ResolverActivity; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; Loading Loading @@ -123,6 +125,8 @@ public final class PinnerService extends SystemService { public @interface AppKey {} private final Context mContext; private final Injector mInjector; private final DeviceConfigInterface mDeviceConfigInterface; private final ActivityTaskManagerInternal mAtmInternal; private final ActivityManagerInternal mAmInternal; private final IActivityManager mAm; Loading Loading @@ -195,10 +199,29 @@ public final class PinnerService extends SystemService { } }; /** Utility class for testing. */ @VisibleForTesting static class Injector { protected DeviceConfigInterface getDeviceConfigInterface() { return DeviceConfigInterface.REAL; } protected void publishBinderService(PinnerService service, Binder binderService) { service.publishBinderService("pinner", binderService); } } public PinnerService(Context context) { this(context, new Injector()); } @VisibleForTesting PinnerService(Context context, Injector injector) { super(context); mContext = context; mInjector = injector; mDeviceConfigInterface = mInjector.getDeviceConfigInterface(); mConfiguredToPinCamera = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerCameraApp); mConfiguredToPinHome = context.getResources().getBoolean( Loading @@ -222,7 +245,7 @@ public final class PinnerService extends SystemService { registerUidListener(); registerUserSetupCompleteListener(); DeviceConfig.addOnPropertiesChangedListener( mDeviceConfigInterface.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, new HandlerExecutor(mPinnerHandler), mDeviceConfigListener); Loading @@ -234,7 +257,7 @@ public final class PinnerService extends SystemService { Slog.i(TAG, "Starting PinnerService"); } mBinderService = new BinderService(); publishBinderService("pinner", mBinderService); mInjector.publishBinderService(this, mBinderService); publishLocalService(PinnerService.class, this); mPinnerHandler.obtainMessage(PinnerHandler.PIN_ONSTART_MSG).sendToTarget(); Loading Loading @@ -566,7 +589,7 @@ public final class PinnerService extends SystemService { // Pin the camera application. Default to the system property only if the experiment // phenotype property is not set. boolean shouldPinCamera = mConfiguredToPinCamera && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, && mDeviceConfigInterface.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, "pin_camera", SystemProperties.getBoolean("pinner.pin_camera", true)); if (shouldPinCamera) { Loading Loading @@ -709,7 +732,7 @@ public final class PinnerService extends SystemService { */ private void refreshPinAnonConfig() { long newPinAnonSize = DeviceConfig.getLong( mDeviceConfigInterface.getLong( DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, DEVICE_CONFIG_KEY_ANON_SIZE, DEFAULT_ANON_SIZE); Loading services/tests/servicestests/src/com/android/server/PinnerServiceTest.java +117 −27 Original line number Diff line number Diff line Loading @@ -22,28 +22,32 @@ import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.app.ActivityManagerInternal; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.testing.AndroidTestingRunner; import android.provider.DeviceConfig; import android.provider.DeviceConfigInterface; import android.testing.TestableContext; import android.testing.TestableLooper; import android.testing.TestableResources; import android.util.ArrayMap; import android.util.ArraySet; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.testutils.FakeDeviceConfigInterface; import com.android.server.wm.ActivityTaskManagerInternal; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -61,7 +65,8 @@ import java.lang.reflect.Method; import java.util.Optional; import java.util.concurrent.TimeUnit; @RunWith(AndroidTestingRunner.class) @SmallTest @RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper public class PinnerServiceTest { private static final int KEY_CAMERA = 0; Loading @@ -76,6 +81,8 @@ public class PinnerServiceTest { private final ArraySet<String> mUpdatedPackages = new ArraySet<>(); private ResolveInfo mHomePackageResolveInfo; private FakeDeviceConfigInterface mFakeDeviceConfigInterface; private PinnerService.Injector mInjector; @Before public void setUp() { Loading @@ -85,6 +92,8 @@ public class PinnerServiceTest { Looper.prepare(); } // PinnerService.onStart will add itself as a local service, remove to avoid conflicts. LocalServices.removeServiceForTest(PinnerService.class); LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class); LocalServices.removeServiceForTest(ActivityManagerInternal.class); Loading @@ -100,6 +109,17 @@ public class PinnerServiceTest { doReturn(true).when(mockActivityManagerInternal).isUidActive(anyInt()); LocalServices.addService(ActivityManagerInternal.class, mockActivityManagerInternal); // Configure the default state to disable any pinning. TestableResources resources = mContext.getOrCreateTestableResources(); resources.addOverride( com.android.internal.R.array.config_defaultPinnerServiceFiles, new String[0]); resources.addOverride(com.android.internal.R.bool.config_pinnerCameraApp, false); resources.addOverride(com.android.internal.R.bool.config_pinnerHomeApp, false); resources.addOverride(com.android.internal.R.bool.config_pinnerAssistantApp, false); mFakeDeviceConfigInterface = new FakeDeviceConfigInterface(); setDeviceConfigPinnedAnonSize(0); mContext = spy(mContext); // Get HOME (Launcher) package Loading @@ -107,6 +127,18 @@ public class PinnerServiceTest { PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 0); mUpdatedPackages.add(mHomePackageResolveInfo.activityInfo.applicationInfo.packageName); mInjector = new PinnerService.Injector() { @Override protected DeviceConfigInterface getDeviceConfigInterface() { return mFakeDeviceConfigInterface; } @Override protected void publishBinderService(PinnerService service, Binder binderService) { // Suppress this for testing, it's not needed and causes conflitcs. } }; } @After Loading @@ -122,12 +154,12 @@ public class PinnerServiceTest { } private void unpinAll(PinnerService pinnerService) throws Exception { // unpin all packages Method unpinAppMethod = PinnerService.class.getDeclaredMethod("unpinApp", int.class); unpinAppMethod.setAccessible(true); unpinAppMethod.invoke(pinnerService, KEY_HOME); unpinAppMethod.invoke(pinnerService, KEY_CAMERA); unpinAppMethod.invoke(pinnerService, KEY_ASSISTANT); Method unpinAppsMethod = PinnerService.class.getDeclaredMethod("unpinApps"); unpinAppsMethod.setAccessible(true); unpinAppsMethod.invoke(pinnerService); Method unpinAnonRegionMethod = PinnerService.class.getDeclaredMethod("unpinAnonRegion"); unpinAnonRegionMethod.setAccessible(true); unpinAnonRegionMethod.invoke(pinnerService); } private void waitForPinnerService(PinnerService pinnerService) Loading Loading @@ -171,21 +203,37 @@ public class PinnerServiceTest { } private int getPinnedSize(PinnerService pinnerService) throws Exception { final String totalSizeToken = "Total size: "; return getPinnedSizeImpl(pinnerService, "Total size: "); } private int getPinnedAnonSize(PinnerService pinnerService) throws Exception { return getPinnedSizeImpl(pinnerService, "Pinned anon region: "); } private int getPinnedSizeImpl(PinnerService pinnerService, String sizeToken) throws Exception { String dumpOutput = getPinnerServiceDump(pinnerService); BufferedReader bufReader = new BufferedReader(new StringReader(dumpOutput)); Optional<Integer> size = bufReader.lines().filter(s -> s.contains(totalSizeToken)) .map(s -> Integer.valueOf(s.substring(totalSizeToken.length()))).findAny(); Optional<Integer> size = bufReader.lines().filter(s -> s.contains(sizeToken)) .map(s -> Integer.valueOf(s.substring(sizeToken.length()))).findAny(); return size.orElse(-1); } private void setDeviceConfigPinnedAnonSize(long size) { mFakeDeviceConfigInterface.setProperty( DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, "pin_shared_anon_size", String.valueOf(size), /*makeDefault=*/false); } @Test @Ignore("b/309853498, pinning home app can fail with ENOMEM") public void testPinHomeApp() throws Exception { // Enable HOME app pinning Resources res = mock(Resources.class); doReturn(true).when(res).getBoolean(com.android.internal.R.bool.config_pinnerHomeApp); when(mContext.getResources()).thenReturn(res); PinnerService pinnerService = new PinnerService(mContext); mContext.getOrCreateTestableResources() .addOverride(com.android.internal.R.bool.config_pinnerHomeApp, true); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); ArraySet<Integer> pinKeys = getPinKeys(pinnerService); assertThat(pinKeys.valueAt(0)).isEqualTo(KEY_HOME); Loading @@ -201,17 +249,17 @@ public class PinnerServiceTest { int totalPinnedSizeBytes = getPinnedSize(pinnerService); assertThat(totalPinnedSizeBytes).isGreaterThan(0); // Make sure pinned files are unmapped unpinAll(pinnerService); } @Test @Ignore("b/309853498, pinning home app can fail with ENOMEM") public void testPinHomeAppOnBootCompleted() throws Exception { // Enable HOME app pinning Resources res = mock(Resources.class); doReturn(true).when(res).getBoolean(com.android.internal.R.bool.config_pinnerHomeApp); when(mContext.getResources()).thenReturn(res); PinnerService pinnerService = new PinnerService(mContext); mContext.getOrCreateTestableResources() .addOverride(com.android.internal.R.bool.config_pinnerHomeApp, true); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); ArraySet<Integer> pinKeys = getPinKeys(pinnerService); assertThat(pinKeys.valueAt(0)).isEqualTo(KEY_HOME); Loading @@ -227,16 +275,14 @@ public class PinnerServiceTest { int totalPinnedSizeBytes = getPinnedSize(pinnerService); assertThat(totalPinnedSizeBytes).isGreaterThan(0); // Make sure pinned files are unmapped unpinAll(pinnerService); } @Test public void testNothingToPin() throws Exception { // No package enabled for pinning Resources res = mock(Resources.class); when(mContext.getResources()).thenReturn(res); PinnerService pinnerService = new PinnerService(mContext); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); ArraySet<Integer> pinKeys = getPinKeys(pinnerService); assertThat(pinKeys).isEmpty(); Loading @@ -252,7 +298,51 @@ public class PinnerServiceTest { int totalPinnedSizeBytes = getPinnedSize(pinnerService); assertThat(totalPinnedSizeBytes).isEqualTo(0); // Make sure pinned files are unmapped int pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(-1); unpinAll(pinnerService); } @Test public void testPinAnonRegion() throws Exception { setDeviceConfigPinnedAnonSize(32768); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); waitForPinnerService(pinnerService); // Ensure the dump reflects the requested anon region. int pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(32768); unpinAll(pinnerService); } @Test public void testPinAnonRegionUpdatesOnConfigChange() throws Exception { PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); waitForPinnerService(pinnerService); // Ensure the PinnerService updates itself when the associated DeviceConfig changes. setDeviceConfigPinnedAnonSize(65536); waitForPinnerService(pinnerService); int pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(65536); // Each update should be reflected in the reported status. setDeviceConfigPinnedAnonSize(32768); waitForPinnerService(pinnerService); pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(32768); setDeviceConfigPinnedAnonSize(0); waitForPinnerService(pinnerService); // An empty anon region should clear the associated status entry. pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(-1); unpinAll(pinnerService); } Loading Loading
services/core/java/com/android/server/PinnerService.java +27 −4 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; import android.provider.DeviceConfigInterface; import android.provider.MediaStore; import android.provider.Settings; import android.system.ErrnoException; Loading @@ -61,6 +62,7 @@ import android.util.ArraySet; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.ResolverActivity; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; Loading Loading @@ -123,6 +125,8 @@ public final class PinnerService extends SystemService { public @interface AppKey {} private final Context mContext; private final Injector mInjector; private final DeviceConfigInterface mDeviceConfigInterface; private final ActivityTaskManagerInternal mAtmInternal; private final ActivityManagerInternal mAmInternal; private final IActivityManager mAm; Loading Loading @@ -195,10 +199,29 @@ public final class PinnerService extends SystemService { } }; /** Utility class for testing. */ @VisibleForTesting static class Injector { protected DeviceConfigInterface getDeviceConfigInterface() { return DeviceConfigInterface.REAL; } protected void publishBinderService(PinnerService service, Binder binderService) { service.publishBinderService("pinner", binderService); } } public PinnerService(Context context) { this(context, new Injector()); } @VisibleForTesting PinnerService(Context context, Injector injector) { super(context); mContext = context; mInjector = injector; mDeviceConfigInterface = mInjector.getDeviceConfigInterface(); mConfiguredToPinCamera = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerCameraApp); mConfiguredToPinHome = context.getResources().getBoolean( Loading @@ -222,7 +245,7 @@ public final class PinnerService extends SystemService { registerUidListener(); registerUserSetupCompleteListener(); DeviceConfig.addOnPropertiesChangedListener( mDeviceConfigInterface.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, new HandlerExecutor(mPinnerHandler), mDeviceConfigListener); Loading @@ -234,7 +257,7 @@ public final class PinnerService extends SystemService { Slog.i(TAG, "Starting PinnerService"); } mBinderService = new BinderService(); publishBinderService("pinner", mBinderService); mInjector.publishBinderService(this, mBinderService); publishLocalService(PinnerService.class, this); mPinnerHandler.obtainMessage(PinnerHandler.PIN_ONSTART_MSG).sendToTarget(); Loading Loading @@ -566,7 +589,7 @@ public final class PinnerService extends SystemService { // Pin the camera application. Default to the system property only if the experiment // phenotype property is not set. boolean shouldPinCamera = mConfiguredToPinCamera && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, && mDeviceConfigInterface.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, "pin_camera", SystemProperties.getBoolean("pinner.pin_camera", true)); if (shouldPinCamera) { Loading Loading @@ -709,7 +732,7 @@ public final class PinnerService extends SystemService { */ private void refreshPinAnonConfig() { long newPinAnonSize = DeviceConfig.getLong( mDeviceConfigInterface.getLong( DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, DEVICE_CONFIG_KEY_ANON_SIZE, DEFAULT_ANON_SIZE); Loading
services/tests/servicestests/src/com/android/server/PinnerServiceTest.java +117 −27 Original line number Diff line number Diff line Loading @@ -22,28 +22,32 @@ import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.app.ActivityManagerInternal; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.os.Binder; import android.os.Handler; import android.os.Looper; import android.testing.AndroidTestingRunner; import android.provider.DeviceConfig; import android.provider.DeviceConfigInterface; import android.testing.TestableContext; import android.testing.TestableLooper; import android.testing.TestableResources; import android.util.ArrayMap; import android.util.ArraySet; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.testutils.FakeDeviceConfigInterface; import com.android.server.wm.ActivityTaskManagerInternal; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -61,7 +65,8 @@ import java.lang.reflect.Method; import java.util.Optional; import java.util.concurrent.TimeUnit; @RunWith(AndroidTestingRunner.class) @SmallTest @RunWith(AndroidJUnit4.class) @TestableLooper.RunWithLooper public class PinnerServiceTest { private static final int KEY_CAMERA = 0; Loading @@ -76,6 +81,8 @@ public class PinnerServiceTest { private final ArraySet<String> mUpdatedPackages = new ArraySet<>(); private ResolveInfo mHomePackageResolveInfo; private FakeDeviceConfigInterface mFakeDeviceConfigInterface; private PinnerService.Injector mInjector; @Before public void setUp() { Loading @@ -85,6 +92,8 @@ public class PinnerServiceTest { Looper.prepare(); } // PinnerService.onStart will add itself as a local service, remove to avoid conflicts. LocalServices.removeServiceForTest(PinnerService.class); LocalServices.removeServiceForTest(ActivityTaskManagerInternal.class); LocalServices.removeServiceForTest(ActivityManagerInternal.class); Loading @@ -100,6 +109,17 @@ public class PinnerServiceTest { doReturn(true).when(mockActivityManagerInternal).isUidActive(anyInt()); LocalServices.addService(ActivityManagerInternal.class, mockActivityManagerInternal); // Configure the default state to disable any pinning. TestableResources resources = mContext.getOrCreateTestableResources(); resources.addOverride( com.android.internal.R.array.config_defaultPinnerServiceFiles, new String[0]); resources.addOverride(com.android.internal.R.bool.config_pinnerCameraApp, false); resources.addOverride(com.android.internal.R.bool.config_pinnerHomeApp, false); resources.addOverride(com.android.internal.R.bool.config_pinnerAssistantApp, false); mFakeDeviceConfigInterface = new FakeDeviceConfigInterface(); setDeviceConfigPinnedAnonSize(0); mContext = spy(mContext); // Get HOME (Launcher) package Loading @@ -107,6 +127,18 @@ public class PinnerServiceTest { PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 0); mUpdatedPackages.add(mHomePackageResolveInfo.activityInfo.applicationInfo.packageName); mInjector = new PinnerService.Injector() { @Override protected DeviceConfigInterface getDeviceConfigInterface() { return mFakeDeviceConfigInterface; } @Override protected void publishBinderService(PinnerService service, Binder binderService) { // Suppress this for testing, it's not needed and causes conflitcs. } }; } @After Loading @@ -122,12 +154,12 @@ public class PinnerServiceTest { } private void unpinAll(PinnerService pinnerService) throws Exception { // unpin all packages Method unpinAppMethod = PinnerService.class.getDeclaredMethod("unpinApp", int.class); unpinAppMethod.setAccessible(true); unpinAppMethod.invoke(pinnerService, KEY_HOME); unpinAppMethod.invoke(pinnerService, KEY_CAMERA); unpinAppMethod.invoke(pinnerService, KEY_ASSISTANT); Method unpinAppsMethod = PinnerService.class.getDeclaredMethod("unpinApps"); unpinAppsMethod.setAccessible(true); unpinAppsMethod.invoke(pinnerService); Method unpinAnonRegionMethod = PinnerService.class.getDeclaredMethod("unpinAnonRegion"); unpinAnonRegionMethod.setAccessible(true); unpinAnonRegionMethod.invoke(pinnerService); } private void waitForPinnerService(PinnerService pinnerService) Loading Loading @@ -171,21 +203,37 @@ public class PinnerServiceTest { } private int getPinnedSize(PinnerService pinnerService) throws Exception { final String totalSizeToken = "Total size: "; return getPinnedSizeImpl(pinnerService, "Total size: "); } private int getPinnedAnonSize(PinnerService pinnerService) throws Exception { return getPinnedSizeImpl(pinnerService, "Pinned anon region: "); } private int getPinnedSizeImpl(PinnerService pinnerService, String sizeToken) throws Exception { String dumpOutput = getPinnerServiceDump(pinnerService); BufferedReader bufReader = new BufferedReader(new StringReader(dumpOutput)); Optional<Integer> size = bufReader.lines().filter(s -> s.contains(totalSizeToken)) .map(s -> Integer.valueOf(s.substring(totalSizeToken.length()))).findAny(); Optional<Integer> size = bufReader.lines().filter(s -> s.contains(sizeToken)) .map(s -> Integer.valueOf(s.substring(sizeToken.length()))).findAny(); return size.orElse(-1); } private void setDeviceConfigPinnedAnonSize(long size) { mFakeDeviceConfigInterface.setProperty( DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, "pin_shared_anon_size", String.valueOf(size), /*makeDefault=*/false); } @Test @Ignore("b/309853498, pinning home app can fail with ENOMEM") public void testPinHomeApp() throws Exception { // Enable HOME app pinning Resources res = mock(Resources.class); doReturn(true).when(res).getBoolean(com.android.internal.R.bool.config_pinnerHomeApp); when(mContext.getResources()).thenReturn(res); PinnerService pinnerService = new PinnerService(mContext); mContext.getOrCreateTestableResources() .addOverride(com.android.internal.R.bool.config_pinnerHomeApp, true); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); ArraySet<Integer> pinKeys = getPinKeys(pinnerService); assertThat(pinKeys.valueAt(0)).isEqualTo(KEY_HOME); Loading @@ -201,17 +249,17 @@ public class PinnerServiceTest { int totalPinnedSizeBytes = getPinnedSize(pinnerService); assertThat(totalPinnedSizeBytes).isGreaterThan(0); // Make sure pinned files are unmapped unpinAll(pinnerService); } @Test @Ignore("b/309853498, pinning home app can fail with ENOMEM") public void testPinHomeAppOnBootCompleted() throws Exception { // Enable HOME app pinning Resources res = mock(Resources.class); doReturn(true).when(res).getBoolean(com.android.internal.R.bool.config_pinnerHomeApp); when(mContext.getResources()).thenReturn(res); PinnerService pinnerService = new PinnerService(mContext); mContext.getOrCreateTestableResources() .addOverride(com.android.internal.R.bool.config_pinnerHomeApp, true); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); ArraySet<Integer> pinKeys = getPinKeys(pinnerService); assertThat(pinKeys.valueAt(0)).isEqualTo(KEY_HOME); Loading @@ -227,16 +275,14 @@ public class PinnerServiceTest { int totalPinnedSizeBytes = getPinnedSize(pinnerService); assertThat(totalPinnedSizeBytes).isGreaterThan(0); // Make sure pinned files are unmapped unpinAll(pinnerService); } @Test public void testNothingToPin() throws Exception { // No package enabled for pinning Resources res = mock(Resources.class); when(mContext.getResources()).thenReturn(res); PinnerService pinnerService = new PinnerService(mContext); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); ArraySet<Integer> pinKeys = getPinKeys(pinnerService); assertThat(pinKeys).isEmpty(); Loading @@ -252,7 +298,51 @@ public class PinnerServiceTest { int totalPinnedSizeBytes = getPinnedSize(pinnerService); assertThat(totalPinnedSizeBytes).isEqualTo(0); // Make sure pinned files are unmapped int pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(-1); unpinAll(pinnerService); } @Test public void testPinAnonRegion() throws Exception { setDeviceConfigPinnedAnonSize(32768); PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); waitForPinnerService(pinnerService); // Ensure the dump reflects the requested anon region. int pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(32768); unpinAll(pinnerService); } @Test public void testPinAnonRegionUpdatesOnConfigChange() throws Exception { PinnerService pinnerService = new PinnerService(mContext, mInjector); pinnerService.onStart(); waitForPinnerService(pinnerService); // Ensure the PinnerService updates itself when the associated DeviceConfig changes. setDeviceConfigPinnedAnonSize(65536); waitForPinnerService(pinnerService); int pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(65536); // Each update should be reflected in the reported status. setDeviceConfigPinnedAnonSize(32768); waitForPinnerService(pinnerService); pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(32768); setDeviceConfigPinnedAnonSize(0); waitForPinnerService(pinnerService); // An empty anon region should clear the associated status entry. pinnedAnonSizeBytes = getPinnedAnonSize(pinnerService); assertThat(pinnedAnonSizeBytes).isEqualTo(-1); unpinAll(pinnerService); } Loading