ActivityManagerServiceTest.java revision deeb08fdcb2ccf90d013a9e909122e1a997c40bb
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;
54deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shankaimport android.content.Context;
5584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport android.content.pm.ApplicationInfo;
56deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shankaimport android.content.pm.PackageManager;
5751ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Handler;
5851ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.HandlerThread;
594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.IBinder;
6051ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Looper;
6151ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.Message;
624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.Process;
634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport android.os.RemoteException;
6451ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.os.SystemClock;
6551ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport android.support.test.filters.MediumTest;
6688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport android.support.test.filters.SmallTest;
6788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport android.support.test.runner.AndroidJUnit4;
6888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
6984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport com.android.internal.os.BatteryStatsImpl;
704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport com.android.server.AppOpsService;
714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
7251ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport org.junit.After;
734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.junit.Before;
7488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport org.junit.Test;
7588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport org.junit.runner.RunWith;
764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.Mock;
774c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.Mockito;
784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport org.mockito.MockitoAnnotations;
7988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
8084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport java.io.File;
814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.ArrayList;
824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.HashMap;
8351ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport java.util.HashSet;
844c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shankaimport java.util.Map;
8551ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport java.util.Set;
8688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankaimport java.util.function.Function;
8788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
8888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka/**
8988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Test class for {@link ActivityManagerService}.
9088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *
9188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * To run the tests, use
9288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *
9388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services
9488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *
9588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * or the following steps:
9688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *
9788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Build: m FrameworksServicesTests
9888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Install: adb install -r \
9988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
10088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerServiceTest -w \
10188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
10288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka */
10388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka@SmallTest
10488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka@RunWith(AndroidJUnit4.class)
10588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shankapublic class ActivityManagerServiceTest {
10651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private static final String TAG = ActivityManagerServiceTest.class.getSimpleName();
10751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
10888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    private static final int TEST_UID = 111;
10988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
11051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private static final long TEST_PROC_STATE_SEQ1 = 555;
11151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private static final long TEST_PROC_STATE_SEQ2 = 556;
11251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
11351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private static final int[] UID_RECORD_CHANGES = {
11451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_PROCSTATE,
11551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_GONE,
11651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_GONE_IDLE,
11751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_IDLE,
11851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        UidRecord.CHANGE_ACTIVE
11951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    };
12051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
121deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka    @Mock private Context mContext;
1224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Mock private AppOpsService mAppOpsService;
123deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka    @Mock private PackageManager mPackageManager;
1244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
12584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private TestInjector mInjector;
12651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private ActivityManagerService mAms;
12751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private HandlerThread mHandlerThread;
12851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private TestHandler mHandler;
12951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
1304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Before
1314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void setUp() {
1324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        MockitoAnnotations.initMocks(this);
13351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
13451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread = new HandlerThread(TAG);
13551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread.start();
13651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandler = new TestHandler(mHandlerThread.getLooper());
13784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mInjector = new TestInjector();
13884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms = new ActivityManagerService(mInjector);
1395918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        mAms.mWaitForNetworkTimeoutMs = 100;
140deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka
141deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        when(mContext.getPackageManager()).thenReturn(mPackageManager);
14251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
14351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
14451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @After
14551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void tearDown() {
14651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread.quit();
1474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
1484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
14984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @MediumTest
15088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    @Test
15184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void incrementProcStateSeqAndNotifyAppsLocked() throws Exception {
15288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        final UidRecord uidRec = new UidRecord(TEST_UID);
15384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.waitingForNetwork = true;
15484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.put(TEST_UID, uidRec);
15584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
15684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final BatteryStatsImpl batteryStats = Mockito.mock(BatteryStatsImpl.class);
15784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final ProcessRecord appRec = new ProcessRecord(batteryStats,
15884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                new ApplicationInfo(), TAG, TEST_UID);
15984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        appRec.thread = Mockito.mock(IApplicationThread.class);
16084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mLruProcesses.add(appRec);
16188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
16284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final ProcessRecord appRec2 = new ProcessRecord(batteryStats,
16384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                new ApplicationInfo(), TAG, TEST_UID + 1);
16484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        appRec2.thread = Mockito.mock(IApplicationThread.class);
16584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mLruProcesses.add(appRec2);
16688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
16788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is not moving from background to foreground or vice versa.
16884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
16984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // prevState
17084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
17184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                0, // expectedGlobalCounter
17284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                0, // exptectedCurProcStateSeq
17384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_NO_CHANGE, // expectedBlockState
17484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
17588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
17688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is moving from foreground to background.
17784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
17884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_FOREGROUND_SERVICE, // prevState
17984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_SERVICE, // curState
18084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // expectedGlobalCounter
18184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // exptectedCurProcStateSeq
18284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_UNBLOCK, // expectedBlockState
18384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                true); // expectNotify
18488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
18588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Explicitly setting the seq counter for more verification.
18651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mProcStateSeqCounter = 42;
18788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
18888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is not moving from background to foreground or vice versa.
18984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
19084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
19184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_FOREGROUND, // curState
19284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                42, // expectedGlobalCounter
19384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // exptectedCurProcStateSeq
19484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_NO_CHANGE, // expectedBlockState
19584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
19688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
19788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is moving from background to foreground.
19884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
19984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_LAST_ACTIVITY, // prevState
20084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
20184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                43, // expectedGlobalCounter
20284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                43, // exptectedCurProcStateSeq
20384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_BLOCK, // expectedBlockState
20484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
20584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
20684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // verify waiting threads are not notified.
20784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.waitingForNetwork = false;
20884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Uid state is moving from foreground to background.
20984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
21084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_FOREGROUND_SERVICE, // prevState
21184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_SERVICE, // curState
21284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // expectedGlobalCounter
21384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // exptectedCurProcStateSeq
21484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_UNBLOCK, // expectedBlockState
21584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
21684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
21784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify when uid is not restricted, procStateSeq is not incremented.
21884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.waitingForNetwork = true;
21984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mInjector.setNetworkRestrictedForUid(false);
22084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
22184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
22284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
22384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // expectedGlobalCounter
22484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // exptectedCurProcStateSeq
22584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
22684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
2275918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka
2285918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        // Verify when waitForNetworkTimeout is 0, then procStateSeq is not incremented.
2295918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        mAms.mWaitForNetworkTimeoutMs = 0;
2305918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        mInjector.setNetworkRestrictedForUid(true);
2315918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
2325918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                PROCESS_STATE_TOP, // prevState
2335918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                PROCESS_STATE_IMPORTANT_BACKGROUND, // curState
2345918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                44, // expectedGlobalCounter
2355918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                44, // exptectedCurProcStateSeq
2365918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
2375918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                false); // expectNotify
23884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
23984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
24084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private void verifySeqCounterAndInteractions(UidRecord uidRec, int prevState, int curState,
24184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            int expectedGlobalCounter, int expectedCurProcStateSeq, int expectedBlockState,
24284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            boolean expectNotify) throws Exception {
24384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        CustomThread thread = new CustomThread(uidRec.lock);
24484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        thread.startAndWait("Unexpected state for " + uidRec);
24584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
24684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.setProcState = prevState;
24784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.curProcState = curState;
24884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.incrementProcStateSeqAndNotifyAppsLocked();
24984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
25084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(expectedGlobalCounter, mAms.mProcStateSeqCounter);
25184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(expectedCurProcStateSeq, uidRec.curProcStateSeq);
25284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
25384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        for (int i = mAms.mLruProcesses.size() - 1; i >= 0; --i) {
25484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final ProcessRecord app = mAms.mLruProcesses.get(i);
25584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            // AMS should notify apps only for block states other than NETWORK_STATE_NO_CHANGE.
25684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            if (app.uid == uidRec.uid && expectedBlockState == NETWORK_STATE_BLOCK) {
25784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                verify(app.thread).setNetworkBlockSeq(uidRec.curProcStateSeq);
25884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            } else {
25984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                verifyZeroInteractions(app.thread);
26084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
26184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            Mockito.reset(app.thread);
26284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
26384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
26484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        if (expectNotify) {
26584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated("Unexpected state for " + uidRec);
26684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        } else {
26784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertWaiting("Unexpected state for " + uidRec);
26884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.interrupt();
26984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
27088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    }
27188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
27288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    @Test
27384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void testBlockStateForUid() {
27488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        final UidRecord uidRec = new UidRecord(TEST_UID);
27584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        int expectedBlockState;
27688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
27784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final String errorTemplate = "Block state should be %s, prevState: %s, curState: %s";
27884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        Function<Integer, String> errorMsg = (blockState) -> {
27988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka            return String.format(errorTemplate,
28084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    valueToString(ActivityManagerService.class, "NETWORK_STATE_", blockState),
28188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.setProcState),
28288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.curProcState));
28388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        };
28488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
28588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // No change in uid state
28688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_RECEIVER;
28788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_RECEIVER;
28884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
28984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
29084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
29188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
29288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Foreground to foreground
29388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_FOREGROUND_SERVICE;
29488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
29584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
29684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
29784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
29888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
29988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to background
30088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_CACHED_ACTIVITY;
30188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_CACHED_EMPTY;
30284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
30384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
30484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
30588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
30688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to background
30788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_NONEXISTENT;
30888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_CACHED_ACTIVITY;
30984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
31084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
31184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
31288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
31388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to foreground
31488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_SERVICE;
31588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE;
31684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_BLOCK;
31784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
31884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
31988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
32088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Foreground to background
32188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_TOP;
32288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_LAST_ACTIVITY;
32384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_UNBLOCK;
32484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
32584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
32688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    }
3274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
3294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that process state changes are dispatched to observers based on the
3304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * changes they wanted to listen (this is specified when registering the observer).
3314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
3324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
3334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUids_dispatchNeededChanges() throws RemoteException {
3344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS, Process.myUid(), null))
3354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                .thenReturn(AppOpsManager.MODE_ALLOWED);
3364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] changesToObserve = {
3384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_PROCSTATE,
3394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_GONE,
3404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_IDLE,
3414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_ACTIVE,
3424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE
3434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    | ActivityManager.UID_OBSERVER_ACTIVE | ActivityManager.UID_OBSERVER_IDLE
3444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
3454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length];
3464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < observers.length; ++i) {
3474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            observers[i] = Mockito.mock(IUidObserver.Stub.class);
3484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            when(observers[i].asBinder()).thenReturn((IBinder) observers[i]);
34951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.registerUidObserver(observers[i], changesToObserve[i] /* which */,
3504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */);
3514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // When we invoke AMS.registerUidObserver, there are some interactions with observers[i]
3534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // mock in RemoteCallbackList class. We don't want to test those interactions and
3544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
3554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // So, resetting the mock here.
3564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            Mockito.reset(observers[i]);
3574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
3584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Add pending uid records each corresponding to a different change type UidRecord.CHANGE_*
36051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int[] changesForPendingUidRecords = UID_RECORD_CHANGES;
36151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
3624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] procStatesForPendingUidRecords = {
3634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
3644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_NONEXISTENT,
3654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
3664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
3674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_TOP
3684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
3694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final Map<Integer, UidRecord.ChangeItem> changeItems = new HashMap<>();
3704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < changesForPendingUidRecords.length; ++i) {
3714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem pendingChange = new UidRecord.ChangeItem();
3724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.change = changesForPendingUidRecords[i];
3734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.uid = i;
3744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.processState = procStatesForPendingUidRecords[i];
3758025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka            pendingChange.procStateSeq = i;
3764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            changeItems.put(changesForPendingUidRecords[i], pendingChange);
37751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.mPendingUidChanges.add(pendingChange);
3784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
3794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
38051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
3814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify the required changes have been dispatched to observers.
3824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < observers.length; ++i) {
3834c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final int changeToObserve = changesToObserve[i];
3844c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final IUidObserver observerToTest = observers[i];
3854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid idle changes, so change items corresponding to
3874c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_IDLE or UidRecord.CHANGE_IDLE_GONE needs to be
3884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // delivered to this observer.
3894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
3904c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    UidRecord.CHANGE_IDLE,
3914c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    UidRecord.CHANGE_GONE_IDLE
3924c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
3934c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
3944c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
3954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidIdle(changeItem.uid, changeItem.ephemeral);
3964c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
3974c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
3984c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3994c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid active changes, so change items corresponding to
4004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_ACTIVE needs to be delivered to this observer.
4014c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = { UidRecord.CHANGE_ACTIVE };
4024c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
4034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
4044c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidActive(changeItem.uid);
4054c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4064c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4074c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_GONE) != 0) {
4084c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid gone changes, so change items corresponding to
4094c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_GONE or UidRecord.CHANGE_IDLE_GONE needs to be
4104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // delivered to this observer.
4114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
4124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_GONE,
4134c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_GONE_IDLE
4144c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
4154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
4164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
4174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidGone(changeItem.uid, changeItem.ephemeral);
4184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid procState changes, so change items corresponding to
4224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_PROCSTATE or UidRecord.CHANGE_IDLE or UidRecord.CHANGE_ACTIVE
4234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // needs to be delivered to this observer.
4244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
4254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_PROCSTATE,
4264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_ACTIVE,
4274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_IDLE
4284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
4294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
4304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
4318025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                            verify(observer).onUidStateChanged(changeItem.uid,
4328025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                                    changeItem.processState, changeItem.procStateSeq);
4334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // Verify there are no other callbacks for this observer.
4364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            verifyNoMoreInteractions(observerToTest);
4374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
4384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    private interface ObserverChangesVerifier {
4414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        void verify(IUidObserver observer, UidRecord.ChangeItem changeItem) throws RemoteException;
4424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    private void verifyObserverReceivedChanges(IUidObserver observer, int[] changesToVerify,
4454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            Map<Integer, UidRecord.ChangeItem> changeItems, ObserverChangesVerifier verifier)
4464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            throws RemoteException {
4474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int change : changesToVerify) {
4484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem changeItem = changeItems.get(change);
4494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            verifier.verify(observer, changeItem);
4504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
4514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
4544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that process state changes are dispatched to observers only when they
4554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * change across the cutpoint (this is specified when registering the observer).
4564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
4574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
4584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUidChanges_procStateCutpoint() throws RemoteException {
4594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
4604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(observer.asBinder()).thenReturn((IBinder) observer);
46251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */,
4634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */);
4644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // When we invoke AMS.registerUidObserver, there are some interactions with observer
4654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // mock in RemoteCallbackList class. We don't want to test those interactions and
4664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
4674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // So, resetting the mock here.
4684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        Mockito.reset(observer);
4694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
4714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.uid = TEST_UID;
4724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.change = UidRecord.CHANGE_PROCSTATE;
4734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
4748025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka        changeItem.procStateSeq = 111;
47551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
47651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4774c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // First process state message is always delivered regardless of whether the process state
4784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // change is above or below the cutpoint (PROCESS_STATE_SERVICE).
4794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
4808025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
4814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
4824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4834c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_RECEIVER;
48451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
48551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
4874c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is also below cutpoint, so no callback will be invoked.
4884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
4894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4904c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
49151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
49251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4934c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
4944c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is above cutpoint, so callback will be invoked with the
4954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // current process state change.
4964c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
4978025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
4984c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
4994c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_TOP;
50151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
50251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
5044c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is also above cutpoint, so no callback will be invoked.
5054c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
5064c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5074c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
50851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
50951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
5114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is below cutpoint, so callback will be invoked with the
5124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // current process state change.
5138025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
5148025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
5154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
5164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
5174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
5194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that {@link ActivityManagerService#mValidateUids} which is a
5204c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * part of dumpsys is correctly updated.
5214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
5224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
5234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUidChanges_validateUidsUpdated() {
52451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int[] changesForPendingItems = UID_RECORD_CHANGES;
52551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
5264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] procStatesForPendingItems = {
5274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
5284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
5294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
5304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_SERVICE,
5314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_RECEIVER
5324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
5334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final ArrayList<UidRecord.ChangeItem> pendingItemsForUids
5344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                = new ArrayList<>(changesForPendingItems.length);
5354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < changesForPendingItems.length; ++i) {
5364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = new UidRecord.ChangeItem();
5374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.uid = i;
5384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.change = changesForPendingItems[i];
5394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.processState = procStatesForPendingItems[i];
5404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingItemsForUids.add(i, item);
5414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
5424c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when there no observers listening to uid state changes, then there will
5444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // be no changes to validateUids.
54551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
54651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        assertEquals("No observers registered, so validateUids should be empty",
54851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                0, mAms.mValidateUids.size());
5494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
5514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(observer.asBinder()).thenReturn((IBinder) observer);
55251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.registerUidObserver(observer, 0, 0, null);
5534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when observers are registered, then validateUids is correctly updated.
55451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
55551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
5574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
55851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final UidRecord validateUidRecord = mAms.mValidateUids.get(item.uid);
5594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if (item.change == UidRecord.CHANGE_GONE || item.change == UidRecord.CHANGE_GONE_IDLE) {
5604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertNull("validateUidRecord should be null since the change is either "
5614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + "CHANGE_GONE or CHANGE_GONE_IDLE", validateUidRecord);
5624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            } else {
5634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertNotNull("validateUidRecord should not be null since the change is neither "
5644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + "CHANGE_GONE nor CHANGE_GONE_IDLE", validateUidRecord);
5654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertEquals("processState: " + item.processState + " curProcState: "
5664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + validateUidRecord.curProcState + " should have been equal",
5674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        item.processState, validateUidRecord.curProcState);
5684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertEquals("processState: " + item.processState + " setProcState: "
5694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + validateUidRecord.curProcState + " should have been equal",
5704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        item.processState, validateUidRecord.setProcState);
5714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                if (item.change == UidRecord.CHANGE_IDLE) {
5724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    assertTrue("UidRecord.idle should be updated to true for CHANGE_IDLE",
5734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            validateUidRecord.idle);
5744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                } else if (item.change == UidRecord.CHANGE_ACTIVE) {
5754c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    assertFalse("UidRecord.idle should be updated to false for CHANGE_ACTIVE",
5764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            validateUidRecord.idle);
5774c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                }
5784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
5794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
5804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when uid state changes to CHANGE_GONE or CHANGE_GONE_IDLE, then it
5824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // will be removed from validateUids.
58351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        assertNotEquals("validateUids should not be empty", 0, mAms.mValidateUids.size());
5844c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
5854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
5864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // Assign CHANGE_GONE_IDLE to some items and CHANGE_GONE to the others, using even/odd
5874c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // distribution for this assignment.
5884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.change = (i % 2) == 0 ? UidRecord.CHANGE_GONE_IDLE : UidRecord.CHANGE_GONE;
5894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
59051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
59151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
59251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        assertEquals("validateUids should be empty, validateUids: " + mAms.mValidateUids,
59351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                0, mAms.mValidateUids.size());
59451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
59551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
59651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @Test
59751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void testEnqueueUidChangeLocked_procStateSeqUpdated() {
59851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord uidRecord = new UidRecord(TEST_UID);
59951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
60051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
60151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Verify with no pending changes for TEST_UID.
60251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ1);
60351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
60451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Add a pending change for TEST_UID and verify enqueueUidChangeLocked still works as
60551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // expected.
60651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
60751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.pendingChange = changeItem;
60851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ2;
60951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ2);
610deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka    }
61151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
612deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka    @Test
613deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka    public void testEnqueueUidChangeLocked_nullUidRecord() {
61451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Use "null" uidRecord to make sure there is no crash.
615deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
61651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
61751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
61851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) {
61951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Test enqueueUidChangeLocked with every UidRecord.CHANGE_*
62051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
62151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final int changeToDispatch = UID_RECORD_CHANGES[i];
62251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Reset lastProcStateSeqDispatchToObservers after every test.
62351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            uidRecord.lastDispatchedProcStateSeq = 0;
62451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch);
62551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify there is no effect on curProcStateSeq.
62651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(curProcstateSeq, uidRecord.curProcStateSeq);
62751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            if (changeToDispatch == UidRecord.CHANGE_GONE
62851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                    || changeToDispatch == UidRecord.CHANGE_GONE_IDLE) {
62951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // Since the change is CHANGE_GONE or CHANGE_GONE_IDLE, verify that
63051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // lastProcStateSeqDispatchedToObservers is not updated.
63151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                assertNotEquals(uidRecord.curProcStateSeq,
63251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                        uidRecord.lastDispatchedProcStateSeq);
63351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            } else {
63451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // Since the change is neither CHANGE_GONE nor CHANGE_GONE_IDLE, verify that
63551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // lastProcStateSeqDispatchedToObservers has been updated to curProcStateSeq.
63651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                assertEquals(uidRecord.curProcStateSeq,
63751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                        uidRecord.lastDispatchedProcStateSeq);
63851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
63951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
64051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
64151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
64251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @MediumTest
64351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @Test
64451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void testEnqueueUidChangeLocked_dispatchUidsChanged() {
64551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord uidRecord = new UidRecord(TEST_UID);
64651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int expectedProcState = PROCESS_STATE_SERVICE;
64751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.setProcState = expectedProcState;
64851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
64951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
65051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Test with no pending uid records.
65151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
65251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final int changeToDispatch = UID_RECORD_CHANGES[i];
65351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
65451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Reset the current state
65551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mHandler.reset();
65651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            uidRecord.pendingChange = null;
65751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.mPendingUidChanges.clear();
65851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
65951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.enqueueUidChangeLocked(uidRecord, -1, changeToDispatch);
66051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
66151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify that UidRecord.pendingChange is updated correctly.
66251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertNotNull(uidRecord.pendingChange);
66351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(TEST_UID, uidRecord.pendingChange.uid);
66451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(expectedProcState, uidRecord.pendingChange.processState);
66551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(TEST_PROC_STATE_SEQ1, uidRecord.pendingChange.procStateSeq);
66651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
66751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify that DISPATCH_UIDS_CHANGED_UI_MSG is posted to handler.
66851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mHandler.waitForMessage(DISPATCH_UIDS_CHANGED_UI_MSG);
66951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
67051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
67151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
67284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @MediumTest
67384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @Test
67484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void testWaitForNetworkStateUpdate() throws Exception {
67584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Check there is no crash when there is no UidRecord for myUid
67684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.waitForNetworkStateUpdate(TEST_PROC_STATE_SEQ1);
67784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
67884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is no waiting when UidRecord.curProcStateSeq is greater than
67984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // the procStateSeq in the request to wait.
68084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
68184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
68284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
68384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 4, // lastNetworkUpdatedProcStateSeq
68484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 2, // procStateSeqToWait
68584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
68684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
68784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is no waiting when the procStateSeq in the request to wait is
68884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // not dispatched to NPMS.
68984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
69084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
69184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastDsipatchedProcStateSeq
69284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
69384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
69484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
69584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
69684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is not waiting when the procStateSeq in the request already has
69784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // an updated network state.
69884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
69984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
70084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
70184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastNetworkUpdatedProcStateSeq
70284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
70384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
70484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
70584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify waiting for network works
70684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
70784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
70884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
70984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
71084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
71184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                true); // expectWait
71284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
71384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
71484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq,
71584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            long lastDispatchedProcStateSeq, long lastNetworkUpdatedProcStateSeq,
71684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final long procStateSeqToWait, boolean expectWait) throws Exception {
71784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final UidRecord record = new UidRecord(Process.myUid());
71884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.curProcStateSeq = curProcStateSeq;
71984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.lastDispatchedProcStateSeq = lastDispatchedProcStateSeq;
72084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
72184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.put(Process.myUid(), record);
72284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
72384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        CustomThread thread = new CustomThread(record.lock, new Runnable() {
72484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            @Override
72584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            public void run() {
72684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                mAms.waitForNetworkStateUpdate(procStateSeqToWait);
72784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
72884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        });
72984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final String errMsg = "Unexpected state for " + record;
73084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        if (expectWait) {
73184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.startAndWait(errMsg, true);
73284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTimedWaiting(errMsg);
73384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            synchronized (record.lock) {
73484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                record.lock.notifyAll();
73584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
73684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated(errMsg);
73784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertTrue(thread.mNotified);
73884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertFalse(record.waitingForNetwork);
73984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        } else {
74084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.start();
74184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated(errMsg);
74284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
74384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
74484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.clear();
74584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
74684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
74751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private class TestHandler extends Handler {
74851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private static final long WAIT_FOR_MSG_TIMEOUT_MS = 4000; // 4 sec
74951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private static final long WAIT_FOR_MSG_INTERVAL_MS = 400; // 0.4 sec
75051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
75151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private Set<Integer> mMsgsHandled = new HashSet<>();
75251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
75351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        TestHandler(Looper looper) {
75451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            super(looper);
75551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
75651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
75751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
75851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void handleMessage(Message msg) {
75951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mMsgsHandled.add(msg.what);
76051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
76151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
76251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void waitForMessage(int msg) {
76351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final long endTime = System.currentTimeMillis() + WAIT_FOR_MSG_TIMEOUT_MS;
76451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            while (!mMsgsHandled.contains(msg) && System.currentTimeMillis() < endTime) {
76551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                SystemClock.sleep(WAIT_FOR_MSG_INTERVAL_MS);
76651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
76751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            if (!mMsgsHandled.contains(msg)) {
76851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                fail("Timed out waiting for the message to be handled, msg: " + msg);
76951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
77051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
77151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
77251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void reset() {
77351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mMsgsHandled.clear();
77451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
77551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
77651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
77784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private class TestInjector extends Injector {
77884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        private boolean mRestricted = true;
77984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
78051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
781deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        public Context getContext() {
782deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka            return mContext;
783deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        }
784deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka
785deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        @Override
78684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public AppOpsService getAppOpsService(File file, Handler handler) {
78751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            return mAppOpsService;
78851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
78951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
79051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
79184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public Handler getUiHandler(ActivityManagerService service) {
79251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            return mHandler;
79351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
79484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
79584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        @Override
79684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public boolean isNetworkRestrictedForUid(int uid) {
79784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            return mRestricted;
79884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
79984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
80084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void setNetworkRestrictedForUid(boolean restricted) {
80184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            mRestricted = restricted;
80284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
8034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
80488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka}