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}