ActivityManagerServiceTest.java revision 51ab3acf270c655ed90706895b43915433d022c7
188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka/* 288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Copyright (C) 2017 The Android Open Source Project 388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * 488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Licensed under the Apache License, Version 2.0 (the "License"); 588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * you may not use this file except in compliance with the License. 688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * You may obtain a copy of the License at 788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * 888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * http://www.apache.org/licenses/LICENSE-2.0 988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * 1088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Unless required by applicable law or agreed to in writing, software 1188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * distributed under the License is distributed on an "AS IS" BASIS, 1288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * See the License for the specific language governing permissions and 1488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * limitations under the License 1588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka */ 1688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 1788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankapackage com.android.server.am; 1888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 1988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 2088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 2188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY; 2288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 2388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 2488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 2588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 2688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 2788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_RECEIVER; 2888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_SERVICE; 2988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.app.ActivityManager.PROCESS_STATE_TOP; 3088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static android.util.DebugUtils.valueToString; 3151ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport static com.android.server.am.ActivityManagerService.DISPATCH_UIDS_CHANGED_UI_MSG; 3251ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport static com.android.server.am.ActivityManagerService.Injector; 3388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 3488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static org.junit.Assert.assertEquals; 3588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static org.junit.Assert.assertFalse; 364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.junit.Assert.assertNotEquals; 374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.junit.Assert.assertNotNull; 384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.junit.Assert.assertNull; 3988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static org.junit.Assert.assertTrue; 4051ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport static org.junit.Assert.fail; 414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.mockito.Mockito.verify; 424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.mockito.Mockito.verifyNoMoreInteractions; 434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.mockito.Mockito.when; 4488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 4588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport android.app.ActivityManager; 464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.app.AppOpsManager; 474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.app.IUidObserver; 4851ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Handler; 4951ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.HandlerThread; 504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.IBinder; 5151ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Looper; 5251ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Message; 534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.Process; 544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.RemoteException; 5551ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.SystemClock; 5651ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.support.test.filters.MediumTest; 5788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport android.support.test.filters.SmallTest; 5888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport android.support.test.runner.AndroidJUnit4; 5988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport com.android.server.AppOpsService; 614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 6251ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport org.junit.After; 634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.junit.Before; 6488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport org.junit.Test; 6588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport org.junit.runner.RunWith; 664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.Mock; 674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.Mockito; 684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.MockitoAnnotations; 6988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.ArrayList; 714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.HashMap; 7251ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport java.util.HashSet; 734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.Map; 7451ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport java.util.Set; 7588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport java.util.function.Function; 7688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 7788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka/** 7888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Test class for {@link ActivityManagerService}. 7988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * 8088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * To run the tests, use 8188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * 8288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services 8388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * 8488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * or the following steps: 8588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * 8688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Build: m FrameworksServicesTests 8788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Install: adb install -r \ 8888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk 8988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerServiceTest -w \ 9088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner 9188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka */ 9288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka@SmallTest 9388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka@RunWith(AndroidJUnit4.class) 9488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankapublic class ActivityManagerServiceTest { 9551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private static final String TAG = ActivityManagerServiceTest.class.getSimpleName(); 9651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 9788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka private static final int TEST_UID = 111; 9888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 9951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private static final long TEST_PROC_STATE_SEQ1 = 555; 10051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private static final long TEST_PROC_STATE_SEQ2 = 556; 10151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 10251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private static final int[] UID_RECORD_CHANGES = { 10351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka UidRecord.CHANGE_PROCSTATE, 10451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka UidRecord.CHANGE_GONE, 10551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka UidRecord.CHANGE_GONE_IDLE, 10651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka UidRecord.CHANGE_IDLE, 10751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka UidRecord.CHANGE_ACTIVE 10851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka }; 10951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 1104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka @Mock private AppOpsService mAppOpsService; 1114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 11251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private ActivityManagerService mAms; 11351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private HandlerThread mHandlerThread; 11451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private TestHandler mHandler; 11551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 1164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka @Before 1174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka public void setUp() { 1184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka MockitoAnnotations.initMocks(this); 11951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 12051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mHandlerThread = new HandlerThread(TAG); 12151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mHandlerThread.start(); 12251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mHandler = new TestHandler(mHandlerThread.getLooper()); 12351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms = new ActivityManagerService(new TestInjector()); 12451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 12551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 12651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka @After 12751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka public void tearDown() { 12851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mHandlerThread.quit(); 1294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 1304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 13188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka @Test 13288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka public void testIncrementProcStateSeqIfNeeded() { 13388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka final UidRecord uidRec = new UidRecord(TEST_UID); 13488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 13551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals("Initially global seq counter should be 0", 0, mAms.mProcStateSeqCounter); 13688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka assertEquals("Initially seq counter in uidRecord should be 0", 0, uidRec.curProcStateSeq); 13788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 13888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Uid state is not moving from background to foreground or vice versa. 13988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_TOP; 14088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_TOP; 14151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.incrementProcStateSeqIfNeeded(uidRec); 14251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(0, mAms.mProcStateSeqCounter); 14388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka assertEquals(0, uidRec.curProcStateSeq); 14488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 14588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Uid state is moving from foreground to background. 14688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE; 14788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_SERVICE; 14851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.incrementProcStateSeqIfNeeded(uidRec); 14951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(1, mAms.mProcStateSeqCounter); 15088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka assertEquals(1, uidRec.curProcStateSeq); 15188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 15288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Explicitly setting the seq counter for more verification. 15351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mProcStateSeqCounter = 42; 15488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 15588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Uid state is not moving from background to foreground or vice versa. 15688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_IMPORTANT_BACKGROUND; 15788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_IMPORTANT_FOREGROUND; 15851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.incrementProcStateSeqIfNeeded(uidRec); 15951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(42, mAms.mProcStateSeqCounter); 16088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka assertEquals(1, uidRec.curProcStateSeq); 16188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 16288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Uid state is moving from background to foreground. 16388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_LAST_ACTIVITY; 16488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_TOP; 16551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.incrementProcStateSeqIfNeeded(uidRec); 16651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(43, mAms.mProcStateSeqCounter); 16788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka assertEquals(43, uidRec.curProcStateSeq); 16888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka } 16988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 17088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka @Test 17188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka public void testShouldIncrementProcStateSeq() { 17288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka final UidRecord uidRec = new UidRecord(TEST_UID); 17388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 17488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka final String error1 = "Seq should be incremented: prevState: %s, curState: %s"; 17588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka final String error2 = "Seq should not be incremented: prevState: %s, curState: %s"; 17688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka Function<String, String> errorMsg = errorTemplate -> { 17788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka return String.format(errorTemplate, 17888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.setProcState), 17988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.curProcState)); 18088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka }; 18188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 18288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // No change in uid state 18388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_RECEIVER; 18488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_RECEIVER; 18551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertFalse(errorMsg.apply(error2), mAms.shouldIncrementProcStateSeq(uidRec)); 18688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 18788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Foreground to foreground 18888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_FOREGROUND_SERVICE; 18988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 19051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertFalse(errorMsg.apply(error2), mAms.shouldIncrementProcStateSeq(uidRec)); 19188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 19288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Background to background 19388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_CACHED_ACTIVITY; 19488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_CACHED_EMPTY; 19551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertFalse(errorMsg.apply(error2), mAms.shouldIncrementProcStateSeq(uidRec)); 19688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 19788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Background to background 19888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_NONEXISTENT; 19988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_CACHED_ACTIVITY; 20051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertFalse(errorMsg.apply(error2), mAms.shouldIncrementProcStateSeq(uidRec)); 20188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 20288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Background to foreground 20388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_SERVICE; 20488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE; 20551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertTrue(errorMsg.apply(error1), mAms.shouldIncrementProcStateSeq(uidRec)); 20688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka 20788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka // Foreground to background 20888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.setProcState = PROCESS_STATE_TOP; 20988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka uidRec.curProcState = PROCESS_STATE_LAST_ACTIVITY; 21051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertTrue(errorMsg.apply(error1), mAms.shouldIncrementProcStateSeq(uidRec)); 21188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka } 2124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 2134c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka /** 2144c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka * This test verifies that process state changes are dispatched to observers based on the 2154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka * changes they wanted to listen (this is specified when registering the observer). 2164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka */ 2174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka @Test 2184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka public void testDispatchUids_dispatchNeededChanges() throws RemoteException { 2194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka when(mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS, Process.myUid(), null)) 2204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka .thenReturn(AppOpsManager.MODE_ALLOWED); 2214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 2224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final int[] changesToObserve = { 2234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.UID_OBSERVER_PROCSTATE, 2244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.UID_OBSERVER_GONE, 2254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.UID_OBSERVER_IDLE, 2264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.UID_OBSERVER_ACTIVE, 2274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE 2284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka | ActivityManager.UID_OBSERVER_ACTIVE | ActivityManager.UID_OBSERVER_IDLE 2294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }; 2304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length]; 2314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka for (int i = 0; i < observers.length; ++i) { 2324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka observers[i] = Mockito.mock(IUidObserver.Stub.class); 2334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka when(observers[i].asBinder()).thenReturn((IBinder) observers[i]); 23451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.registerUidObserver(observers[i], changesToObserve[i] /* which */, 2354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */); 2364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 2374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // When we invoke AMS.registerUidObserver, there are some interactions with observers[i] 2384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // mock in RemoteCallbackList class. We don't want to test those interactions and 2394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // at the same time, we don't want those to interfere with verifyNoMoreInteractions. 2404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // So, resetting the mock here. 2414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka Mockito.reset(observers[i]); 2424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 2434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 2444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Add pending uid records each corresponding to a different change type UidRecord.CHANGE_* 24551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final int[] changesForPendingUidRecords = UID_RECORD_CHANGES; 24651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 2474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final int[] procStatesForPendingUidRecords = { 2484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 2494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_NONEXISTENT, 2504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_CACHED_EMPTY, 2514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, 2524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_TOP 2534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }; 2544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final Map<Integer, UidRecord.ChangeItem> changeItems = new HashMap<>(); 2554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka for (int i = 0; i < changesForPendingUidRecords.length; ++i) { 2564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final UidRecord.ChangeItem pendingChange = new UidRecord.ChangeItem(); 2574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka pendingChange.change = changesForPendingUidRecords[i]; 2584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka pendingChange.uid = i; 2594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka pendingChange.processState = procStatesForPendingUidRecords[i]; 2608025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka pendingChange.procStateSeq = i; 2614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka changeItems.put(changesForPendingUidRecords[i], pendingChange); 26251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.add(pendingChange); 2634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 2644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 26551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 2664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Verify the required changes have been dispatched to observers. 2674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka for (int i = 0; i < observers.length; ++i) { 2684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final int changeToObserve = changesToObserve[i]; 2694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final IUidObserver observerToTest = observers[i]; 2704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka if ((changeToObserve & ActivityManager.UID_OBSERVER_IDLE) != 0) { 2714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Observer listens to uid idle changes, so change items corresponding to 2724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // UidRecord.CHANGE_IDLE or UidRecord.CHANGE_IDLE_GONE needs to be 2734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // delivered to this observer. 2744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final int[] changesToVerify = { 2754c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka UidRecord.CHANGE_IDLE, 2764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka UidRecord.CHANGE_GONE_IDLE 2774c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }; 2784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems, 2794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka (observer, changeItem) -> { 2804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verify(observer).onUidIdle(changeItem.uid, changeItem.ephemeral); 2814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }); 2824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 2834c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka if ((changeToObserve & ActivityManager.UID_OBSERVER_ACTIVE) != 0) { 2844c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Observer listens to uid active changes, so change items corresponding to 2854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // UidRecord.CHANGE_ACTIVE needs to be delivered to this observer. 2864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final int[] changesToVerify = { UidRecord.CHANGE_ACTIVE }; 2874c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems, 2884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka (observer, changeItem) -> { 2894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verify(observer).onUidActive(changeItem.uid); 2904c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }); 2914c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 2924c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka if ((changeToObserve & ActivityManager.UID_OBSERVER_GONE) != 0) { 2934c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Observer listens to uid gone changes, so change items corresponding to 2944c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // UidRecord.CHANGE_GONE or UidRecord.CHANGE_IDLE_GONE needs to be 2954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // delivered to this observer. 2964c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final int[] changesToVerify = { 2974c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka UidRecord.CHANGE_GONE, 2984c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka UidRecord.CHANGE_GONE_IDLE 2994c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }; 3004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems, 3014c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka (observer, changeItem) -> { 3024c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verify(observer).onUidGone(changeItem.uid, changeItem.ephemeral); 3034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }); 3044c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 3054c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { 3064c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Observer listens to uid procState changes, so change items corresponding to 3074c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // UidRecord.CHANGE_PROCSTATE or UidRecord.CHANGE_IDLE or UidRecord.CHANGE_ACTIVE 3084c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // needs to be delivered to this observer. 3094c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final int[] changesToVerify = { 3104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka UidRecord.CHANGE_PROCSTATE, 3114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka UidRecord.CHANGE_ACTIVE, 3124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka UidRecord.CHANGE_IDLE 3134c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }; 3144c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems, 3154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka (observer, changeItem) -> { 3168025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka verify(observer).onUidStateChanged(changeItem.uid, 3178025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka changeItem.processState, changeItem.procStateSeq); 3184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }); 3194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 3204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Verify there are no other callbacks for this observer. 3214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyNoMoreInteractions(observerToTest); 3224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 3234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 3244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka private interface ObserverChangesVerifier { 3264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka void verify(IUidObserver observer, UidRecord.ChangeItem changeItem) throws RemoteException; 3274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 3284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka private void verifyObserverReceivedChanges(IUidObserver observer, int[] changesToVerify, 3304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka Map<Integer, UidRecord.ChangeItem> changeItems, ObserverChangesVerifier verifier) 3314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka throws RemoteException { 3324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka for (int change : changesToVerify) { 3334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final UidRecord.ChangeItem changeItem = changeItems.get(change); 3344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifier.verify(observer, changeItem); 3354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 3364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 3374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka /** 3394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka * This test verifies that process state changes are dispatched to observers only when they 3404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka * change across the cutpoint (this is specified when registering the observer). 3414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka */ 3424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka @Test 3434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka public void testDispatchUidChanges_procStateCutpoint() throws RemoteException { 3444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class); 3454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka when(observer.asBinder()).thenReturn((IBinder) observer); 34751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */, 3484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */); 3494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // When we invoke AMS.registerUidObserver, there are some interactions with observer 3504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // mock in RemoteCallbackList class. We don't want to test those interactions and 3514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // at the same time, we don't want those to interfere with verifyNoMoreInteractions. 3524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // So, resetting the mock here. 3534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka Mockito.reset(observer); 3544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem(); 3564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka changeItem.uid = TEST_UID; 3574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka changeItem.change = UidRecord.CHANGE_PROCSTATE; 3584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka changeItem.processState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 3598025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka changeItem.procStateSeq = 111; 36051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.add(changeItem); 36151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 3624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // First process state message is always delivered regardless of whether the process state 3634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // change is above or below the cutpoint (PROCESS_STATE_SERVICE). 3644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verify(observer).onUidStateChanged(TEST_UID, 3658025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka changeItem.processState, changeItem.procStateSeq); 3664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyNoMoreInteractions(observer); 3674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka changeItem.processState = ActivityManager.PROCESS_STATE_RECEIVER; 36951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.add(changeItem); 37051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 3714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and 3724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // the current process state change is also below cutpoint, so no callback will be invoked. 3734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyNoMoreInteractions(observer); 3744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3754c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka changeItem.processState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 37651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.add(changeItem); 37751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 3784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and 3794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // the current process state change is above cutpoint, so callback will be invoked with the 3804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // current process state change. 3814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verify(observer).onUidStateChanged(TEST_UID, 3828025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka changeItem.processState, changeItem.procStateSeq); 3834c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyNoMoreInteractions(observer); 3844c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka changeItem.processState = ActivityManager.PROCESS_STATE_TOP; 38651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.add(changeItem); 38751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 3884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and 3894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // the current process state change is also above cutpoint, so no callback will be invoked. 3904c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyNoMoreInteractions(observer); 3914c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 3924c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka changeItem.processState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 39351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.add(changeItem); 39451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 3954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and 3964c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // the current process state change is below cutpoint, so callback will be invoked with the 3974c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // current process state change. 3988025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka verify(observer).onUidStateChanged(TEST_UID, 3998025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka changeItem.processState, changeItem.procStateSeq); 4004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka verifyNoMoreInteractions(observer); 4014c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 4024c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 4034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka /** 4044c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka * This test verifies that {@link ActivityManagerService#mValidateUids} which is a 4054c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka * part of dumpsys is correctly updated. 4064c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka */ 4074c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka @Test 4084c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka public void testDispatchUidChanges_validateUidsUpdated() { 40951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final int[] changesForPendingItems = UID_RECORD_CHANGES; 41051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 4114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final int[] procStatesForPendingItems = { 4124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 4134c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_CACHED_EMPTY, 4144c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, 4154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_SERVICE, 4164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka ActivityManager.PROCESS_STATE_RECEIVER 4174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka }; 4184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final ArrayList<UidRecord.ChangeItem> pendingItemsForUids 4194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka = new ArrayList<>(changesForPendingItems.length); 4204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka for (int i = 0; i < changesForPendingItems.length; ++i) { 4214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final UidRecord.ChangeItem item = new UidRecord.ChangeItem(); 4224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka item.uid = i; 4234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka item.change = changesForPendingItems[i]; 4244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka item.processState = procStatesForPendingItems[i]; 4254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka pendingItemsForUids.add(i, item); 4264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 4274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 4284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Verify that when there no observers listening to uid state changes, then there will 4294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // be no changes to validateUids. 43051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.addAll(pendingItemsForUids); 43151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 4324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka assertEquals("No observers registered, so validateUids should be empty", 43351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 0, mAms.mValidateUids.size()); 4344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 4354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class); 4364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka when(observer.asBinder()).thenReturn((IBinder) observer); 43751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.registerUidObserver(observer, 0, 0, null); 4384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Verify that when observers are registered, then validateUids is correctly updated. 43951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.addAll(pendingItemsForUids); 44051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 4414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka for (int i = 0; i < pendingItemsForUids.size(); ++i) { 4424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final UidRecord.ChangeItem item = pendingItemsForUids.get(i); 44351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final UidRecord validateUidRecord = mAms.mValidateUids.get(item.uid); 4444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka if (item.change == UidRecord.CHANGE_GONE || item.change == UidRecord.CHANGE_GONE_IDLE) { 4454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka assertNull("validateUidRecord should be null since the change is either " 4464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka + "CHANGE_GONE or CHANGE_GONE_IDLE", validateUidRecord); 4474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } else { 4484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka assertNotNull("validateUidRecord should not be null since the change is neither " 4494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka + "CHANGE_GONE nor CHANGE_GONE_IDLE", validateUidRecord); 4504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka assertEquals("processState: " + item.processState + " curProcState: " 4514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka + validateUidRecord.curProcState + " should have been equal", 4524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka item.processState, validateUidRecord.curProcState); 4534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka assertEquals("processState: " + item.processState + " setProcState: " 4544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka + validateUidRecord.curProcState + " should have been equal", 4554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka item.processState, validateUidRecord.setProcState); 4564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka if (item.change == UidRecord.CHANGE_IDLE) { 4574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka assertTrue("UidRecord.idle should be updated to true for CHANGE_IDLE", 4584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka validateUidRecord.idle); 4594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } else if (item.change == UidRecord.CHANGE_ACTIVE) { 4604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka assertFalse("UidRecord.idle should be updated to false for CHANGE_ACTIVE", 4614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka validateUidRecord.idle); 4624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 4634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 4644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 4654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka 4664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Verify that when uid state changes to CHANGE_GONE or CHANGE_GONE_IDLE, then it 4674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // will be removed from validateUids. 46851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertNotEquals("validateUids should not be empty", 0, mAms.mValidateUids.size()); 4694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka for (int i = 0; i < pendingItemsForUids.size(); ++i) { 4704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka final UidRecord.ChangeItem item = pendingItemsForUids.get(i); 4714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // Assign CHANGE_GONE_IDLE to some items and CHANGE_GONE to the others, using even/odd 4724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka // distribution for this assignment. 4734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka item.change = (i % 2) == 0 ? UidRecord.CHANGE_GONE_IDLE : UidRecord.CHANGE_GONE; 4744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 47551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.addAll(pendingItemsForUids); 47651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.dispatchUidsChanged(); 47751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals("validateUids should be empty, validateUids: " + mAms.mValidateUids, 47851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 0, mAms.mValidateUids.size()); 47951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 48051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 48151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka @Test 48251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka public void testEnqueueUidChangeLocked_procStateSeqUpdated() { 48351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final UidRecord uidRecord = new UidRecord(TEST_UID); 48451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1; 48551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 48651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Verify with no pending changes for TEST_UID. 48751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ1); 48851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 48951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Add a pending change for TEST_UID and verify enqueueUidChangeLocked still works as 49051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // expected. 49151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem(); 49251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.pendingChange = changeItem; 49351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ2; 49451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ2); 49551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 49651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Use "null" uidRecord to make sure there is no crash. 49751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // TODO: currently it crashes, uncomment after fixing it. 49851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE); 49951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 50051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 50151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) { 50251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Test enqueueUidChangeLocked with every UidRecord.CHANGE_* 50351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) { 50451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final int changeToDispatch = UID_RECORD_CHANGES[i]; 50551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Reset lastProcStateSeqDispatchToObservers after every test. 50651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.lastDispatchedProcStateSeq = 0; 50751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch); 50851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Verify there is no effect on curProcStateSeq. 50951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(curProcstateSeq, uidRecord.curProcStateSeq); 51051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka if (changeToDispatch == UidRecord.CHANGE_GONE 51151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka || changeToDispatch == UidRecord.CHANGE_GONE_IDLE) { 51251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Since the change is CHANGE_GONE or CHANGE_GONE_IDLE, verify that 51351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // lastProcStateSeqDispatchedToObservers is not updated. 51451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertNotEquals(uidRecord.curProcStateSeq, 51551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.lastDispatchedProcStateSeq); 51651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } else { 51751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Since the change is neither CHANGE_GONE nor CHANGE_GONE_IDLE, verify that 51851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // lastProcStateSeqDispatchedToObservers has been updated to curProcStateSeq. 51951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(uidRecord.curProcStateSeq, 52051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.lastDispatchedProcStateSeq); 52151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 52251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 52351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 52451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 52551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka @MediumTest 52651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka @Test 52751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka public void testEnqueueUidChangeLocked_dispatchUidsChanged() { 52851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final UidRecord uidRecord = new UidRecord(TEST_UID); 52951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final int expectedProcState = PROCESS_STATE_SERVICE; 53051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.setProcState = expectedProcState; 53151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1; 53251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 53351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Test with no pending uid records. 53451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) { 53551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final int changeToDispatch = UID_RECORD_CHANGES[i]; 53651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 53751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Reset the current state 53851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mHandler.reset(); 53951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka uidRecord.pendingChange = null; 54051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.mPendingUidChanges.clear(); 54151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 54251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mAms.enqueueUidChangeLocked(uidRecord, -1, changeToDispatch); 54351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 54451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Verify that UidRecord.pendingChange is updated correctly. 54551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertNotNull(uidRecord.pendingChange); 54651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(TEST_UID, uidRecord.pendingChange.uid); 54751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(expectedProcState, uidRecord.pendingChange.processState); 54851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka assertEquals(TEST_PROC_STATE_SEQ1, uidRecord.pendingChange.procStateSeq); 54951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 55051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka // Verify that DISPATCH_UIDS_CHANGED_UI_MSG is posted to handler. 55151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mHandler.waitForMessage(DISPATCH_UIDS_CHANGED_UI_MSG); 55251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 55351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 55451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 55551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private class TestHandler extends Handler { 55651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private static final long WAIT_FOR_MSG_TIMEOUT_MS = 4000; // 4 sec 55751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private static final long WAIT_FOR_MSG_INTERVAL_MS = 400; // 0.4 sec 55851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 55951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private Set<Integer> mMsgsHandled = new HashSet<>(); 56051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 56151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka TestHandler(Looper looper) { 56251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka super(looper); 56351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 56451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 56551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka @Override 56651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka public void handleMessage(Message msg) { 56751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mMsgsHandled.add(msg.what); 56851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 56951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 57051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka public void waitForMessage(int msg) { 57151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka final long endTime = System.currentTimeMillis() + WAIT_FOR_MSG_TIMEOUT_MS; 57251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka while (!mMsgsHandled.contains(msg) && System.currentTimeMillis() < endTime) { 57351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka SystemClock.sleep(WAIT_FOR_MSG_INTERVAL_MS); 57451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 57551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka if (!mMsgsHandled.contains(msg)) { 57651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka fail("Timed out waiting for the message to be handled, msg: " + msg); 57751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 57851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 57951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 58051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka public void reset() { 58151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka mMsgsHandled.clear(); 58251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 58351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 58451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 58551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka private class TestInjector implements Injector { 58651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka @Override 58751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka public AppOpsService getAppOpsService() { 58851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka return mAppOpsService; 58951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 59051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka 59151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka @Override 59251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka public Handler getHandler() { 59351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka return mHandler; 59451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka } 5954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka } 59688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka}