Loading services/core/java/com/android/server/am/ActivityManagerService.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -543,7 +543,7 @@ public class ActivityManagerService extends IActivityManager.Stub private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds; private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds; final OomAdjuster mOomAdjuster; OomAdjuster mOomAdjuster; final LowMemDetector mLowMemDetector; final LowMemDetector mLowMemDetector; /** All system services */ /** All system services */ Loading Loading @@ -1483,7 +1483,7 @@ public class ActivityManagerService extends IActivityManager.Stub final ServiceThread mProcStartHandlerThread; final ServiceThread mProcStartHandlerThread; final Handler mProcStartHandler; final Handler mProcStartHandler; final ActivityManagerConstants mConstants; ActivityManagerConstants mConstants; // Encapsulates the global setting "hidden_api_blacklist_exemptions" // Encapsulates the global setting "hidden_api_blacklist_exemptions" final HiddenApiSettings mHiddenApiBlacklist; final HiddenApiSettings mHiddenApiBlacklist; Loading services/core/java/com/android/server/am/OomAdjuster.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -75,6 +75,7 @@ import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.procstats.ProcessStats; import com.android.internal.app.procstats.ProcessStats; import com.android.server.LocalServices; import com.android.server.LocalServices; import com.android.server.wm.ActivityServiceConnectionsHolder; import com.android.server.wm.ActivityServiceConnectionsHolder; Loading Loading @@ -1897,6 +1898,10 @@ public final class OomAdjuster { // For apps that sit around for a long time in the interactive state, we need // For apps that sit around for a long time in the interactive state, we need // to report this at least once a day so they don't go idle. // to report this at least once a day so they don't go idle. maybeUpdateUsageStatsLocked(app, nowElapsed); maybeUpdateUsageStatsLocked(app, nowElapsed); } else if (!app.reportedInteraction && (nowElapsed - app.getFgInteractionTime()) > mConstants.SERVICE_USAGE_INTERACTION_TIME) { // For foreground services that sit around for a long time but are not interacted with. maybeUpdateUsageStatsLocked(app, nowElapsed); } } if (changes != 0) { if (changes != 0) { Loading @@ -1917,6 +1922,14 @@ public final class OomAdjuster { return success; return success; } } // ONLY used for unit testing in OomAdjusterTests.java @VisibleForTesting void maybeUpdateUsageStats(ProcessRecord app, long nowElapsed) { synchronized (mService) { maybeUpdateUsageStatsLocked(app, nowElapsed); } } @GuardedBy("mService") @GuardedBy("mService") private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) { private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) { if (DEBUG_USAGE_STATS) { if (DEBUG_USAGE_STATS) { Loading services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java 0 → 100644 +255 −0 Original line number Original line Diff line number Diff line /* * 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 android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import android.app.ActivityManager; import android.app.usage.UsageStatsManagerInternal; import android.content.Context; import com.android.server.LocalServices; import com.android.server.wm.ActivityTaskManagerService; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * Test class for {@link OomAdjuster}. * * Build/Install/Run: * atest FrameworksServicesTests:OomAdjusterTests */ public class OomAdjusterTests { private static Context sContext; private static ActivityManagerService sService; private ProcessRecord mProcessRecord; private static final long ZERO = 0L; private static final long USAGE_STATS_INTERACTION = 2 * 60 * 60 * 1000L; private static final long SERVICE_USAGE_INTERACTION = 30 * 60 * 1000; @BeforeClass public static void setUpOnce() { sContext = getInstrumentation().getTargetContext(); // We need to run with dexmaker share class loader to make use of // ActivityTaskManagerService from wm package. runWithDexmakerShareClassLoader(() -> { sService = mock(ActivityManagerService.class); sService.mActivityTaskManager = new ActivityTaskManagerService(sContext); sService.mActivityTaskManager.initialize(null, null, sContext.getMainLooper()); sService.mAtmInternal = sService.mActivityTaskManager.getAtmInternal(); sService.mConstants = new ActivityManagerConstants(sContext, sService, sContext.getMainThreadHandler()); sService.mOomAdjuster = new OomAdjuster(sService, sService.mProcessList, null); LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); LocalServices.addService(UsageStatsManagerInternal.class, mock(UsageStatsManagerInternal.class)); sService.mUsageStatsService = LocalServices.getService(UsageStatsManagerInternal.class); }); } @Before public void setUpProcess() { // Need to run with dexmaker share class loader to mock package private class. runWithDexmakerShareClassLoader(() -> { mProcessRecord = spy(new ProcessRecord(sService, sContext.getApplicationInfo(), "name", 12345)); }); // Ensure certain services and constants are defined properly assertNotNull(sService.mUsageStatsService); assertEquals(USAGE_STATS_INTERACTION, sService.mConstants.USAGE_STATS_INTERACTION_INTERVAL); assertEquals(SERVICE_USAGE_INTERACTION, sService.mConstants.SERVICE_USAGE_INTERACTION_TIME); } @Test public void testMaybeUpdateUsageStats_ProcStatePersistentUI() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateTop() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_TOP); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateTop_PreviousInteraction() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_TOP); mProcessRecord.reportedInteraction = true; sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateTop_PastUsageInterval() { final long elapsedTime = 3 * USAGE_STATS_INTERACTION; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_TOP); mProcessRecord.reportedInteraction = true; sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateBoundTop() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_BOUND_TOP); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateFGS() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(elapsedTime, false, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateFGS_ShortInteraction() { final long elapsedTime = ZERO; final long fgInteractionTime = 1000L; mProcessRecord.setFgInteractionTime(fgInteractionTime); mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(fgInteractionTime, false, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateFGS_LongInteraction() { final long elapsedTime = 2 * SERVICE_USAGE_INTERACTION; final long fgInteractionTime = 1000L; mProcessRecord.setFgInteractionTime(fgInteractionTime); mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(fgInteractionTime, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateFGS_PreviousLongInteraction() { final long elapsedTime = 2 * SERVICE_USAGE_INTERACTION; final long fgInteractionTime = 1000L; mProcessRecord.setFgInteractionTime(fgInteractionTime); mProcessRecord.reportedInteraction = true; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(fgInteractionTime, true, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateFGSLocation() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(elapsedTime, false, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateBFGS() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateImportantFG() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateImportantFG_PreviousInteraction() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); mProcessRecord.reportedInteraction = true; sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateImportantFG_PastUsageInterval() { final long elapsedTime = 3 * USAGE_STATS_INTERACTION; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); mProcessRecord.reportedInteraction = true; sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateImportantBG() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, false, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateService() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, false, ZERO); } private void assertProcessRecordState(long fgInteractionTime, boolean reportedInteraction, long interactionEventTime) { assertEquals("Foreground interaction time was not updated correctly.", fgInteractionTime, mProcessRecord.getFgInteractionTime()); assertEquals("Interaction was not updated correctly.", reportedInteraction, mProcessRecord.reportedInteraction); assertEquals("Interaction event time was not updated correctly.", interactionEventTime, mProcessRecord.getInteractionEventTime()); } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -543,7 +543,7 @@ public class ActivityManagerService extends IActivityManager.Stub private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds; private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds; final OomAdjuster mOomAdjuster; OomAdjuster mOomAdjuster; final LowMemDetector mLowMemDetector; final LowMemDetector mLowMemDetector; /** All system services */ /** All system services */ Loading Loading @@ -1483,7 +1483,7 @@ public class ActivityManagerService extends IActivityManager.Stub final ServiceThread mProcStartHandlerThread; final ServiceThread mProcStartHandlerThread; final Handler mProcStartHandler; final Handler mProcStartHandler; final ActivityManagerConstants mConstants; ActivityManagerConstants mConstants; // Encapsulates the global setting "hidden_api_blacklist_exemptions" // Encapsulates the global setting "hidden_api_blacklist_exemptions" final HiddenApiSettings mHiddenApiBlacklist; final HiddenApiSettings mHiddenApiBlacklist; Loading
services/core/java/com/android/server/am/OomAdjuster.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -75,6 +75,7 @@ import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.procstats.ProcessStats; import com.android.internal.app.procstats.ProcessStats; import com.android.server.LocalServices; import com.android.server.LocalServices; import com.android.server.wm.ActivityServiceConnectionsHolder; import com.android.server.wm.ActivityServiceConnectionsHolder; Loading Loading @@ -1897,6 +1898,10 @@ public final class OomAdjuster { // For apps that sit around for a long time in the interactive state, we need // For apps that sit around for a long time in the interactive state, we need // to report this at least once a day so they don't go idle. // to report this at least once a day so they don't go idle. maybeUpdateUsageStatsLocked(app, nowElapsed); maybeUpdateUsageStatsLocked(app, nowElapsed); } else if (!app.reportedInteraction && (nowElapsed - app.getFgInteractionTime()) > mConstants.SERVICE_USAGE_INTERACTION_TIME) { // For foreground services that sit around for a long time but are not interacted with. maybeUpdateUsageStatsLocked(app, nowElapsed); } } if (changes != 0) { if (changes != 0) { Loading @@ -1917,6 +1922,14 @@ public final class OomAdjuster { return success; return success; } } // ONLY used for unit testing in OomAdjusterTests.java @VisibleForTesting void maybeUpdateUsageStats(ProcessRecord app, long nowElapsed) { synchronized (mService) { maybeUpdateUsageStatsLocked(app, nowElapsed); } } @GuardedBy("mService") @GuardedBy("mService") private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) { private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) { if (DEBUG_USAGE_STATS) { if (DEBUG_USAGE_STATS) { Loading
services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java 0 → 100644 +255 −0 Original line number Original line Diff line number Diff line /* * 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 android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import android.app.ActivityManager; import android.app.usage.UsageStatsManagerInternal; import android.content.Context; import com.android.server.LocalServices; import com.android.server.wm.ActivityTaskManagerService; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * Test class for {@link OomAdjuster}. * * Build/Install/Run: * atest FrameworksServicesTests:OomAdjusterTests */ public class OomAdjusterTests { private static Context sContext; private static ActivityManagerService sService; private ProcessRecord mProcessRecord; private static final long ZERO = 0L; private static final long USAGE_STATS_INTERACTION = 2 * 60 * 60 * 1000L; private static final long SERVICE_USAGE_INTERACTION = 30 * 60 * 1000; @BeforeClass public static void setUpOnce() { sContext = getInstrumentation().getTargetContext(); // We need to run with dexmaker share class loader to make use of // ActivityTaskManagerService from wm package. runWithDexmakerShareClassLoader(() -> { sService = mock(ActivityManagerService.class); sService.mActivityTaskManager = new ActivityTaskManagerService(sContext); sService.mActivityTaskManager.initialize(null, null, sContext.getMainLooper()); sService.mAtmInternal = sService.mActivityTaskManager.getAtmInternal(); sService.mConstants = new ActivityManagerConstants(sContext, sService, sContext.getMainThreadHandler()); sService.mOomAdjuster = new OomAdjuster(sService, sService.mProcessList, null); LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); LocalServices.addService(UsageStatsManagerInternal.class, mock(UsageStatsManagerInternal.class)); sService.mUsageStatsService = LocalServices.getService(UsageStatsManagerInternal.class); }); } @Before public void setUpProcess() { // Need to run with dexmaker share class loader to mock package private class. runWithDexmakerShareClassLoader(() -> { mProcessRecord = spy(new ProcessRecord(sService, sContext.getApplicationInfo(), "name", 12345)); }); // Ensure certain services and constants are defined properly assertNotNull(sService.mUsageStatsService); assertEquals(USAGE_STATS_INTERACTION, sService.mConstants.USAGE_STATS_INTERACTION_INTERVAL); assertEquals(SERVICE_USAGE_INTERACTION, sService.mConstants.SERVICE_USAGE_INTERACTION_TIME); } @Test public void testMaybeUpdateUsageStats_ProcStatePersistentUI() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateTop() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_TOP); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateTop_PreviousInteraction() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_TOP); mProcessRecord.reportedInteraction = true; sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateTop_PastUsageInterval() { final long elapsedTime = 3 * USAGE_STATS_INTERACTION; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_TOP); mProcessRecord.reportedInteraction = true; sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateBoundTop() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_BOUND_TOP); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateFGS() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(elapsedTime, false, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateFGS_ShortInteraction() { final long elapsedTime = ZERO; final long fgInteractionTime = 1000L; mProcessRecord.setFgInteractionTime(fgInteractionTime); mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(fgInteractionTime, false, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateFGS_LongInteraction() { final long elapsedTime = 2 * SERVICE_USAGE_INTERACTION; final long fgInteractionTime = 1000L; mProcessRecord.setFgInteractionTime(fgInteractionTime); mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(fgInteractionTime, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateFGS_PreviousLongInteraction() { final long elapsedTime = 2 * SERVICE_USAGE_INTERACTION; final long fgInteractionTime = 1000L; mProcessRecord.setFgInteractionTime(fgInteractionTime); mProcessRecord.reportedInteraction = true; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(fgInteractionTime, true, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateFGSLocation() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(elapsedTime, false, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateBFGS() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateImportantFG() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateImportantFG_PreviousInteraction() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); mProcessRecord.reportedInteraction = true; sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateImportantFG_PastUsageInterval() { final long elapsedTime = 3 * USAGE_STATS_INTERACTION; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); mProcessRecord.reportedInteraction = true; sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, true, elapsedTime); } @Test public void testMaybeUpdateUsageStats_ProcStateImportantBG() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, false, ZERO); } @Test public void testMaybeUpdateUsageStats_ProcStateService() { final long elapsedTime = ZERO; mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_SERVICE); sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime); assertProcessRecordState(ZERO, false, ZERO); } private void assertProcessRecordState(long fgInteractionTime, boolean reportedInteraction, long interactionEventTime) { assertEquals("Foreground interaction time was not updated correctly.", fgInteractionTime, mProcessRecord.getFgInteractionTime()); assertEquals("Interaction was not updated correctly.", reportedInteraction, mProcessRecord.reportedInteraction); assertEquals("Interaction event time was not updated correctly.", interactionEventTime, mProcessRecord.getInteractionEventTime()); } }