Loading api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -5844,6 +5844,7 @@ package android.provider { public static interface DeviceConfig.ActivityManager { field public static final String KEY_COMPACT_ACTION_1 = "compact_action_1"; field public static final String KEY_COMPACT_ACTION_2 = "compact_action_2"; field public static final String KEY_COMPACT_STATSD_SAMPLE_RATE = "compact_statsd_sample_rate"; field public static final String KEY_COMPACT_THROTTLE_1 = "compact_throttle_1"; field public static final String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2"; field public static final String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3"; Loading core/java/android/provider/DeviceConfig.java +1 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,7 @@ public final class DeviceConfig { String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2"; String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3"; String KEY_COMPACT_THROTTLE_4 = "compact_throttle_4"; String KEY_COMPACT_STATSD_SAMPLE_RATE = "compact_statsd_sample_rate"; /** * Maximum number of cached processes. See Loading services/core/java/com/android/server/am/AppCompactor.java +42 −12 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.am; import static android.os.Process.THREAD_PRIORITY_FOREGROUND; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_1; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_2; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_STATSD_SAMPLE_RATE; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_1; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_2; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_3; Loading @@ -45,6 +46,7 @@ import com.android.server.ServiceThread; import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Random; public final class AppCompactor { Loading @@ -65,6 +67,8 @@ public final class AppCompactor { @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_2 = 10_000; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_3 = 500; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_4 = 10_000; // The sampling rate to push app compaction events into statsd for upload. @VisibleForTesting static final float DEFAULT_STATSD_SAMPLE_RATE = 0.1f; @VisibleForTesting interface PropertyChangedCallbackForTest { Loading Loading @@ -104,6 +108,8 @@ public final class AppCompactor { || KEY_COMPACT_THROTTLE_3.equals(name) || KEY_COMPACT_THROTTLE_4.equals(name)) { updateCompactionThrottles(); } else if (KEY_COMPACT_STATSD_SAMPLE_RATE.equals(name)) { updateStatsdSampleRate(); } } if (mTestCallback != null) { Loading @@ -116,21 +122,25 @@ public final class AppCompactor { // Configured by phenotype. Updates from the server take effect immediately. @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting String mCompactActionSome = @VisibleForTesting volatile String mCompactActionSome = compactActionIntToString(DEFAULT_COMPACT_ACTION_1); @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting String mCompactActionFull = @VisibleForTesting volatile String mCompactActionFull = compactActionIntToString(DEFAULT_COMPACT_ACTION_2); @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting long mCompactThrottleSomeSome = DEFAULT_COMPACT_THROTTLE_1; @VisibleForTesting volatile long mCompactThrottleSomeSome = DEFAULT_COMPACT_THROTTLE_1; @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting long mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2; @VisibleForTesting volatile long mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2; @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting long mCompactThrottleFullSome = DEFAULT_COMPACT_THROTTLE_3; @VisibleForTesting volatile long mCompactThrottleFullSome = DEFAULT_COMPACT_THROTTLE_3; @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting long mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4; @VisibleForTesting volatile long mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4; @GuardedBy("mPhenotypeFlagLock") private boolean mUseCompaction = DEFAULT_USE_COMPACTION; private volatile boolean mUseCompaction = DEFAULT_USE_COMPACTION; private final Random mRandom = new Random(); @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting volatile float mStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE; // Handler on which compaction runs. private Handler mCompactionHandler; Loading Loading @@ -158,6 +168,7 @@ public final class AppCompactor { updateUseCompaction(); updateCompactionActions(); updateCompactionThrottles(); updateStatsdSampleRate(); } } Loading @@ -181,6 +192,7 @@ public final class AppCompactor { pw.println(" " + KEY_COMPACT_THROTTLE_2 + "=" + mCompactThrottleSomeFull); pw.println(" " + KEY_COMPACT_THROTTLE_3 + "=" + mCompactThrottleFullSome); pw.println(" " + KEY_COMPACT_THROTTLE_4 + "=" + mCompactThrottleFullFull); pw.println(" " + KEY_COMPACT_STATSD_SAMPLE_RATE + "=" + mStatsdSampleRate); } } Loading Loading @@ -289,6 +301,19 @@ public final class AppCompactor { } } @GuardedBy("mPhenotypeFlagLock") private void updateStatsdSampleRate() { String sampleRateFlag = DeviceConfig.getProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE); try { mStatsdSampleRate = TextUtils.isEmpty(sampleRateFlag) ? DEFAULT_STATSD_SAMPLE_RATE : Float.parseFloat(sampleRateFlag); } catch (NumberFormatException e) { mStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE; } mStatsdSampleRate = Math.min(1.0f, Math.max(0.0f, mStatsdSampleRate)); } @VisibleForTesting static String compactActionIntToString(int action) { switch(action) { Loading Loading @@ -385,11 +410,16 @@ public final class AppCompactor { rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3], rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], time, lastCompactAction, lastCompactTime, msg.arg1, msg.arg2); // Note that as above not taking mPhenoTypeFlagLock here to avoid locking // on every single compaction for a flag that will seldom change and the // impact of reading the wrong value here is low. if (mRandom.nextFloat() < mStatsdSampleRate) { StatsLog.write(StatsLog.APP_COMPACTED, pid, name, pendingAction, rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3], rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], time, lastCompactAction, lastCompactTime, msg.arg1, ActivityManager.processStateAmToProto(msg.arg2)); } synchronized (mAm) { proc.lastCompactTime = end; proc.lastCompactAction = pendingAction; Loading services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java +77 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.am; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_1; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_2; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_STATSD_SAMPLE_RATE; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_1; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_2; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_3; Loading Loading @@ -61,6 +62,9 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public final class AppCompactorTest { private static final String CLEAR_DEVICE_CONFIG_KEY_CMD = "device_config delete activity_manager"; @Mock private AppOpsService mAppOpsService; private AppCompactor mCompactorUnderTest; private HandlerThread mHandlerThread; Loading @@ -70,19 +74,21 @@ public final class AppCompactorTest { private static void clearDeviceConfig() throws IOException { UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_USE_COMPACTION); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_USE_COMPACTION); uiDevice.executeShellCommand( CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_ACTION_1); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_ACTION_1); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_ACTION_2); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_ACTION_2); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_1); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_1); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_2); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_2); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_3); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_3); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_4); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_4); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_STATSD_SAMPLE_RATE); } @Before Loading Loading @@ -128,6 +134,8 @@ public final class AppCompactorTest { is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3)); assertThat(mCompactorUnderTest.mCompactThrottleFullFull, is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4)); assertThat(mCompactorUnderTest.mStatsdSampleRate, is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE)); } @Test Loading Loading @@ -155,6 +163,9 @@ public final class AppCompactorTest { DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_THROTTLE_4, Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1), false); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false); // Then calling init will read and set that flag. mCompactorUnderTest.init(); Loading @@ -173,6 +184,8 @@ public final class AppCompactorTest { is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1)); assertThat(mCompactorUnderTest.mCompactThrottleFullFull, is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1)); assertThat(mCompactorUnderTest.mStatsdSampleRate, is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f)); } @Test Loading Loading @@ -365,6 +378,63 @@ public final class AppCompactorTest { is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4)); } @Test public void statsdSampleRate_listensToDeviceConfigChanges() throws InterruptedException { mCompactorUnderTest.init(); // When we override mStatsdSampleRate with a reasonable values ... mCountDown = new CountDownLatch(1); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); // Then that override is reflected in the compactor. assertThat(mCompactorUnderTest.mStatsdSampleRate, is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f)); } @Test public void statsdSanokeRate_listensToDeviceConfigChangesBadValues() throws InterruptedException { mCompactorUnderTest.init(); // When we override mStatsdSampleRate with a reasonable values ... mCountDown = new CountDownLatch(1); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, "foo", false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); // Then that override is reflected in the compactor. assertThat(mCompactorUnderTest.mStatsdSampleRate, is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE)); } @Test public void statsdSanokeRate_listensToDeviceConfigChangesOutOfRangeValues() throws InterruptedException { mCompactorUnderTest.init(); // When we override mStatsdSampleRate with an value outside of [0..1]... mCountDown = new CountDownLatch(1); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, Float.toString(-1.0f), false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); // Then the values is capped in the range. assertThat(mCompactorUnderTest.mStatsdSampleRate, is(0.0f)); mCountDown = new CountDownLatch(1); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, Float.toString(1.01f), false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); // Then the values is capped in the range. assertThat(mCompactorUnderTest.mStatsdSampleRate, is(1.0f)); } private class TestInjector extends Injector { @Override public AppOpsService getAppOpsService(File file, Handler handler) { Loading Loading
api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -5844,6 +5844,7 @@ package android.provider { public static interface DeviceConfig.ActivityManager { field public static final String KEY_COMPACT_ACTION_1 = "compact_action_1"; field public static final String KEY_COMPACT_ACTION_2 = "compact_action_2"; field public static final String KEY_COMPACT_STATSD_SAMPLE_RATE = "compact_statsd_sample_rate"; field public static final String KEY_COMPACT_THROTTLE_1 = "compact_throttle_1"; field public static final String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2"; field public static final String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3"; Loading
core/java/android/provider/DeviceConfig.java +1 −0 Original line number Diff line number Diff line Loading @@ -261,6 +261,7 @@ public final class DeviceConfig { String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2"; String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3"; String KEY_COMPACT_THROTTLE_4 = "compact_throttle_4"; String KEY_COMPACT_STATSD_SAMPLE_RATE = "compact_statsd_sample_rate"; /** * Maximum number of cached processes. See Loading
services/core/java/com/android/server/am/AppCompactor.java +42 −12 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.am; import static android.os.Process.THREAD_PRIORITY_FOREGROUND; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_1; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_2; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_STATSD_SAMPLE_RATE; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_1; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_2; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_3; Loading @@ -45,6 +46,7 @@ import com.android.server.ServiceThread; import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Random; public final class AppCompactor { Loading @@ -65,6 +67,8 @@ public final class AppCompactor { @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_2 = 10_000; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_3 = 500; @VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_4 = 10_000; // The sampling rate to push app compaction events into statsd for upload. @VisibleForTesting static final float DEFAULT_STATSD_SAMPLE_RATE = 0.1f; @VisibleForTesting interface PropertyChangedCallbackForTest { Loading Loading @@ -104,6 +108,8 @@ public final class AppCompactor { || KEY_COMPACT_THROTTLE_3.equals(name) || KEY_COMPACT_THROTTLE_4.equals(name)) { updateCompactionThrottles(); } else if (KEY_COMPACT_STATSD_SAMPLE_RATE.equals(name)) { updateStatsdSampleRate(); } } if (mTestCallback != null) { Loading @@ -116,21 +122,25 @@ public final class AppCompactor { // Configured by phenotype. Updates from the server take effect immediately. @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting String mCompactActionSome = @VisibleForTesting volatile String mCompactActionSome = compactActionIntToString(DEFAULT_COMPACT_ACTION_1); @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting String mCompactActionFull = @VisibleForTesting volatile String mCompactActionFull = compactActionIntToString(DEFAULT_COMPACT_ACTION_2); @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting long mCompactThrottleSomeSome = DEFAULT_COMPACT_THROTTLE_1; @VisibleForTesting volatile long mCompactThrottleSomeSome = DEFAULT_COMPACT_THROTTLE_1; @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting long mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2; @VisibleForTesting volatile long mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2; @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting long mCompactThrottleFullSome = DEFAULT_COMPACT_THROTTLE_3; @VisibleForTesting volatile long mCompactThrottleFullSome = DEFAULT_COMPACT_THROTTLE_3; @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting long mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4; @VisibleForTesting volatile long mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4; @GuardedBy("mPhenotypeFlagLock") private boolean mUseCompaction = DEFAULT_USE_COMPACTION; private volatile boolean mUseCompaction = DEFAULT_USE_COMPACTION; private final Random mRandom = new Random(); @GuardedBy("mPhenotypeFlagLock") @VisibleForTesting volatile float mStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE; // Handler on which compaction runs. private Handler mCompactionHandler; Loading Loading @@ -158,6 +168,7 @@ public final class AppCompactor { updateUseCompaction(); updateCompactionActions(); updateCompactionThrottles(); updateStatsdSampleRate(); } } Loading @@ -181,6 +192,7 @@ public final class AppCompactor { pw.println(" " + KEY_COMPACT_THROTTLE_2 + "=" + mCompactThrottleSomeFull); pw.println(" " + KEY_COMPACT_THROTTLE_3 + "=" + mCompactThrottleFullSome); pw.println(" " + KEY_COMPACT_THROTTLE_4 + "=" + mCompactThrottleFullFull); pw.println(" " + KEY_COMPACT_STATSD_SAMPLE_RATE + "=" + mStatsdSampleRate); } } Loading Loading @@ -289,6 +301,19 @@ public final class AppCompactor { } } @GuardedBy("mPhenotypeFlagLock") private void updateStatsdSampleRate() { String sampleRateFlag = DeviceConfig.getProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE); try { mStatsdSampleRate = TextUtils.isEmpty(sampleRateFlag) ? DEFAULT_STATSD_SAMPLE_RATE : Float.parseFloat(sampleRateFlag); } catch (NumberFormatException e) { mStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE; } mStatsdSampleRate = Math.min(1.0f, Math.max(0.0f, mStatsdSampleRate)); } @VisibleForTesting static String compactActionIntToString(int action) { switch(action) { Loading Loading @@ -385,11 +410,16 @@ public final class AppCompactor { rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3], rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], time, lastCompactAction, lastCompactTime, msg.arg1, msg.arg2); // Note that as above not taking mPhenoTypeFlagLock here to avoid locking // on every single compaction for a flag that will seldom change and the // impact of reading the wrong value here is low. if (mRandom.nextFloat() < mStatsdSampleRate) { StatsLog.write(StatsLog.APP_COMPACTED, pid, name, pendingAction, rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3], rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], time, lastCompactAction, lastCompactTime, msg.arg1, ActivityManager.processStateAmToProto(msg.arg2)); } synchronized (mAm) { proc.lastCompactTime = end; proc.lastCompactAction = pendingAction; Loading
services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java +77 −7 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.am; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_1; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_2; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_STATSD_SAMPLE_RATE; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_1; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_2; import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_3; Loading Loading @@ -61,6 +62,9 @@ import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public final class AppCompactorTest { private static final String CLEAR_DEVICE_CONFIG_KEY_CMD = "device_config delete activity_manager"; @Mock private AppOpsService mAppOpsService; private AppCompactor mCompactorUnderTest; private HandlerThread mHandlerThread; Loading @@ -70,19 +74,21 @@ public final class AppCompactorTest { private static void clearDeviceConfig() throws IOException { UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_USE_COMPACTION); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_USE_COMPACTION); uiDevice.executeShellCommand( CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_ACTION_1); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_ACTION_1); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_ACTION_2); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_ACTION_2); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_1); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_1); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_2); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_2); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_3); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_3); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_4); uiDevice.executeShellCommand( "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_4); CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_STATSD_SAMPLE_RATE); } @Before Loading Loading @@ -128,6 +134,8 @@ public final class AppCompactorTest { is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3)); assertThat(mCompactorUnderTest.mCompactThrottleFullFull, is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4)); assertThat(mCompactorUnderTest.mStatsdSampleRate, is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE)); } @Test Loading Loading @@ -155,6 +163,9 @@ public final class AppCompactorTest { DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_THROTTLE_4, Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1), false); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false); // Then calling init will read and set that flag. mCompactorUnderTest.init(); Loading @@ -173,6 +184,8 @@ public final class AppCompactorTest { is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1)); assertThat(mCompactorUnderTest.mCompactThrottleFullFull, is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1)); assertThat(mCompactorUnderTest.mStatsdSampleRate, is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f)); } @Test Loading Loading @@ -365,6 +378,63 @@ public final class AppCompactorTest { is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4)); } @Test public void statsdSampleRate_listensToDeviceConfigChanges() throws InterruptedException { mCompactorUnderTest.init(); // When we override mStatsdSampleRate with a reasonable values ... mCountDown = new CountDownLatch(1); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); // Then that override is reflected in the compactor. assertThat(mCompactorUnderTest.mStatsdSampleRate, is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f)); } @Test public void statsdSanokeRate_listensToDeviceConfigChangesBadValues() throws InterruptedException { mCompactorUnderTest.init(); // When we override mStatsdSampleRate with a reasonable values ... mCountDown = new CountDownLatch(1); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, "foo", false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); // Then that override is reflected in the compactor. assertThat(mCompactorUnderTest.mStatsdSampleRate, is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE)); } @Test public void statsdSanokeRate_listensToDeviceConfigChangesOutOfRangeValues() throws InterruptedException { mCompactorUnderTest.init(); // When we override mStatsdSampleRate with an value outside of [0..1]... mCountDown = new CountDownLatch(1); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, Float.toString(-1.0f), false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); // Then the values is capped in the range. assertThat(mCompactorUnderTest.mStatsdSampleRate, is(0.0f)); mCountDown = new CountDownLatch(1); DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE, KEY_COMPACT_STATSD_SAMPLE_RATE, Float.toString(1.01f), false); assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true)); // Then the values is capped in the range. assertThat(mCompactorUnderTest.mStatsdSampleRate, is(1.0f)); } private class TestInjector extends Injector { @Override public AppOpsService getAppOpsService(File file, Handler handler) { Loading