ActivityManagerServiceTest.java revision 84a4895c9c1eb7f381d99fb8eb298d8335d4e480
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;
3184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport static com.android.server.am.ActivityManagerInternalTest.CustomThread;
3251ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport static com.android.server.am.ActivityManagerService.DISPATCH_UIDS_CHANGED_UI_MSG;
3351ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport static com.android.server.am.ActivityManagerService.Injector;
3484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport static com.android.server.am.ActivityManagerService.NETWORK_STATE_BLOCK;
3584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport static com.android.server.am.ActivityManagerService.NETWORK_STATE_NO_CHANGE;
3684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport static com.android.server.am.ActivityManagerService.NETWORK_STATE_UNBLOCK;
3788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
3888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static org.junit.Assert.assertEquals;
3988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static org.junit.Assert.assertFalse;
404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.junit.Assert.assertNotEquals;
414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.junit.Assert.assertNotNull;
424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.junit.Assert.assertNull;
4388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport static org.junit.Assert.assertTrue;
4451ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport static org.junit.Assert.fail;
454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.mockito.Mockito.verify;
464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.mockito.Mockito.verifyNoMoreInteractions;
4784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport static org.mockito.Mockito.verifyZeroInteractions;
484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport static org.mockito.Mockito.when;
4988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
5088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport android.app.ActivityManager;
514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.app.AppOpsManager;
5284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport android.app.IApplicationThread;
534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.app.IUidObserver;
5484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport android.content.pm.ApplicationInfo;
5551ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Handler;
5651ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.HandlerThread;
574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.IBinder;
5851ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Looper;
5951ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Message;
604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.Process;
614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.RemoteException;
6251ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.SystemClock;
6351ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.support.test.filters.MediumTest;
6488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport android.support.test.filters.SmallTest;
6588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport android.support.test.runner.AndroidJUnit4;
6688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
6784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport com.android.internal.os.BatteryStatsImpl;
684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport com.android.server.AppOpsService;
694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
7051ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport org.junit.After;
714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.junit.Before;
7288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport org.junit.Test;
7388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport org.junit.runner.RunWith;
744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.Mock;
754c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.Mockito;
764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.MockitoAnnotations;
7788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
7884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport java.io.File;
794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.ArrayList;
804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.HashMap;
8151ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport java.util.HashSet;
824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.Map;
8351ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport java.util.Set;
8488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport java.util.function.Function;
8588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
8688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka/**
8788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Test class for {@link ActivityManagerService}.
8888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *
8988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * To run the tests, use
9088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *
9188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services
9288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *
9388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * or the following steps:
9488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *
9588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Build: m FrameworksServicesTests
9688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Install: adb install -r \
9788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
9888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerServiceTest -w \
9988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
10088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka */
10188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka@SmallTest
10288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka@RunWith(AndroidJUnit4.class)
10388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankapublic class ActivityManagerServiceTest {
10451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private static final String TAG = ActivityManagerServiceTest.class.getSimpleName();
10551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
10688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    private static final int TEST_UID = 111;
10788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
10851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private static final long TEST_PROC_STATE_SEQ1 = 555;
10951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private static final long TEST_PROC_STATE_SEQ2 = 556;
11051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
11151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private static final int[] UID_RECORD_CHANGES = {
11251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_PROCSTATE,
11351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_GONE,
11451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_GONE_IDLE,
11551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_IDLE,
11651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_ACTIVE
11751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    };
11851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
1194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Mock private AppOpsService mAppOpsService;
1204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
12184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private TestInjector mInjector;
12251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private ActivityManagerService mAms;
12351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private HandlerThread mHandlerThread;
12451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private TestHandler mHandler;
12551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
1264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Before
1274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void setUp() {
1284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        MockitoAnnotations.initMocks(this);
12951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
13051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread = new HandlerThread(TAG);
13151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread.start();
13251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandler = new TestHandler(mHandlerThread.getLooper());
13384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mInjector = new TestInjector();
13484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms = new ActivityManagerService(mInjector);
13551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
13651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
13751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @After
13851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void tearDown() {
13951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread.quit();
1404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
1414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
14284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @MediumTest
14388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    @Test
14484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void incrementProcStateSeqAndNotifyAppsLocked() throws Exception {
14588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        final UidRecord uidRec = new UidRecord(TEST_UID);
14684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.waitingForNetwork = true;
14784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.put(TEST_UID, uidRec);
14884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
14984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final BatteryStatsImpl batteryStats = Mockito.mock(BatteryStatsImpl.class);
15084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final ProcessRecord appRec = new ProcessRecord(batteryStats,
15184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                new ApplicationInfo(), TAG, TEST_UID);
15284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        appRec.thread = Mockito.mock(IApplicationThread.class);
15384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mLruProcesses.add(appRec);
15488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
15584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final ProcessRecord appRec2 = new ProcessRecord(batteryStats,
15684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                new ApplicationInfo(), TAG, TEST_UID + 1);
15784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        appRec2.thread = Mockito.mock(IApplicationThread.class);
15884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mLruProcesses.add(appRec2);
15988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
16088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is not moving from background to foreground or vice versa.
16184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
16284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // prevState
16384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
16484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                0, // expectedGlobalCounter
16584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                0, // exptectedCurProcStateSeq
16684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_NO_CHANGE, // expectedBlockState
16784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
16888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
16988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is moving from foreground to background.
17084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
17184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_FOREGROUND_SERVICE, // prevState
17284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_SERVICE, // curState
17384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // expectedGlobalCounter
17484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // exptectedCurProcStateSeq
17584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_UNBLOCK, // expectedBlockState
17684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                true); // expectNotify
17788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
17888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Explicitly setting the seq counter for more verification.
17951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mProcStateSeqCounter = 42;
18088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
18188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is not moving from background to foreground or vice versa.
18284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
18384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
18484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_FOREGROUND, // curState
18584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                42, // expectedGlobalCounter
18684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // exptectedCurProcStateSeq
18784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_NO_CHANGE, // expectedBlockState
18884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
18988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
19088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is moving from background to foreground.
19184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
19284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_LAST_ACTIVITY, // prevState
19384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
19484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                43, // expectedGlobalCounter
19584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                43, // exptectedCurProcStateSeq
19684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_BLOCK, // expectedBlockState
19784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
19884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
19984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // verify waiting threads are not notified.
20084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.waitingForNetwork = false;
20184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Uid state is moving from foreground to background.
20284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
20384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_FOREGROUND_SERVICE, // prevState
20484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_SERVICE, // curState
20584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // expectedGlobalCounter
20684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // exptectedCurProcStateSeq
20784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_UNBLOCK, // expectedBlockState
20884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
20984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
21084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify when uid is not restricted, procStateSeq is not incremented.
21184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.waitingForNetwork = true;
21284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mInjector.setNetworkRestrictedForUid(false);
21384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
21484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
21584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
21684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // expectedGlobalCounter
21784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // exptectedCurProcStateSeq
21884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
21984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
22084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
22184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
22284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private void verifySeqCounterAndInteractions(UidRecord uidRec, int prevState, int curState,
22384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            int expectedGlobalCounter, int expectedCurProcStateSeq, int expectedBlockState,
22484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            boolean expectNotify) throws Exception {
22584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        CustomThread thread = new CustomThread(uidRec.lock);
22684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        thread.startAndWait("Unexpected state for " + uidRec);
22784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
22884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.setProcState = prevState;
22984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.curProcState = curState;
23084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.incrementProcStateSeqAndNotifyAppsLocked();
23184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
23284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(expectedGlobalCounter, mAms.mProcStateSeqCounter);
23384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(expectedCurProcStateSeq, uidRec.curProcStateSeq);
23484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
23584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        for (int i = mAms.mLruProcesses.size() - 1; i >= 0; --i) {
23684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final ProcessRecord app = mAms.mLruProcesses.get(i);
23784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            // AMS should notify apps only for block states other than NETWORK_STATE_NO_CHANGE.
23884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            if (app.uid == uidRec.uid && expectedBlockState == NETWORK_STATE_BLOCK) {
23984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                verify(app.thread).setNetworkBlockSeq(uidRec.curProcStateSeq);
24084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            } else {
24184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                verifyZeroInteractions(app.thread);
24284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
24384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            Mockito.reset(app.thread);
24484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
24584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
24684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        if (expectNotify) {
24784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated("Unexpected state for " + uidRec);
24884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        } else {
24984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertWaiting("Unexpected state for " + uidRec);
25084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.interrupt();
25184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
25288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    }
25388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
25488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    @Test
25584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void testBlockStateForUid() {
25688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        final UidRecord uidRec = new UidRecord(TEST_UID);
25784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        int expectedBlockState;
25888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
25984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final String errorTemplate = "Block state should be %s, prevState: %s, curState: %s";
26084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        Function<Integer, String> errorMsg = (blockState) -> {
26188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka            return String.format(errorTemplate,
26284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    valueToString(ActivityManagerService.class, "NETWORK_STATE_", blockState),
26388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.setProcState),
26488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.curProcState));
26588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        };
26688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
26788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // No change in uid state
26888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_RECEIVER;
26988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_RECEIVER;
27084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
27184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
27284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
27388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
27488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Foreground to foreground
27588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_FOREGROUND_SERVICE;
27688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
27784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
27884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
27984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
28088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
28188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to background
28288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_CACHED_ACTIVITY;
28388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_CACHED_EMPTY;
28484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
28584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
28684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
28788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
28888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to background
28988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_NONEXISTENT;
29088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_CACHED_ACTIVITY;
29184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
29284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
29384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
29488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
29588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to foreground
29688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_SERVICE;
29788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE;
29884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_BLOCK;
29984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
30084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
30188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
30288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Foreground to background
30388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_TOP;
30488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_LAST_ACTIVITY;
30584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_UNBLOCK;
30684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
30784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
30888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    }
3094c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
3114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that process state changes are dispatched to observers based on the
3124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * changes they wanted to listen (this is specified when registering the observer).
3134c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
3144c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
3154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUids_dispatchNeededChanges() throws RemoteException {
3164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS, Process.myUid(), null))
3174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                .thenReturn(AppOpsManager.MODE_ALLOWED);
3184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] changesToObserve = {
3204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_PROCSTATE,
3214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_GONE,
3224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_IDLE,
3234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_ACTIVE,
3244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE
3254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    | ActivityManager.UID_OBSERVER_ACTIVE | ActivityManager.UID_OBSERVER_IDLE
3264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
3274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length];
3284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < observers.length; ++i) {
3294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            observers[i] = Mockito.mock(IUidObserver.Stub.class);
3304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            when(observers[i].asBinder()).thenReturn((IBinder) observers[i]);
33151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.registerUidObserver(observers[i], changesToObserve[i] /* which */,
3324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */);
3334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // When we invoke AMS.registerUidObserver, there are some interactions with observers[i]
3354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // mock in RemoteCallbackList class. We don't want to test those interactions and
3364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
3374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // So, resetting the mock here.
3384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            Mockito.reset(observers[i]);
3394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
3404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Add pending uid records each corresponding to a different change type UidRecord.CHANGE_*
34251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int[] changesForPendingUidRecords = UID_RECORD_CHANGES;
34351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
3444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] procStatesForPendingUidRecords = {
3454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
3464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_NONEXISTENT,
3474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
3484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
3494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_TOP
3504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
3514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final Map<Integer, UidRecord.ChangeItem> changeItems = new HashMap<>();
3524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < changesForPendingUidRecords.length; ++i) {
3534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem pendingChange = new UidRecord.ChangeItem();
3544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.change = changesForPendingUidRecords[i];
3554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.uid = i;
3564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.processState = procStatesForPendingUidRecords[i];
3578025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka            pendingChange.procStateSeq = i;
3584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            changeItems.put(changesForPendingUidRecords[i], pendingChange);
35951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.mPendingUidChanges.add(pendingChange);
3604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
3614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
36251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
3634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify the required changes have been dispatched to observers.
3644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < observers.length; ++i) {
3654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final int changeToObserve = changesToObserve[i];
3664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final IUidObserver observerToTest = observers[i];
3674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid idle changes, so change items corresponding to
3694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_IDLE or UidRecord.CHANGE_IDLE_GONE needs to be
3704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // delivered to this observer.
3714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
3724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    UidRecord.CHANGE_IDLE,
3734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    UidRecord.CHANGE_GONE_IDLE
3744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
3754c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
3764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
3774c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidIdle(changeItem.uid, changeItem.ephemeral);
3784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
3794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
3804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid active changes, so change items corresponding to
3824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_ACTIVE needs to be delivered to this observer.
3834c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = { UidRecord.CHANGE_ACTIVE };
3844c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
3854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
3864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidActive(changeItem.uid);
3874c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
3884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
3894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_GONE) != 0) {
3904c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid gone changes, so change items corresponding to
3914c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_GONE or UidRecord.CHANGE_IDLE_GONE needs to be
3924c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // delivered to this observer.
3934c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
3944c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_GONE,
3954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_GONE_IDLE
3964c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
3974c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
3984c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
3994c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidGone(changeItem.uid, changeItem.ephemeral);
4004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4014c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4024c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid procState changes, so change items corresponding to
4044c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_PROCSTATE or UidRecord.CHANGE_IDLE or UidRecord.CHANGE_ACTIVE
4054c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // needs to be delivered to this observer.
4064c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
4074c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_PROCSTATE,
4084c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_ACTIVE,
4094c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_IDLE
4104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
4114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
4124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
4138025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                            verify(observer).onUidStateChanged(changeItem.uid,
4148025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                                    changeItem.processState, changeItem.procStateSeq);
4154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // Verify there are no other callbacks for this observer.
4184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            verifyNoMoreInteractions(observerToTest);
4194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
4204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    private interface ObserverChangesVerifier {
4234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        void verify(IUidObserver observer, UidRecord.ChangeItem changeItem) throws RemoteException;
4244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    private void verifyObserverReceivedChanges(IUidObserver observer, int[] changesToVerify,
4274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            Map<Integer, UidRecord.ChangeItem> changeItems, ObserverChangesVerifier verifier)
4284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            throws RemoteException {
4294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int change : changesToVerify) {
4304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem changeItem = changeItems.get(change);
4314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            verifier.verify(observer, changeItem);
4324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
4334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
4364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that process state changes are dispatched to observers only when they
4374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * change across the cutpoint (this is specified when registering the observer).
4384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
4394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
4404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUidChanges_procStateCutpoint() throws RemoteException {
4414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
4424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(observer.asBinder()).thenReturn((IBinder) observer);
44451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */,
4454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */);
4464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // When we invoke AMS.registerUidObserver, there are some interactions with observer
4474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // mock in RemoteCallbackList class. We don't want to test those interactions and
4484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
4494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // So, resetting the mock here.
4504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        Mockito.reset(observer);
4514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
4534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.uid = TEST_UID;
4544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.change = UidRecord.CHANGE_PROCSTATE;
4554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
4568025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka        changeItem.procStateSeq = 111;
45751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
45851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // First process state message is always delivered regardless of whether the process state
4604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // change is above or below the cutpoint (PROCESS_STATE_SERVICE).
4614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
4628025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
4634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
4644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_RECEIVER;
46651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
46751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
4694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is also below cutpoint, so no callback will be invoked.
4704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
4714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
47351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
47451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4754c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
4764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is above cutpoint, so callback will be invoked with the
4774c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // current process state change.
4784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
4798025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
4804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
4814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_TOP;
48351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
48451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
4864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is also above cutpoint, so no callback will be invoked.
4874c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
4884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
49051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
49151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4924c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
4934c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is below cutpoint, so callback will be invoked with the
4944c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // current process state change.
4958025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
4968025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
4974c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
4984c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4994c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
5014c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that {@link ActivityManagerService#mValidateUids} which is a
5024c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * part of dumpsys is correctly updated.
5034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
5044c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
5054c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUidChanges_validateUidsUpdated() {
50651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int[] changesForPendingItems = UID_RECORD_CHANGES;
50751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
5084c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] procStatesForPendingItems = {
5094c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
5104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
5114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
5124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_SERVICE,
5134c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_RECEIVER
5144c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
5154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final ArrayList<UidRecord.ChangeItem> pendingItemsForUids
5164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                = new ArrayList<>(changesForPendingItems.length);
5174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < changesForPendingItems.length; ++i) {
5184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = new UidRecord.ChangeItem();
5194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.uid = i;
5204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.change = changesForPendingItems[i];
5214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.processState = procStatesForPendingItems[i];
5224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingItemsForUids.add(i, item);
5234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
5244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when there no observers listening to uid state changes, then there will
5264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // be no changes to validateUids.
52751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
52851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        assertEquals("No observers registered, so validateUids should be empty",
53051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                0, mAms.mValidateUids.size());
5314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
5334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(observer.asBinder()).thenReturn((IBinder) observer);
53451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.registerUidObserver(observer, 0, 0, null);
5354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when observers are registered, then validateUids is correctly updated.
53651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
53751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
5394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
54051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final UidRecord validateUidRecord = mAms.mValidateUids.get(item.uid);
5414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if (item.change == UidRecord.CHANGE_GONE || item.change == UidRecord.CHANGE_GONE_IDLE) {
5424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertNull("validateUidRecord should be null since the change is either "
5434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + "CHANGE_GONE or CHANGE_GONE_IDLE", validateUidRecord);
5444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            } else {
5454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertNotNull("validateUidRecord should not be null since the change is neither "
5464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + "CHANGE_GONE nor CHANGE_GONE_IDLE", validateUidRecord);
5474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertEquals("processState: " + item.processState + " curProcState: "
5484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + validateUidRecord.curProcState + " should have been equal",
5494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        item.processState, validateUidRecord.curProcState);
5504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertEquals("processState: " + item.processState + " setProcState: "
5514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + validateUidRecord.curProcState + " should have been equal",
5524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        item.processState, validateUidRecord.setProcState);
5534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                if (item.change == UidRecord.CHANGE_IDLE) {
5544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    assertTrue("UidRecord.idle should be updated to true for CHANGE_IDLE",
5554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            validateUidRecord.idle);
5564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                } else if (item.change == UidRecord.CHANGE_ACTIVE) {
5574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    assertFalse("UidRecord.idle should be updated to false for CHANGE_ACTIVE",
5584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            validateUidRecord.idle);
5594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                }
5604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
5614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
5624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when uid state changes to CHANGE_GONE or CHANGE_GONE_IDLE, then it
5644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // will be removed from validateUids.
56551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        assertNotEquals("validateUids should not be empty", 0, mAms.mValidateUids.size());
5664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
5674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
5684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // Assign CHANGE_GONE_IDLE to some items and CHANGE_GONE to the others, using even/odd
5694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // distribution for this assignment.
5704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.change = (i % 2) == 0 ? UidRecord.CHANGE_GONE_IDLE : UidRecord.CHANGE_GONE;
5714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
57251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
57351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
57451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        assertEquals("validateUids should be empty, validateUids: " + mAms.mValidateUids,
57551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                0, mAms.mValidateUids.size());
57651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
57751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
57851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @Test
57951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void testEnqueueUidChangeLocked_procStateSeqUpdated() {
58051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord uidRecord = new UidRecord(TEST_UID);
58151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
58251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
58351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Verify with no pending changes for TEST_UID.
58451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ1);
58551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
58651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Add a pending change for TEST_UID and verify enqueueUidChangeLocked still works as
58751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // expected.
58851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
58951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.pendingChange = changeItem;
59051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ2;
59151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ2);
59251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
59351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Use "null" uidRecord to make sure there is no crash.
59451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // TODO: currently it crashes, uncomment after fixing it.
59551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
59651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
59751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
59851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) {
59951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Test enqueueUidChangeLocked with every UidRecord.CHANGE_*
60051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
60151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final int changeToDispatch = UID_RECORD_CHANGES[i];
60251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Reset lastProcStateSeqDispatchToObservers after every test.
60351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            uidRecord.lastDispatchedProcStateSeq = 0;
60451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch);
60551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify there is no effect on curProcStateSeq.
60651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(curProcstateSeq, uidRecord.curProcStateSeq);
60751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            if (changeToDispatch == UidRecord.CHANGE_GONE
60851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                    || changeToDispatch == UidRecord.CHANGE_GONE_IDLE) {
60951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // Since the change is CHANGE_GONE or CHANGE_GONE_IDLE, verify that
61051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // lastProcStateSeqDispatchedToObservers is not updated.
61151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                assertNotEquals(uidRecord.curProcStateSeq,
61251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                        uidRecord.lastDispatchedProcStateSeq);
61351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            } else {
61451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // Since the change is neither CHANGE_GONE nor CHANGE_GONE_IDLE, verify that
61551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // lastProcStateSeqDispatchedToObservers has been updated to curProcStateSeq.
61651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                assertEquals(uidRecord.curProcStateSeq,
61751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                        uidRecord.lastDispatchedProcStateSeq);
61851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
61951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
62051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
62151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
62251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @MediumTest
62351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @Test
62451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void testEnqueueUidChangeLocked_dispatchUidsChanged() {
62551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord uidRecord = new UidRecord(TEST_UID);
62651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int expectedProcState = PROCESS_STATE_SERVICE;
62751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.setProcState = expectedProcState;
62851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
62951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
63051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Test with no pending uid records.
63151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
63251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final int changeToDispatch = UID_RECORD_CHANGES[i];
63351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
63451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Reset the current state
63551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mHandler.reset();
63651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            uidRecord.pendingChange = null;
63751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.mPendingUidChanges.clear();
63851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
63951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.enqueueUidChangeLocked(uidRecord, -1, changeToDispatch);
64051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
64151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify that UidRecord.pendingChange is updated correctly.
64251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertNotNull(uidRecord.pendingChange);
64351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(TEST_UID, uidRecord.pendingChange.uid);
64451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(expectedProcState, uidRecord.pendingChange.processState);
64551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(TEST_PROC_STATE_SEQ1, uidRecord.pendingChange.procStateSeq);
64651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
64751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify that DISPATCH_UIDS_CHANGED_UI_MSG is posted to handler.
64851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mHandler.waitForMessage(DISPATCH_UIDS_CHANGED_UI_MSG);
64951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
65051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
65151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
65284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @MediumTest
65384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @Test
65484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void testWaitForNetworkStateUpdate() throws Exception {
65584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Check there is no crash when there is no UidRecord for myUid
65684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.waitForNetworkStateUpdate(TEST_PROC_STATE_SEQ1);
65784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
65884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is no waiting when UidRecord.curProcStateSeq is greater than
65984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // the procStateSeq in the request to wait.
66084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
66184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
66284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
66384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 4, // lastNetworkUpdatedProcStateSeq
66484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 2, // procStateSeqToWait
66584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
66684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
66784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is no waiting when the procStateSeq in the request to wait is
66884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // not dispatched to NPMS.
66984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
67084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
67184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastDsipatchedProcStateSeq
67284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
67384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
67484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
67584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
67684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is not waiting when the procStateSeq in the request already has
67784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // an updated network state.
67884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
67984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
68084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
68184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastNetworkUpdatedProcStateSeq
68284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
68384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
68484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
68584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify waiting for network works
68684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
68784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
68884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
68984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
69084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
69184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                true); // expectWait
69284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
69384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
69484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq,
69584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            long lastDispatchedProcStateSeq, long lastNetworkUpdatedProcStateSeq,
69684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final long procStateSeqToWait, boolean expectWait) throws Exception {
69784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final UidRecord record = new UidRecord(Process.myUid());
69884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.curProcStateSeq = curProcStateSeq;
69984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.lastDispatchedProcStateSeq = lastDispatchedProcStateSeq;
70084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
70184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.put(Process.myUid(), record);
70284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
70384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        CustomThread thread = new CustomThread(record.lock, new Runnable() {
70484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            @Override
70584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            public void run() {
70684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                mAms.waitForNetworkStateUpdate(procStateSeqToWait);
70784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
70884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        });
70984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final String errMsg = "Unexpected state for " + record;
71084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        if (expectWait) {
71184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.startAndWait(errMsg, true);
71284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTimedWaiting(errMsg);
71384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            synchronized (record.lock) {
71484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                record.lock.notifyAll();
71584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
71684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated(errMsg);
71784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertTrue(thread.mNotified);
71884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertFalse(record.waitingForNetwork);
71984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        } else {
72084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.start();
72184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated(errMsg);
72284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
72384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
72484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.clear();
72584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
72684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
72751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private class TestHandler extends Handler {
72851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private static final long WAIT_FOR_MSG_TIMEOUT_MS = 4000; // 4 sec
72951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private static final long WAIT_FOR_MSG_INTERVAL_MS = 400; // 0.4 sec
73051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
73151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private Set<Integer> mMsgsHandled = new HashSet<>();
73251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
73351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        TestHandler(Looper looper) {
73451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            super(looper);
73551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
73651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
73751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
73851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void handleMessage(Message msg) {
73951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mMsgsHandled.add(msg.what);
74051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
74151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
74251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void waitForMessage(int msg) {
74351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final long endTime = System.currentTimeMillis() + WAIT_FOR_MSG_TIMEOUT_MS;
74451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            while (!mMsgsHandled.contains(msg) && System.currentTimeMillis() < endTime) {
74551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                SystemClock.sleep(WAIT_FOR_MSG_INTERVAL_MS);
74651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
74751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            if (!mMsgsHandled.contains(msg)) {
74851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                fail("Timed out waiting for the message to be handled, msg: " + msg);
74951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
75051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
75151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
75251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void reset() {
75351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mMsgsHandled.clear();
75451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
75551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
75651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
75784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private class TestInjector extends Injector {
75884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        private boolean mRestricted = true;
75984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
76051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
76184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public AppOpsService getAppOpsService(File file, Handler handler) {
76251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            return mAppOpsService;
76351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
76451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
76551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
76684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public Handler getUiHandler(ActivityManagerService service) {
76751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            return mHandler;
76851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
76984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
77084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        @Override
77184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public boolean isNetworkRestrictedForUid(int uid) {
77284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            return mRestricted;
77384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
77484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
77584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void setNetworkRestrictedForUid(boolean restricted) {
77684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            mRestricted = restricted;
77784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
7784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
77988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka}