diff options
-rw-r--r-- | services/art-profile | 30 | ||||
-rw-r--r-- | services/art-profile-boot | 2 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 10 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/CachedAppOptimizer.java (renamed from services/core/java/com/android/server/am/AppCompactor.java) | 24 | ||||
-rw-r--r-- | services/core/java/com/android/server/am/OomAdjuster.java | 28 | ||||
-rw-r--r-- | services/core/jni/Android.bp | 2 | ||||
-rw-r--r-- | services/core/jni/com_android_server_am_CachedAppOptimizer.cpp (renamed from services/core/jni/com_android_server_am_AppCompactor.cpp) | 10 | ||||
-rw-r--r-- | services/core/jni/onload.cpp | 4 | ||||
-rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java | 680 | ||||
-rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java | 692 |
10 files changed, 747 insertions, 735 deletions
diff --git a/services/art-profile b/services/art-profile index a0338d55c55f..4e113c818c6c 100644 --- a/services/art-profile +++ b/services/art-profile @@ -3066,18 +3066,18 @@ HSPLcom/android/server/am/ActivityManagerShellCommand;->runSendBroadcast(Ljava/i HSPLcom/android/server/am/AppBindRecord;->dumpInIntentBind(Ljava/io/PrintWriter;Ljava/lang/String;)V PLcom/android/server/am/AppBindRecord;->toString()Ljava/lang/String; PLcom/android/server/am/AppBindRecord;->writeToProto(Landroid/util/proto/ProtoOutputStream;J)V -PLcom/android/server/am/AppCompactor$1;->onPropertyChanged(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V -HSPLcom/android/server/am/AppCompactor$MemCompactionHandler;->handleMessage(Landroid/os/Message;)V -HSPLcom/android/server/am/AppCompactor;-><init>(Lcom/android/server/am/ActivityManagerService;)V -HSPLcom/android/server/am/AppCompactor;->access$1000(Lcom/android/server/am/AppCompactor;)V -HSPLcom/android/server/am/AppCompactor;->access$700(Lcom/android/server/am/AppCompactor;)Lcom/android/server/am/ActivityManagerService; -HSPLcom/android/server/am/AppCompactor;->access$800(Lcom/android/server/am/AppCompactor;)Ljava/util/ArrayList; -HSPLcom/android/server/am/AppCompactor;->access$900(Lcom/android/server/am/AppCompactor;)Ljava/util/Random; -PLcom/android/server/am/AppCompactor;->dump(Ljava/io/PrintWriter;)V -HSPLcom/android/server/am/AppCompactor;->init()V -HSPLcom/android/server/am/AppCompactor;->updateCompactionThrottles()V -HSPLcom/android/server/am/AppCompactor;->updateUseCompaction()V -HSPLcom/android/server/am/AppCompactor;->useCompaction()Z +PLcom/android/server/am/CachedAppOptimizer$1;->onPropertyChanged(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V +HSPLcom/android/server/am/CachedAppOptimizer$MemCompactionHandler;->handleMessage(Landroid/os/Message;)V +HSPLcom/android/server/am/CachedAppOptimizer;-><init>(Lcom/android/server/am/ActivityManagerService;)V +HSPLcom/android/server/am/CachedAppOptimizer;->access$1000(Lcom/android/server/am/CachedAppOptimizer;)V +HSPLcom/android/server/am/CachedAppOptimizer;->access$700(Lcom/android/server/am/CachedAppOptimizer;)Lcom/android/server/am/ActivityManagerService; +HSPLcom/android/server/am/CachedAppOptimizer;->access$800(Lcom/android/server/am/CachedAppOptimizer;)Ljava/util/ArrayList; +HSPLcom/android/server/am/CachedAppOptimizer;->access$900(Lcom/android/server/am/CachedAppOptimizer;)Ljava/util/Random; +PLcom/android/server/am/CachedAppOptimizer;->dump(Ljava/io/PrintWriter;)V +HSPLcom/android/server/am/CachedAppOptimizer;->init()V +HSPLcom/android/server/am/CachedAppOptimizer;->updateCompactionThrottles()V +HSPLcom/android/server/am/CachedAppOptimizer;->updateUseCompaction()V +HSPLcom/android/server/am/CachedAppOptimizer;->useCompaction()Z PLcom/android/server/am/AppErrorDialog$1;->handleMessage(Landroid/os/Message;)V PLcom/android/server/am/AppErrorDialog;-><init>(Landroid/content/Context;Lcom/android/server/am/ActivityManagerService;Lcom/android/server/am/AppErrorDialog$Data;)V PLcom/android/server/am/AppErrorDialog;->onClick(Landroid/view/View;)V @@ -18632,9 +18632,9 @@ Lcom/android/server/am/ActivityManagerService$UiHandler; Lcom/android/server/am/ActivityManagerService$UidObserverRegistration; Lcom/android/server/am/ActivityManagerService; Lcom/android/server/am/AppBindRecord; -Lcom/android/server/am/AppCompactor$1; -Lcom/android/server/am/AppCompactor$MemCompactionHandler; -Lcom/android/server/am/AppCompactor; +Lcom/android/server/am/CachedAppOptimizer$1; +Lcom/android/server/am/CachedAppOptimizer$MemCompactionHandler; +Lcom/android/server/am/CachedAppOptimizer; Lcom/android/server/am/AppErrorDialog$Data; Lcom/android/server/am/AppErrorResult; Lcom/android/server/am/AppErrors$BadProcessInfo; diff --git a/services/art-profile-boot b/services/art-profile-boot index e09424bc261c..fe4178ac4a50 100644 --- a/services/art-profile-boot +++ b/services/art-profile-boot @@ -538,7 +538,7 @@ Lcom/android/server/wm/WindowProcessController;->setCurrentProcState(I)V Lcom/android/server/am/ActivityManagerService;->updateLowMemStateLocked(III)Z Lcom/android/server/wm/ConfigurationContainer;->getWindowConfiguration()Landroid/app/WindowConfiguration; Lcom/android/server/am/OomAdjuster;->applyOomAdjLocked(Lcom/android/server/am/ProcessRecord;ZJJ)Z -Lcom/android/server/am/AppCompactor;->useCompaction()Z +Lcom/android/server/am/CachedAppOptimizer;->useCompaction()Z Lcom/android/server/am/ProcessList;->procStatesDifferForMem(II)Z Lcom/android/server/am/ActivityManagerService;->dispatchUidsChanged()V Lcom/android/server/audio/AudioService$VolumeStreamState;->setIndex(IILjava/lang/String;)Z diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 8f6d981064de..f11083eda02b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2555,7 +2555,7 @@ public class ActivityManagerService extends IActivityManager.Stub Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(), Process.THREAD_GROUP_SYSTEM); Process.setThreadGroupAndCpuset( - mOomAdjuster.mAppCompact.mCompactionThread.getThreadId(), + mOomAdjuster.mCachedAppOptimizer.mCachedAppOptimizerThread.getThreadId(), Process.THREAD_GROUP_SYSTEM); } catch (Exception e) { Slog.w(TAG, "Setting background thread cpuset failed"); @@ -5304,7 +5304,7 @@ public class ActivityManagerService extends IActivityManager.Stub String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) { synchronized (ActivityManagerService.this) { - mOomAdjuster.mAppCompact.compactAllSystem(); + mOomAdjuster.mCachedAppOptimizer.compactAllSystem(); requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); } } @@ -9000,7 +9000,7 @@ public class ActivityManagerService extends IActivityManager.Stub final long timeSinceLastIdle = now - mLastIdleTime; // Compact all non-zygote processes to freshen up the page cache. - mOomAdjuster.mAppCompact.compactAllSystem(); + mOomAdjuster.mCachedAppOptimizer.compactAllSystem(); final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); mLastIdleTime = now; @@ -10020,7 +10020,7 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized(this) { mConstants.dump(pw); - mOomAdjuster.dumpAppCompactorSettings(pw); + mOomAdjuster.dumpCachedAppOptimizerSettings(pw); pw.println(); if (dumpAll) { pw.println("-------------------------------------------------------------------------------"); @@ -10425,7 +10425,7 @@ public class ActivityManagerService extends IActivityManager.Stub } else if ("settings".equals(cmd)) { synchronized (this) { mConstants.dump(pw); - mOomAdjuster.dumpAppCompactorSettings(pw); + mOomAdjuster.dumpCachedAppOptimizerSettings(pw); } } else if ("services".equals(cmd) || "s".equals(cmd)) { if (dumpClient) { diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index b7e206516640..3ca5ebce93f2 100644 --- a/services/core/java/com/android/server/am/AppCompactor.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -51,7 +51,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; -public final class AppCompactor { +public final class CachedAppOptimizer { // Flags stored in the DeviceConfig API. @VisibleForTesting static final String KEY_USE_COMPACTION = "use_compaction"; @@ -122,7 +122,7 @@ public final class AppCompactor { * that will wipe out the cpuset assignment for system_server threads. * Accordingly, this is in the AMS constructor. */ - final ServiceThread mCompactionThread; + final ServiceThread mCachedAppOptimizerThread; private final ArrayList<ProcessRecord> mPendingCompactionProcesses = new ArrayList<ProcessRecord>(); @@ -214,15 +214,15 @@ public final class AppCompactor { private int mPersistentCompactionCount; private int mBfgsCompactionCount; - public AppCompactor(ActivityManagerService am) { + public CachedAppOptimizer(ActivityManagerService am) { mAm = am; - mCompactionThread = new ServiceThread("CompactionThread", + mCachedAppOptimizerThread = new ServiceThread("CachedAppOptimizerThread", THREAD_PRIORITY_FOREGROUND, true); mProcStateThrottle = new HashSet<>(); } @VisibleForTesting - AppCompactor(ActivityManagerService am, PropertyChangedCallbackForTest callback) { + CachedAppOptimizer(ActivityManagerService am, PropertyChangedCallbackForTest callback) { this(am); mTestCallback = callback; } @@ -243,7 +243,7 @@ public final class AppCompactor { updateFullDeltaRssThrottle(); updateProcStateThrottle(); } - Process.setThreadGroupAndCpuset(mCompactionThread.getThreadId(), + Process.setThreadGroupAndCpuset(mCachedAppOptimizerThread.getThreadId(), Process.THREAD_GROUP_SYSTEM); } @@ -258,7 +258,7 @@ public final class AppCompactor { @GuardedBy("mAm") void dump(PrintWriter pw) { - pw.println("AppCompactor settings"); + pw.println("CachedAppOptimizer settings"); synchronized (mPhenotypeFlagLock) { pw.println(" " + KEY_USE_COMPACTION + "=" + mUseCompaction); pw.println(" " + KEY_COMPACT_ACTION_1 + "=" + mCompactActionSome); @@ -300,7 +300,7 @@ public final class AppCompactor { app.reqCompactAction = COMPACT_PROCESS_SOME; mPendingCompactionProcesses.add(app); mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( + mCompactionHandler.obtainMessage( COMPACT_PROCESS_MSG, app.setAdj, app.setProcState)); } @@ -309,7 +309,7 @@ public final class AppCompactor { app.reqCompactAction = COMPACT_PROCESS_FULL; mPendingCompactionProcesses.add(app); mCompactionHandler.sendMessage( - mCompactionHandler.obtainMessage( + mCompactionHandler.obtainMessage( COMPACT_PROCESS_MSG, app.setAdj, app.setProcState)); } @@ -362,8 +362,8 @@ public final class AppCompactor { private void updateUseCompaction() { mUseCompaction = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_USE_COMPACTION, DEFAULT_USE_COMPACTION); - if (mUseCompaction && !mCompactionThread.isAlive()) { - mCompactionThread.start(); + if (mUseCompaction && !mCachedAppOptimizerThread.isAlive()) { + mCachedAppOptimizerThread.start(); mCompactionHandler = new MemCompactionHandler(); } } @@ -521,7 +521,7 @@ public final class AppCompactor { private final class MemCompactionHandler extends Handler { private MemCompactionHandler() { - super(mCompactionThread.getLooper()); + super(mCachedAppOptimizerThread.getLooper()); } @Override diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 0fc885a2e61f..f86d6a70a076 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -122,9 +122,9 @@ public final class OomAdjuster { PowerManagerInternal mLocalPowerManager; /** - * Service for compacting background apps. + * Service for optimizing resource usage from background apps. */ - AppCompactor mAppCompact; + CachedAppOptimizer mCachedAppOptimizer; ActivityManagerConstants mConstants; @@ -197,7 +197,7 @@ public final class OomAdjuster { mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class); mConstants = mService.mConstants; - mAppCompact = new AppCompactor(mService); + mCachedAppOptimizer = new CachedAppOptimizer(mService); mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> { final int pid = msg.arg1; @@ -224,7 +224,7 @@ public final class OomAdjuster { } void initSettings() { - mAppCompact.init(); + mCachedAppOptimizer.init(); } /** @@ -1978,7 +1978,7 @@ public final class OomAdjuster { int changes = 0; // don't compact during bootup - if (mAppCompact.useCompaction() && mService.mBooted) { + if (mCachedAppOptimizer.useCompaction() && mService.mBooted) { // Cached and prev/home compaction if (app.curAdj != app.setAdj) { // Perform a minor compaction when a perceptible app becomes the prev/home app @@ -1987,26 +1987,26 @@ public final class OomAdjuster { if (app.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ && (app.curAdj == ProcessList.PREVIOUS_APP_ADJ || app.curAdj == ProcessList.HOME_APP_ADJ)) { - mAppCompact.compactAppSome(app); + mCachedAppOptimizer.compactAppSome(app); } else if ((app.setAdj < ProcessList.CACHED_APP_MIN_ADJ || app.setAdj > ProcessList.CACHED_APP_MAX_ADJ) && app.curAdj >= ProcessList.CACHED_APP_MIN_ADJ && app.curAdj <= ProcessList.CACHED_APP_MAX_ADJ) { - mAppCompact.compactAppFull(app); + mCachedAppOptimizer.compactAppFull(app); } } else if (mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE && app.setAdj < ProcessList.FOREGROUND_APP_ADJ // Because these can fire independent of oom_adj/procstate changes, we need // to throttle the actual dispatch of these requests in addition to the // processing of the requests. As a result, there is throttling both here - // and in AppCompactor. - && mAppCompact.shouldCompactPersistent(app, now)) { - mAppCompact.compactAppPersistent(app); + // and in CachedAppOptimizer. + && mCachedAppOptimizer.shouldCompactPersistent(app, now)) { + mCachedAppOptimizer.compactAppPersistent(app); } else if (mService.mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE && app.getCurProcState() == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE - && mAppCompact.shouldCompactBFGS(app, now)) { - mAppCompact.compactAppBfgs(app); + && mCachedAppOptimizer.shouldCompactBFGS(app, now)) { + mCachedAppOptimizer.compactAppBfgs(app); } } @@ -2439,7 +2439,7 @@ public final class OomAdjuster { } @GuardedBy("mService") - void dumpAppCompactorSettings(PrintWriter pw) { - mAppCompact.dump(pw); + void dumpCachedAppOptimizerSettings(PrintWriter pw) { + mCachedAppOptimizer.dump(pw); } } diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 03969b01f3f9..77d814e3076b 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -51,7 +51,7 @@ cc_library_static { "com_android_server_VibratorService.cpp", "com_android_server_PersistentDataBlockService.cpp", "com_android_server_GraphicsStatsService.cpp", - "com_android_server_am_AppCompactor.cpp", + "com_android_server_am_CachedAppOptimizer.cpp", "com_android_server_am_LowMemDetector.cpp", "com_android_server_incremental_IncrementalManagerService.cpp", "onload.cpp", diff --git a/services/core/jni/com_android_server_am_AppCompactor.cpp b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp index de6aa8b3266b..6a6da0e2b395 100644 --- a/services/core/jni/com_android_server_am_AppCompactor.cpp +++ b/services/core/jni/com_android_server_am_CachedAppOptimizer.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#define LOG_TAG "AppCompactor" +#define LOG_TAG "CachedAppOptimizer" //#define LOG_NDEBUG 0 #include <dirent.h> @@ -42,7 +42,7 @@ namespace android { // or potentially some mainline modules. The only process that should definitely // not be compacted is system_server, since compacting system_server around the // time of BOOT_COMPLETE could result in perceptible issues. -static void com_android_server_am_AppCompactor_compactSystem(JNIEnv *, jobject) { +static void com_android_server_am_CachedAppOptimizer_compactSystem(JNIEnv *, jobject) { std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir); struct dirent* current; while ((current = readdir(proc.get()))) { @@ -76,12 +76,12 @@ static void com_android_server_am_AppCompactor_compactSystem(JNIEnv *, jobject) static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ - {"compactSystem", "()V", (void*)com_android_server_am_AppCompactor_compactSystem}, + {"compactSystem", "()V", (void*)com_android_server_am_CachedAppOptimizer_compactSystem}, }; -int register_android_server_am_AppCompactor(JNIEnv* env) +int register_android_server_am_CachedAppOptimizer(JNIEnv* env) { - return jniRegisterNativeMethods(env, "com/android/server/am/AppCompactor", + return jniRegisterNativeMethods(env, "com/android/server/am/CachedAppOptimizer", sMethods, NELEM(sMethods)); } diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index c0a6e4e30f3a..19fa062bd9f9 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -54,7 +54,7 @@ int register_android_hardware_display_DisplayViewport(JNIEnv* env); int register_android_server_net_NetworkStatsFactory(JNIEnv* env); int register_android_server_net_NetworkStatsService(JNIEnv* env); int register_android_server_security_VerityUtils(JNIEnv* env); -int register_android_server_am_AppCompactor(JNIEnv* env); +int register_android_server_am_CachedAppOptimizer(JNIEnv* env); int register_android_server_am_LowMemDetector(JNIEnv* env); int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl( JNIEnv* env); @@ -106,7 +106,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_net_NetworkStatsFactory(env); register_android_server_net_NetworkStatsService(env); register_android_server_security_VerityUtils(env); - register_android_server_am_AppCompactor(env); + register_android_server_am_CachedAppOptimizer(env); register_android_server_am_LowMemDetector(env); register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl( env); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java deleted file mode 100644 index 48e459ff2d9d..000000000000 --- a/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java +++ /dev/null @@ -1,680 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.am; - -import static com.android.server.am.ActivityManagerService.Injector; -import static com.android.server.am.AppCompactor.compactActionIntToString; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Process; -import android.platform.test.annotations.Presubmit; -import android.provider.DeviceConfig; -import android.text.TextUtils; - -import androidx.test.platform.app.InstrumentationRegistry; - -import com.android.server.ServiceThread; -import com.android.server.appop.AppOpsService; -import com.android.server.testables.TestableDeviceConfig; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import java.io.File; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * Tests for {@link AppCompactor}. - * - * Build/Install/Run: - * atest FrameworksMockingServicesTests:AppCompactorTest - */ -@Presubmit -@RunWith(MockitoJUnitRunner.class) -public final class AppCompactorTest { - - private ServiceThread mThread; - - @Mock - private AppOpsService mAppOpsService; - private AppCompactor mCompactorUnderTest; - private HandlerThread mHandlerThread; - private Handler mHandler; - private CountDownLatch mCountDown; - - @Rule - public TestableDeviceConfig.TestableDeviceConfigRule - mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule(); - - @Before - public void setUp() { - mHandlerThread = new HandlerThread(""); - mHandlerThread.start(); - mHandler = new Handler(mHandlerThread.getLooper()); - - mThread = new ServiceThread("TestServiceThread", Process.THREAD_PRIORITY_DEFAULT, - true /* allowIo */); - mThread.start(); - - ActivityManagerService ams = new ActivityManagerService( - new TestInjector(InstrumentationRegistry.getInstrumentation().getContext()), - mThread); - mCompactorUnderTest = new AppCompactor(ams, - new AppCompactor.PropertyChangedCallbackForTest() { - @Override - public void onPropertyChanged() { - if (mCountDown != null) { - mCountDown.countDown(); - } - } - }); - } - - @After - public void tearDown() { - mHandlerThread.quit(); - mThread.quit(); - mCountDown = null; - } - - @Test - public void init_setsDefaults() { - mCompactorUnderTest.init(); - assertThat(mCompactorUnderTest.useCompaction()).isEqualTo( - AppCompactor.DEFAULT_USE_COMPACTION); - assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo( - compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_1)); - assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo( - compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_2)); - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4); - assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo( - AppCompactor.DEFAULT_STATSD_SAMPLE_RATE); - assertThat(mCompactorUnderTest.mFullAnonRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6); - assertThat(mCompactorUnderTest.mFullAnonRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB); - assertThat(mCompactorUnderTest.mFullDeltaRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB); - - Set<Integer> expected = new HashSet<>(); - for (String s : TextUtils.split(AppCompactor.DEFAULT_COMPACT_PROC_STATE_THROTTLE, ",")) { - expected.add(Integer.parseInt(s)); - } - assertThat(mCompactorUnderTest.mProcStateThrottle).containsExactlyElementsIn(expected); - } - - @Test - public void init_withDeviceConfigSetsParameters() { - // When the DeviceConfig already has a flag value stored (note this test will need to - // change if the default value changes from false). - assertThat(AppCompactor.DEFAULT_USE_COMPACTION).isFalse(); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_USE_COMPACTION, "true", false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_ACTION_1, - Integer.toString((AppCompactor.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_ACTION_2, - Integer.toString((AppCompactor.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_1, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_2, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_2 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_3, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_4, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_5, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_6, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_STATSD_SAMPLE_RATE, - Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_FULL_RSS_THROTTLE_KB, - Long.toString(AppCompactor.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB, - Long.toString(AppCompactor.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_PROC_STATE_THROTTLE, "1,2,3", false); - - // Then calling init will read and set that flag. - mCompactorUnderTest.init(); - assertThat(mCompactorUnderTest.useCompaction()).isTrue(); - assertThat(mCompactorUnderTest.mCompactionThread.isAlive()).isTrue(); - - assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo( - compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1)); - assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo( - compactActionIntToString((AppCompactor.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1)); - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2 + 1); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1); - assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo( - AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1); - assertThat(mCompactorUnderTest.mFullAnonRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1); - assertThat(mCompactorUnderTest.mProcStateThrottle).containsExactly(1, 2, 3); - } - - @Test - public void useCompaction_listensToDeviceConfigChanges() throws InterruptedException { - assertThat(mCompactorUnderTest.useCompaction()).isEqualTo( - AppCompactor.DEFAULT_USE_COMPACTION); - // When we call init and change some the flag value... - mCompactorUnderTest.init(); - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_USE_COMPACTION, "true", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that new flag value is updated in the implementation. - assertThat(mCompactorUnderTest.useCompaction()).isTrue(); - assertThat(mCompactorUnderTest.mCompactionThread.isAlive()).isTrue(); - - // And again, setting the flag the other way. - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_USE_COMPACTION, "false", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.useCompaction()).isFalse(); - } - - @Test - public void useCompaction_listensToDeviceConfigChangesBadValues() throws InterruptedException { - assertThat(mCompactorUnderTest.useCompaction()).isEqualTo( - AppCompactor.DEFAULT_USE_COMPACTION); - mCompactorUnderTest.init(); - - // When we push an invalid flag value... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_USE_COMPACTION, "foobar", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then we set the default. - assertThat(mCompactorUnderTest.useCompaction()).isEqualTo( - AppCompactor.DEFAULT_USE_COMPACTION); - } - - @Test - public void compactAction_listensToDeviceConfigChanges() throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override new values for the compaction action with reasonable values... - - // There are four possible values for compactAction[Some|Full]. - for (int i = 1; i < 5; i++) { - mCountDown = new CountDownLatch(2); - int expectedSome = (AppCompactor.DEFAULT_COMPACT_ACTION_1 + i) % 4 + 1; - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_ACTION_1, Integer.toString(expectedSome), false); - int expectedFull = (AppCompactor.DEFAULT_COMPACT_ACTION_2 + i) % 4 + 1; - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_ACTION_2, Integer.toString(expectedFull), false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then the updates are reflected in the flags. - assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo( - compactActionIntToString(expectedSome)); - assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo( - compactActionIntToString(expectedFull)); - } - } - - @Test - public void compactAction_listensToDeviceConfigChangesBadValues() throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override new values for the compaction action with bad values ... - mCountDown = new CountDownLatch(2); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_ACTION_1, "foo", false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_ACTION_2, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then the default values are reflected in the flag - assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo( - compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_1)); - assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo( - compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_2)); - - mCountDown = new CountDownLatch(2); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_ACTION_1, "", false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_ACTION_2, "", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - assertThat(mCompactorUnderTest.mCompactActionSome).isEqualTo( - compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_1)); - assertThat(mCompactorUnderTest.mCompactActionFull).isEqualTo( - compactActionIntToString(AppCompactor.DEFAULT_COMPACT_ACTION_2)); - } - - @Test - public void compactThrottle_listensToDeviceConfigChanges() throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override new reasonable throttle values after init... - mCountDown = new CountDownLatch(6); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_1, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_2, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_2 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_3, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_4, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_5, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1), false); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_6, - Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1), false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then those flags values are reflected in the compactor. - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1 + 1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2 + 1); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5 + 1); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6 + 1); - } - - @Test - public void compactThrottle_listensToDeviceConfigChangesBadValues() - throws InterruptedException { - mCompactorUnderTest.init(); - - // When one of the throttles is overridden with a bad value... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_1, "foo", false); - // Then all the throttles have the defaults set. - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6); - - // Repeat for each of the throttle keys. - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_2, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6); - - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_3, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6); - - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_4, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6); - - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_5, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6); - - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_THROTTLE_6, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mCompactThrottleSomeSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_1); - assertThat(mCompactorUnderTest.mCompactThrottleSomeFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_2); - assertThat(mCompactorUnderTest.mCompactThrottleFullSome).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_3); - assertThat(mCompactorUnderTest.mCompactThrottleFullFull).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_4); - assertThat(mCompactorUnderTest.mCompactThrottleBFGS).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_5); - assertThat(mCompactorUnderTest.mCompactThrottlePersistent).isEqualTo( - AppCompactor.DEFAULT_COMPACT_THROTTLE_6); - } - - @Test - public void statsdSampleRate_listensToDeviceConfigChanges() throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override mStatsdSampleRate with a reasonable value ... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_STATSD_SAMPLE_RATE, - Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that override is reflected in the compactor. - assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo( - AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f); - } - - @Test - public void statsdSampleRate_listensToDeviceConfigChangesBadValues() - throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override mStatsdSampleRate with an unreasonable value ... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_STATSD_SAMPLE_RATE, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that override is reflected in the compactor. - assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo( - AppCompactor.DEFAULT_STATSD_SAMPLE_RATE); - } - - @Test - public void statsdSampleRate_listensToDeviceConfigChangesOutOfRangeValues() - throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override mStatsdSampleRate with an value outside of [0..1]... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_STATSD_SAMPLE_RATE, - Float.toString(-1.0f), false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then the values is capped in the range. - assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(0.0f); - - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_STATSD_SAMPLE_RATE, - Float.toString(1.01f), false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then the values is capped in the range. - assertThat(mCompactorUnderTest.mStatsdSampleRate).isEqualTo(1.0f); - } - - @Test - public void fullCompactionRssThrottleKb_listensToDeviceConfigChanges() - throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override mStatsdSampleRate with a reasonable value ... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_FULL_RSS_THROTTLE_KB, - Long.toString(AppCompactor.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1), false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that override is reflected in the compactor. - assertThat(mCompactorUnderTest.mFullAnonRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1); - } - - @Test - public void fullCompactionRssThrottleKb_listensToDeviceConfigChangesBadValues() - throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override mStatsdSampleRate with an unreasonable value ... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_FULL_RSS_THROTTLE_KB, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that override is reflected in the compactor. - assertThat(mCompactorUnderTest.mFullAnonRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB); - - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_FULL_RSS_THROTTLE_KB, "-100", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that override is reflected in the compactor. - assertThat(mCompactorUnderTest.mFullAnonRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB); - } - - @Test - public void fullCompactionDeltaRssThrottleKb_listensToDeviceConfigChanges() - throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override mStatsdSampleRate with a reasonable value ... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB, - Long.toString(AppCompactor.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB + 1), false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that override is reflected in the compactor. - assertThat(mCompactorUnderTest.mFullDeltaRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB + 1); - } - - @Test - public void fullCompactionDeltaRssThrottleKb_listensToDeviceConfigChangesBadValues() - throws InterruptedException { - mCompactorUnderTest.init(); - - // When we override mStatsdSampleRate with an unreasonable value ... - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that override is reflected in the compactor. - assertThat(mCompactorUnderTest.mFullDeltaRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB); - - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB, "-100", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - - // Then that override is reflected in the compactor. - assertThat(mCompactorUnderTest.mFullDeltaRssThrottleKb).isEqualTo( - AppCompactor.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB); - } - - @Test - public void procStateThrottle_listensToDeviceConfigChanges() - throws InterruptedException { - mCompactorUnderTest.init(); - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_PROC_STATE_THROTTLE, "1,2,3", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mProcStateThrottle).containsExactly(1, 2, 3); - - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_PROC_STATE_THROTTLE, "", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mProcStateThrottle).isEmpty(); - } - - @Test - public void procStateThrottle_listensToDeviceConfigChangesBadValues() - throws InterruptedException { - mCompactorUnderTest.init(); - - Set<Integer> expected = new HashSet<>(); - for (String s : TextUtils.split(AppCompactor.DEFAULT_COMPACT_PROC_STATE_THROTTLE, ",")) { - expected.add(Integer.parseInt(s)); - } - - // Not numbers - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_PROC_STATE_THROTTLE, "foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mProcStateThrottle).containsExactlyElementsIn(expected); - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_PROC_STATE_THROTTLE, "1,foo", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mProcStateThrottle).containsExactlyElementsIn(expected); - - // Empty splits - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_PROC_STATE_THROTTLE, ",", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mProcStateThrottle).containsExactlyElementsIn(expected); - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_PROC_STATE_THROTTLE, ",,3", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mProcStateThrottle).containsExactlyElementsIn(expected); - mCountDown = new CountDownLatch(1); - DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, - AppCompactor.KEY_COMPACT_PROC_STATE_THROTTLE, "1,,3", false); - assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); - assertThat(mCompactorUnderTest.mProcStateThrottle).containsExactlyElementsIn(expected); - } - - private class TestInjector extends Injector { - - TestInjector(Context context) { - super(context); - } - - @Override - public AppOpsService getAppOpsService(File file, Handler handler) { - return mAppOpsService; - } - - @Override - public Handler getUiHandler(ActivityManagerService service) { - return mHandler; - } - } -} diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java new file mode 100644 index 000000000000..f037692886ab --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/am/CachedAppOptimizerTest.java @@ -0,0 +1,692 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.am; + +import static com.android.server.am.ActivityManagerService.Injector; +import static com.android.server.am.CachedAppOptimizer.compactActionIntToString; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Process; +import android.platform.test.annotations.Presubmit; +import android.provider.DeviceConfig; +import android.text.TextUtils; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.server.ServiceThread; +import com.android.server.appop.AppOpsService; +import com.android.server.testables.TestableDeviceConfig; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * Tests for {@link CachedAppOptimizer}. + * + * Build/Install/Run: + * atest FrameworksMockingServicesTests:CachedAppOptimizerTest + */ +@Presubmit +@RunWith(MockitoJUnitRunner.class) +public final class CachedAppOptimizerTest { + + private ServiceThread mThread; + + @Mock + private AppOpsService mAppOpsService; + private CachedAppOptimizer mCachedAppOptimizerUnderTest; + private HandlerThread mHandlerThread; + private Handler mHandler; + private CountDownLatch mCountDown; + + @Rule + public TestableDeviceConfig.TestableDeviceConfigRule + mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule(); + + @Before + public void setUp() { + mHandlerThread = new HandlerThread(""); + mHandlerThread.start(); + mHandler = new Handler(mHandlerThread.getLooper()); + + mThread = new ServiceThread("TestServiceThread", Process.THREAD_PRIORITY_DEFAULT, + true /* allowIo */); + mThread.start(); + + ActivityManagerService ams = new ActivityManagerService( + new TestInjector(InstrumentationRegistry.getInstrumentation().getContext()), + mThread); + mCachedAppOptimizerUnderTest = new CachedAppOptimizer(ams, + new CachedAppOptimizer.PropertyChangedCallbackForTest() { + @Override + public void onPropertyChanged() { + if (mCountDown != null) { + mCountDown.countDown(); + } + } + }); + } + + @After + public void tearDown() { + mHandlerThread.quit(); + mThread.quit(); + mCountDown = null; + } + + @Test + public void init_setsDefaults() { + mCachedAppOptimizerUnderTest.init(); + assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isEqualTo( + CachedAppOptimizer.DEFAULT_USE_COMPACTION); + assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome).isEqualTo( + compactActionIntToString(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1)); + assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull).isEqualTo( + compactActionIntToString(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2)); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4); + assertThat(mCachedAppOptimizerUnderTest.mStatsdSampleRate).isEqualTo( + CachedAppOptimizer.DEFAULT_STATSD_SAMPLE_RATE); + assertThat(mCachedAppOptimizerUnderTest.mFullAnonRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6); + assertThat(mCachedAppOptimizerUnderTest.mFullAnonRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB); + assertThat(mCachedAppOptimizerUnderTest.mFullDeltaRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB); + + Set<Integer> expected = new HashSet<>(); + for (String s : TextUtils.split( + CachedAppOptimizer.DEFAULT_COMPACT_PROC_STATE_THROTTLE, ",")) { + expected.add(Integer.parseInt(s)); + } + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle) + .containsExactlyElementsIn(expected); + } + + @Test + public void init_withDeviceConfigSetsParameters() { + // When the DeviceConfig already has a flag value stored (note this test will need to + // change if the default value changes from false). + assertThat(CachedAppOptimizer.DEFAULT_USE_COMPACTION).isFalse(); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_USE_COMPACTION, "true", false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_ACTION_1, + Integer.toString((CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_ACTION_2, + Integer.toString((CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_1, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_2, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_3, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_4, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_5, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_6, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_STATSD_SAMPLE_RATE, + Float.toString(CachedAppOptimizer.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_FULL_RSS_THROTTLE_KB, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB, + Long.toString( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_PROC_STATE_THROTTLE, "1,2,3", false); + + // Then calling init will read and set that flag. + mCachedAppOptimizerUnderTest.init(); + assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mCachedAppOptimizerThread.isAlive()).isTrue(); + + assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome).isEqualTo( + compactActionIntToString( + (CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1 + 1 % 4) + 1)); + assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull).isEqualTo( + compactActionIntToString( + (CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2 + 1 % 4) + 1)); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6 + 1); + assertThat(mCachedAppOptimizerUnderTest.mStatsdSampleRate).isEqualTo( + CachedAppOptimizer.DEFAULT_STATSD_SAMPLE_RATE + 0.1f); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6 + 1); + assertThat(mCachedAppOptimizerUnderTest.mFullAnonRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1); + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle).containsExactly(1, 2, 3); + } + + @Test + public void useCompaction_listensToDeviceConfigChanges() throws InterruptedException { + assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isEqualTo( + CachedAppOptimizer.DEFAULT_USE_COMPACTION); + // When we call init and change some the flag value... + mCachedAppOptimizerUnderTest.init(); + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_USE_COMPACTION, "true", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that new flag value is updated in the implementation. + assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mCachedAppOptimizerThread.isAlive()).isTrue(); + + // And again, setting the flag the other way. + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_USE_COMPACTION, "false", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isFalse(); + } + + @Test + public void useCompaction_listensToDeviceConfigChangesBadValues() throws InterruptedException { + assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isEqualTo( + CachedAppOptimizer.DEFAULT_USE_COMPACTION); + mCachedAppOptimizerUnderTest.init(); + + // When we push an invalid flag value... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_USE_COMPACTION, "foobar", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then we set the default. + assertThat(mCachedAppOptimizerUnderTest.useCompaction()).isEqualTo( + CachedAppOptimizer.DEFAULT_USE_COMPACTION); + } + + @Test + public void compactAction_listensToDeviceConfigChanges() throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override new values for the compaction action with reasonable values... + + // There are four possible values for compactAction[Some|Full]. + for (int i = 1; i < 5; i++) { + mCountDown = new CountDownLatch(2); + int expectedSome = (CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1 + i) % 4 + 1; + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_ACTION_1, Integer.toString(expectedSome), false); + int expectedFull = (CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2 + i) % 4 + 1; + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_ACTION_2, Integer.toString(expectedFull), false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then the updates are reflected in the flags. + assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome).isEqualTo( + compactActionIntToString(expectedSome)); + assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull).isEqualTo( + compactActionIntToString(expectedFull)); + } + } + + @Test + public void compactAction_listensToDeviceConfigChangesBadValues() throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override new values for the compaction action with bad values ... + mCountDown = new CountDownLatch(2); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_ACTION_1, "foo", false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_ACTION_2, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then the default values are reflected in the flag + assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome).isEqualTo( + compactActionIntToString(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1)); + assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull).isEqualTo( + compactActionIntToString(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2)); + + mCountDown = new CountDownLatch(2); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_ACTION_1, "", false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_ACTION_2, "", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + assertThat(mCachedAppOptimizerUnderTest.mCompactActionSome).isEqualTo( + compactActionIntToString(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_1)); + assertThat(mCachedAppOptimizerUnderTest.mCompactActionFull).isEqualTo( + compactActionIntToString(CachedAppOptimizer.DEFAULT_COMPACT_ACTION_2)); + } + + @Test + public void compactThrottle_listensToDeviceConfigChanges() throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override new reasonable throttle values after init... + mCountDown = new CountDownLatch(6); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_1, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_2, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_3, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_4, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_5, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5 + 1), false); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_6, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6 + 1), false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then those flags values are reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5 + 1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6 + 1); + } + + @Test + public void compactThrottle_listensToDeviceConfigChangesBadValues() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When one of the throttles is overridden with a bad value... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_1, "foo", false); + // Then all the throttles have the defaults set. + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6); + + // Repeat for each of the throttle keys. + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_2, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6); + + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_3, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6); + + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_4, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6); + + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_5, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6); + + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_THROTTLE_6, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_1); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleSomeFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_2); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullSome).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_3); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleFullFull).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_4); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottleBFGS).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_5); + assertThat(mCachedAppOptimizerUnderTest.mCompactThrottlePersistent).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_THROTTLE_6); + } + + @Test + public void statsdSampleRate_listensToDeviceConfigChanges() throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override mStatsdSampleRate with a reasonable value ... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_STATSD_SAMPLE_RATE, + Float.toString(CachedAppOptimizer.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that override is reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mStatsdSampleRate).isEqualTo( + CachedAppOptimizer.DEFAULT_STATSD_SAMPLE_RATE + 0.1f); + } + + @Test + public void statsdSampleRate_listensToDeviceConfigChangesBadValues() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override mStatsdSampleRate with an unreasonable value ... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_STATSD_SAMPLE_RATE, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that override is reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mStatsdSampleRate).isEqualTo( + CachedAppOptimizer.DEFAULT_STATSD_SAMPLE_RATE); + } + + @Test + public void statsdSampleRate_listensToDeviceConfigChangesOutOfRangeValues() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override mStatsdSampleRate with an value outside of [0..1]... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_STATSD_SAMPLE_RATE, + Float.toString(-1.0f), false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then the values is capped in the range. + assertThat(mCachedAppOptimizerUnderTest.mStatsdSampleRate).isEqualTo(0.0f); + + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_STATSD_SAMPLE_RATE, + Float.toString(1.01f), false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then the values is capped in the range. + assertThat(mCachedAppOptimizerUnderTest.mStatsdSampleRate).isEqualTo(1.0f); + } + + @Test + public void fullCompactionRssThrottleKb_listensToDeviceConfigChanges() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override mStatsdSampleRate with a reasonable value ... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_FULL_RSS_THROTTLE_KB, + Long.toString(CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1), false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that override is reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mFullAnonRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB + 1); + } + + @Test + public void fullCompactionRssThrottleKb_listensToDeviceConfigChangesBadValues() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override mStatsdSampleRate with an unreasonable value ... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_FULL_RSS_THROTTLE_KB, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that override is reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mFullAnonRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB); + + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_FULL_RSS_THROTTLE_KB, "-100", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that override is reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mFullAnonRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_RSS_THROTTLE_KB); + } + + @Test + public void fullCompactionDeltaRssThrottleKb_listensToDeviceConfigChanges() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override mStatsdSampleRate with a reasonable value ... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB, + Long.toString( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB + 1), false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that override is reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mFullDeltaRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB + 1); + } + + @Test + public void fullCompactionDeltaRssThrottleKb_listensToDeviceConfigChangesBadValues() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + // When we override mStatsdSampleRate with an unreasonable value ... + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that override is reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mFullDeltaRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB); + + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_FULL_DELTA_RSS_THROTTLE_KB, "-100", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + + // Then that override is reflected in the compactor. + assertThat(mCachedAppOptimizerUnderTest.mFullDeltaRssThrottleKb).isEqualTo( + CachedAppOptimizer.DEFAULT_COMPACT_FULL_DELTA_RSS_THROTTLE_KB); + } + + @Test + public void procStateThrottle_listensToDeviceConfigChanges() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_PROC_STATE_THROTTLE, "1,2,3", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle).containsExactly(1, 2, 3); + + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_PROC_STATE_THROTTLE, "", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle).isEmpty(); + } + + @Test + public void procStateThrottle_listensToDeviceConfigChangesBadValues() + throws InterruptedException { + mCachedAppOptimizerUnderTest.init(); + + Set<Integer> expected = new HashSet<>(); + for (String s : TextUtils.split( + CachedAppOptimizer.DEFAULT_COMPACT_PROC_STATE_THROTTLE, ",")) { + expected.add(Integer.parseInt(s)); + } + + // Not numbers + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_PROC_STATE_THROTTLE, "foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle) + .containsExactlyElementsIn(expected); + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_PROC_STATE_THROTTLE, "1,foo", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle) + .containsExactlyElementsIn(expected); + + // Empty splits + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_PROC_STATE_THROTTLE, ",", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle) + .containsExactlyElementsIn(expected); + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_PROC_STATE_THROTTLE, ",,3", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle) + .containsExactlyElementsIn(expected); + mCountDown = new CountDownLatch(1); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, + CachedAppOptimizer.KEY_COMPACT_PROC_STATE_THROTTLE, "1,,3", false); + assertThat(mCountDown.await(5, TimeUnit.SECONDS)).isTrue(); + assertThat(mCachedAppOptimizerUnderTest.mProcStateThrottle) + .containsExactlyElementsIn(expected); + } + + private class TestInjector extends Injector { + + TestInjector(Context context) { + super(context); + } + + @Override + public AppOpsService getAppOpsService(File file, Handler handler) { + return mAppOpsService; + } + + @Override + public Handler getUiHandler(ActivityManagerService service) { + return mHandler; + } + } +} |