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
108f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka    private static final int TEST_UID = 11111;
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,
1163e99f654fbf56d3b7ef7130658b8ef83d2d0cdbdDianne Hackborn        UidRecord.CHANGE_GONE | UidRecord.CHANGE_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;
124f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka    @Mock private BatteryStatsImpl mBatteryStatsImpl;
1254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
12684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private TestInjector mInjector;
12751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private ActivityManagerService mAms;
12851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private HandlerThread mHandlerThread;
12951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private TestHandler mHandler;
13051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
1314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Before
1324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void setUp() {
1334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        MockitoAnnotations.initMocks(this);
13451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
13551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread = new HandlerThread(TAG);
13651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread.start();
13751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandler = new TestHandler(mHandlerThread.getLooper());
13884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mInjector = new TestInjector();
13984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms = new ActivityManagerService(mInjector);
1409d3f668d09dea3e8f14094c2efae9fdd7ce25908Sudheer Shanka        mAms.mWaitForNetworkTimeoutMs = 2000;
141deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka
142deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        when(mContext.getPackageManager()).thenReturn(mPackageManager);
14351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
14451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
14551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @After
14651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void tearDown() {
14751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mHandlerThread.quit();
1484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
1494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
15084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @MediumTest
15188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    @Test
15284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void incrementProcStateSeqAndNotifyAppsLocked() throws Exception {
15384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
154f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        final UidRecord uidRec = addUidRecord(TEST_UID);
155f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        addUidRecord(TEST_UID + 1);
15688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
15788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is not moving from background to foreground or vice versa.
15884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
15984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // prevState
16084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
16184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                0, // expectedGlobalCounter
16284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                0, // exptectedCurProcStateSeq
16384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_NO_CHANGE, // expectedBlockState
16484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
16588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
16688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is moving from foreground to background.
16784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
16884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_FOREGROUND_SERVICE, // prevState
16984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_SERVICE, // curState
17084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // expectedGlobalCounter
17184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // exptectedCurProcStateSeq
17284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_UNBLOCK, // expectedBlockState
17384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                true); // expectNotify
17488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
17588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Explicitly setting the seq counter for more verification.
17651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mProcStateSeqCounter = 42;
17788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
17888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is not moving from background to foreground or vice versa.
17984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
18084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
18184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_FOREGROUND, // curState
18284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                42, // expectedGlobalCounter
18384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                1, // exptectedCurProcStateSeq
18484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_NO_CHANGE, // expectedBlockState
18584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
18688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
18788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Uid state is moving from background to foreground.
18884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
18984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_LAST_ACTIVITY, // prevState
19084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
19184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                43, // expectedGlobalCounter
19284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                43, // exptectedCurProcStateSeq
19384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_BLOCK, // expectedBlockState
19484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
19584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
19684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // verify waiting threads are not notified.
19784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.waitingForNetwork = false;
19884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Uid state is moving from foreground to background.
19984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
20084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_FOREGROUND_SERVICE, // prevState
20184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_SERVICE, // curState
20284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // expectedGlobalCounter
20384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // exptectedCurProcStateSeq
20484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                NETWORK_STATE_UNBLOCK, // expectedBlockState
20584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
20684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
20784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify when uid is not restricted, procStateSeq is not incremented.
20884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.waitingForNetwork = true;
20984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mInjector.setNetworkRestrictedForUid(false);
21084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
21184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_IMPORTANT_BACKGROUND, // prevState
21284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                PROCESS_STATE_TOP, // curState
21384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // expectedGlobalCounter
21484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                44, // exptectedCurProcStateSeq
21584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
21684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
2175918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka
2185918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        // Verify when waitForNetworkTimeout is 0, then procStateSeq is not incremented.
2195918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        mAms.mWaitForNetworkTimeoutMs = 0;
2205918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        mInjector.setNetworkRestrictedForUid(true);
2215918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
2225918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                PROCESS_STATE_TOP, // prevState
2235918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                PROCESS_STATE_IMPORTANT_BACKGROUND, // curState
2245918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                44, // expectedGlobalCounter
2255918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                44, // exptectedCurProcStateSeq
2265918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
2275918c6700bd8e660abbf2c8f78cac5ea6a947374Sudheer Shanka                false); // expectNotify
228f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka
229f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        // Verify when the uid doesn't have internet permission, then procStateSeq is not
230f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        // incremented.
231f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        uidRec.hasInternetPermission = false;
232f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        mAms.mWaitForNetworkTimeoutMs = 111;
233f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        mInjector.setNetworkRestrictedForUid(true);
234f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        verifySeqCounterAndInteractions(uidRec,
235f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                PROCESS_STATE_CACHED_ACTIVITY, // prevState
236f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                PROCESS_STATE_FOREGROUND_SERVICE, // curState
237f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                44, // expectedGlobalCounter
238f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                44, // exptectedCurProcStateSeq
239f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
240f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                false); // expectNotify
241f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka
242f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        // Verify procStateSeq is not incremented when the uid is not an application, regardless
243f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        // of the process state.
244f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        final int notAppUid = 111;
245f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        final UidRecord uidRec2 = addUidRecord(notAppUid);
246f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        verifySeqCounterAndInteractions(uidRec2,
247f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                PROCESS_STATE_CACHED_EMPTY, // prevState
248f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                PROCESS_STATE_TOP, // curState
249f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                44, // expectedGlobalCounter
250f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                0, // exptectedCurProcStateSeq
251f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
252f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                false); // expectNotify
253f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka    }
254f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka
255f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka    private UidRecord addUidRecord(int uid) {
256f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        final UidRecord uidRec = new UidRecord(uid);
257f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        uidRec.waitingForNetwork = true;
258f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        uidRec.hasInternetPermission = true;
259f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        mAms.mActiveUids.put(uid, uidRec);
260f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka
261f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        final ProcessRecord appRec = new ProcessRecord(mBatteryStatsImpl,
262f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                new ApplicationInfo(), TAG, uid);
263f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        appRec.thread = Mockito.mock(IApplicationThread.class);
264f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        mAms.mLruProcesses.add(appRec);
265f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka
266f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        return uidRec;
26784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
26884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
26984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private void verifySeqCounterAndInteractions(UidRecord uidRec, int prevState, int curState,
27084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            int expectedGlobalCounter, int expectedCurProcStateSeq, int expectedBlockState,
27184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            boolean expectNotify) throws Exception {
272f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        CustomThread thread = new CustomThread(uidRec.networkStateLock);
27384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        thread.startAndWait("Unexpected state for " + uidRec);
27484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
27584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.setProcState = prevState;
27684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        uidRec.curProcState = curState;
27784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.incrementProcStateSeqAndNotifyAppsLocked();
27884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
27984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(expectedGlobalCounter, mAms.mProcStateSeqCounter);
28084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(expectedCurProcStateSeq, uidRec.curProcStateSeq);
28184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
28284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        for (int i = mAms.mLruProcesses.size() - 1; i >= 0; --i) {
28384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final ProcessRecord app = mAms.mLruProcesses.get(i);
28484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            // AMS should notify apps only for block states other than NETWORK_STATE_NO_CHANGE.
28584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            if (app.uid == uidRec.uid && expectedBlockState == NETWORK_STATE_BLOCK) {
28684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                verify(app.thread).setNetworkBlockSeq(uidRec.curProcStateSeq);
28784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            } else {
28884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                verifyZeroInteractions(app.thread);
28984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
29084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            Mockito.reset(app.thread);
29184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
29284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
29384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        if (expectNotify) {
29484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated("Unexpected state for " + uidRec);
29584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        } else {
29684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertWaiting("Unexpected state for " + uidRec);
29784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.interrupt();
29884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
29988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    }
30088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
30188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    @Test
30284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void testBlockStateForUid() {
30388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        final UidRecord uidRec = new UidRecord(TEST_UID);
30484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        int expectedBlockState;
30588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
30684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final String errorTemplate = "Block state should be %s, prevState: %s, curState: %s";
30784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        Function<Integer, String> errorMsg = (blockState) -> {
30888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka            return String.format(errorTemplate,
30984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    valueToString(ActivityManagerService.class, "NETWORK_STATE_", blockState),
31088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.setProcState),
31188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.curProcState));
31288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        };
31388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
31488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // No change in uid state
31588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_RECEIVER;
31688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_RECEIVER;
31784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
31884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
31984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
32088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
32188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Foreground to foreground
32288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_FOREGROUND_SERVICE;
32388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
32484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
32584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
32684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
32788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
32888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to background
32988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_CACHED_ACTIVITY;
33088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_CACHED_EMPTY;
33184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
33284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
33384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
33488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
33588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to background
33688c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_NONEXISTENT;
33788c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_CACHED_ACTIVITY;
33884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_NO_CHANGE;
33984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
34084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
34188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
34288c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Background to foreground
34388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_SERVICE;
34488c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE;
34584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_BLOCK;
34684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
34784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
34888c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka
34988c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        // Foreground to background
35088c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.setProcState = PROCESS_STATE_TOP;
35188c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka        uidRec.curProcState = PROCESS_STATE_LAST_ACTIVITY;
35284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        expectedBlockState = NETWORK_STATE_UNBLOCK;
35384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(errorMsg.apply(expectedBlockState),
35484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedBlockState, mAms.getBlockStateForUid(uidRec));
35588c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka    }
3564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
3584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that process state changes are dispatched to observers based on the
3594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * changes they wanted to listen (this is specified when registering the observer).
3604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
3614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
3624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUids_dispatchNeededChanges() throws RemoteException {
3634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS, Process.myUid(), null))
3644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                .thenReturn(AppOpsManager.MODE_ALLOWED);
3654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] changesToObserve = {
3674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_PROCSTATE,
3684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_GONE,
3694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_IDLE,
3704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_ACTIVE,
3714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE
3724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    | ActivityManager.UID_OBSERVER_ACTIVE | ActivityManager.UID_OBSERVER_IDLE
3734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
3744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length];
3754c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < observers.length; ++i) {
3764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            observers[i] = Mockito.mock(IUidObserver.Stub.class);
3774c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            when(observers[i].asBinder()).thenReturn((IBinder) observers[i]);
37851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.registerUidObserver(observers[i], changesToObserve[i] /* which */,
3794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */);
3804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // When we invoke AMS.registerUidObserver, there are some interactions with observers[i]
3824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // mock in RemoteCallbackList class. We don't want to test those interactions and
3834c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
3844c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // So, resetting the mock here.
3854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            Mockito.reset(observers[i]);
3864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
3874c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
3884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Add pending uid records each corresponding to a different change type UidRecord.CHANGE_*
38951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int[] changesForPendingUidRecords = UID_RECORD_CHANGES;
39051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
3914c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] procStatesForPendingUidRecords = {
3924c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
3934c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_NONEXISTENT,
3944c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
3954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
3964c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_TOP
3974c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
3984c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final Map<Integer, UidRecord.ChangeItem> changeItems = new HashMap<>();
3994c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < changesForPendingUidRecords.length; ++i) {
4004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem pendingChange = new UidRecord.ChangeItem();
4014c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.change = changesForPendingUidRecords[i];
4024c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.uid = i;
4034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingChange.processState = procStatesForPendingUidRecords[i];
4048025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka            pendingChange.procStateSeq = i;
4054c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            changeItems.put(changesForPendingUidRecords[i], pendingChange);
40651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.mPendingUidChanges.add(pendingChange);
4074c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
4084c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
40951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
4104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify the required changes have been dispatched to observers.
4114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < observers.length; ++i) {
4124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final int changeToObserve = changesToObserve[i];
4134c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final IUidObserver observerToTest = observers[i];
4144c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid idle changes, so change items corresponding to
4164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_IDLE or UidRecord.CHANGE_IDLE_GONE needs to be
4174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // delivered to this observer.
4184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
4194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    UidRecord.CHANGE_IDLE,
4203e99f654fbf56d3b7ef7130658b8ef83d2d0cdbdDianne Hackborn                    UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE
4214c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
4224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
4234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
4244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidIdle(changeItem.uid, changeItem.ephemeral);
4254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4264c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid active changes, so change items corresponding to
4294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_ACTIVE needs to be delivered to this observer.
4304c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = { UidRecord.CHANGE_ACTIVE };
4314c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
4324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
4334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidActive(changeItem.uid);
4344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_GONE) != 0) {
4374c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid gone changes, so change items corresponding to
4384c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_GONE or UidRecord.CHANGE_IDLE_GONE needs to be
4394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // delivered to this observer.
4404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
4414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_GONE,
4423e99f654fbf56d3b7ef7130658b8ef83d2d0cdbdDianne Hackborn                        UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE
4434c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
4444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
4454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
4464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            verify(observer).onUidGone(changeItem.uid, changeItem.ephemeral);
4474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            if ((changeToObserve & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // Observer listens to uid procState changes, so change items corresponding to
4514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // UidRecord.CHANGE_PROCSTATE or UidRecord.CHANGE_IDLE or UidRecord.CHANGE_ACTIVE
4524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                // needs to be delivered to this observer.
4534c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                final int[] changesToVerify = {
4544c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_PROCSTATE,
4554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_ACTIVE,
4564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        UidRecord.CHANGE_IDLE
4574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                };
4584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
4594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        (observer, changeItem) -> {
4608025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                            verify(observer).onUidStateChanged(changeItem.uid,
4618025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                                    changeItem.processState, changeItem.procStateSeq);
4624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        });
4634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
4644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // Verify there are no other callbacks for this observer.
4654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            verifyNoMoreInteractions(observerToTest);
4664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
4674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    private interface ObserverChangesVerifier {
4704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        void verify(IUidObserver observer, UidRecord.ChangeItem changeItem) throws RemoteException;
4714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    private void verifyObserverReceivedChanges(IUidObserver observer, int[] changesToVerify,
4744c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            Map<Integer, UidRecord.ChangeItem> changeItems, ObserverChangesVerifier verifier)
4754c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            throws RemoteException {
4764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int change : changesToVerify) {
4774c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem changeItem = changeItems.get(change);
4784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            verifier.verify(observer, changeItem);
4794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
4804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
4814c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
4834c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that process state changes are dispatched to observers only when they
4844c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * change across the cutpoint (this is specified when registering the observer).
4854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
4864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
4874c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUidChanges_procStateCutpoint() throws RemoteException {
4884c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
4894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4904c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(observer.asBinder()).thenReturn((IBinder) observer);
49151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */,
4924c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */);
4934c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // When we invoke AMS.registerUidObserver, there are some interactions with observer
4944c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // mock in RemoteCallbackList class. We don't want to test those interactions and
4954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
4964c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // So, resetting the mock here.
4974c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        Mockito.reset(observer);
4984c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
4994c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
5004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.uid = TEST_UID;
5014c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.change = UidRecord.CHANGE_PROCSTATE;
5024c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
5038025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka        changeItem.procStateSeq = 111;
50451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
50551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5064c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // First process state message is always delivered regardless of whether the process state
5074c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // change is above or below the cutpoint (PROCESS_STATE_SERVICE).
5084c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
5098025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
5104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
5114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5124c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_RECEIVER;
51351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
51451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
5164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is also below cutpoint, so no callback will be invoked.
5174c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
5184c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
52051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
52151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5224c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is below cutpoint (PROCESS_STATE_SERVICE) and
5234c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is above cutpoint, so callback will be invoked with the
5244c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // current process state change.
5254c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
5268025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
5274c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
5284c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5294c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_TOP;
53051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
53151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
5334c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is also above cutpoint, so no callback will be invoked.
5344c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
5354c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5364c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        changeItem.processState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
53751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.add(changeItem);
53851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5394c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Previous process state change is above cutpoint (PROCESS_STATE_SERVICE) and
5404c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // the current process state change is below cutpoint, so callback will be invoked with the
5414c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // current process state change.
5428025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka        verify(observer).onUidStateChanged(TEST_UID,
5438025580449081ddd21f449f8719bc87d1cc9fc7bSudheer Shanka                changeItem.processState, changeItem.procStateSeq);
5444c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        verifyNoMoreInteractions(observer);
5454c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
5464c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5474c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    /**
5484c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * This test verifies that {@link ActivityManagerService#mValidateUids} which is a
5494c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     * part of dumpsys is correctly updated.
5504c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka     */
5514c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    @Test
5524c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    public void testDispatchUidChanges_validateUidsUpdated() {
55351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int[] changesForPendingItems = UID_RECORD_CHANGES;
55451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
5554c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final int[] procStatesForPendingItems = {
5564c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
5574c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_EMPTY,
5584c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
5594c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_SERVICE,
5604c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            ActivityManager.PROCESS_STATE_RECEIVER
5614c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        };
5624c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final ArrayList<UidRecord.ChangeItem> pendingItemsForUids
5634c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                = new ArrayList<>(changesForPendingItems.length);
5644c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < changesForPendingItems.length; ++i) {
5654c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = new UidRecord.ChangeItem();
5664c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.uid = i;
5674c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.change = changesForPendingItems[i];
5684c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            item.processState = procStatesForPendingItems[i];
5694c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            pendingItemsForUids.add(i, item);
5704c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
5714c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5724c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when there no observers listening to uid state changes, then there will
5734c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // be no changes to validateUids.
57451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
57551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5764c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        assertEquals("No observers registered, so validateUids should be empty",
57751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                0, mAms.mValidateUids.size());
5784c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
5794c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        final IUidObserver observer = Mockito.mock(IUidObserver.Stub.class);
5804c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        when(observer.asBinder()).thenReturn((IBinder) observer);
58151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.registerUidObserver(observer, 0, 0, null);
5824c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when observers are registered, then validateUids is correctly updated.
58351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
58451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
5854c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
5864c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
58751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final UidRecord validateUidRecord = mAms.mValidateUids.get(item.uid);
5883e99f654fbf56d3b7ef7130658b8ef83d2d0cdbdDianne Hackborn            if ((item.change & UidRecord.CHANGE_GONE) != 0) {
5894c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertNull("validateUidRecord should be null since the change is either "
5904c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + "CHANGE_GONE or CHANGE_GONE_IDLE", validateUidRecord);
5914c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            } else {
5924c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertNotNull("validateUidRecord should not be null since the change is neither "
5934c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + "CHANGE_GONE nor CHANGE_GONE_IDLE", validateUidRecord);
5944c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertEquals("processState: " + item.processState + " curProcState: "
5954c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + validateUidRecord.curProcState + " should have been equal",
5964c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        item.processState, validateUidRecord.curProcState);
5974c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                assertEquals("processState: " + item.processState + " setProcState: "
5984c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        + validateUidRecord.curProcState + " should have been equal",
5994c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                        item.processState, validateUidRecord.setProcState);
6004c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                if (item.change == UidRecord.CHANGE_IDLE) {
6014c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    assertTrue("UidRecord.idle should be updated to true for CHANGE_IDLE",
6024c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            validateUidRecord.idle);
6034c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                } else if (item.change == UidRecord.CHANGE_ACTIVE) {
6044c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                    assertFalse("UidRecord.idle should be updated to false for CHANGE_ACTIVE",
6054c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                            validateUidRecord.idle);
6064c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka                }
6074c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            }
6084c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
6094c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka
6104c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // Verify that when uid state changes to CHANGE_GONE or CHANGE_GONE_IDLE, then it
6114c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        // will be removed from validateUids.
61251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        assertNotEquals("validateUids should not be empty", 0, mAms.mValidateUids.size());
6134c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        for (int i = 0; i < pendingItemsForUids.size(); ++i) {
6144c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            final UidRecord.ChangeItem item = pendingItemsForUids.get(i);
6154c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // Assign CHANGE_GONE_IDLE to some items and CHANGE_GONE to the others, using even/odd
6164c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka            // distribution for this assignment.
6173e99f654fbf56d3b7ef7130658b8ef83d2d0cdbdDianne Hackborn            item.change = (i % 2) == 0 ? (UidRecord.CHANGE_GONE | UidRecord.CHANGE_IDLE)
6183e99f654fbf56d3b7ef7130658b8ef83d2d0cdbdDianne Hackborn                    : UidRecord.CHANGE_GONE;
6194c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka        }
62051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.mPendingUidChanges.addAll(pendingItemsForUids);
62151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms.dispatchUidsChanged();
62251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        assertEquals("validateUids should be empty, validateUids: " + mAms.mValidateUids,
62351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                0, mAms.mValidateUids.size());
62451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
62551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
62651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @Test
62751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void testEnqueueUidChangeLocked_procStateSeqUpdated() {
62851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord uidRecord = new UidRecord(TEST_UID);
62951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
63051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
63151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Verify with no pending changes for TEST_UID.
63251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ1);
63351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
63451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Add a pending change for TEST_UID and verify enqueueUidChangeLocked still works as
63551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // expected.
63651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord.ChangeItem changeItem = new UidRecord.ChangeItem();
63751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.pendingChange = changeItem;
63851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ2;
63951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        verifyLastProcStateSeqUpdated(uidRecord, -1, TEST_PROC_STATE_SEQ2);
640deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka    }
64151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
642deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka    @Test
643deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka    public void testEnqueueUidChangeLocked_nullUidRecord() {
64451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Use "null" uidRecord to make sure there is no crash.
645deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        mAms.enqueueUidChangeLocked(null, TEST_UID, UidRecord.CHANGE_ACTIVE);
64651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
64751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
64851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private void verifyLastProcStateSeqUpdated(UidRecord uidRecord, int uid, long curProcstateSeq) {
64951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Test enqueueUidChangeLocked with every UidRecord.CHANGE_*
65051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
65151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final int changeToDispatch = UID_RECORD_CHANGES[i];
65251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Reset lastProcStateSeqDispatchToObservers after every test.
65351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            uidRecord.lastDispatchedProcStateSeq = 0;
65451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.enqueueUidChangeLocked(uidRecord, uid, changeToDispatch);
65551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify there is no effect on curProcStateSeq.
65651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(curProcstateSeq, uidRecord.curProcStateSeq);
6573e99f654fbf56d3b7ef7130658b8ef83d2d0cdbdDianne Hackborn            if ((changeToDispatch & UidRecord.CHANGE_GONE) != 0) {
65851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // Since the change is CHANGE_GONE or CHANGE_GONE_IDLE, verify that
65951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // lastProcStateSeqDispatchedToObservers is not updated.
66051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                assertNotEquals(uidRecord.curProcStateSeq,
66151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                        uidRecord.lastDispatchedProcStateSeq);
66251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            } else {
66351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // Since the change is neither CHANGE_GONE nor CHANGE_GONE_IDLE, verify that
66451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                // lastProcStateSeqDispatchedToObservers has been updated to curProcStateSeq.
66551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                assertEquals(uidRecord.curProcStateSeq,
66651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                        uidRecord.lastDispatchedProcStateSeq);
66751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
66851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
66951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
67051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
67151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @MediumTest
67251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @Test
67351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    public void testEnqueueUidChangeLocked_dispatchUidsChanged() {
67451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final UidRecord uidRecord = new UidRecord(TEST_UID);
67551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        final int expectedProcState = PROCESS_STATE_SERVICE;
67651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.setProcState = expectedProcState;
67751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
67851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
67951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        // Test with no pending uid records.
68051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        for (int i = 0; i < UID_RECORD_CHANGES.length; ++i) {
68151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final int changeToDispatch = UID_RECORD_CHANGES[i];
68251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
68351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Reset the current state
68451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mHandler.reset();
68551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            uidRecord.pendingChange = null;
68651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.mPendingUidChanges.clear();
68751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
68851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mAms.enqueueUidChangeLocked(uidRecord, -1, changeToDispatch);
68951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
69051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify that UidRecord.pendingChange is updated correctly.
69151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertNotNull(uidRecord.pendingChange);
69251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(TEST_UID, uidRecord.pendingChange.uid);
69351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(expectedProcState, uidRecord.pendingChange.processState);
69451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            assertEquals(TEST_PROC_STATE_SEQ1, uidRecord.pendingChange.procStateSeq);
69551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
69651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            // Verify that DISPATCH_UIDS_CHANGED_UI_MSG is posted to handler.
69751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mHandler.waitForMessage(DISPATCH_UIDS_CHANGED_UI_MSG);
69851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
69951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
70051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
70184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @MediumTest
70284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @Test
70384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void testWaitForNetworkStateUpdate() throws Exception {
70484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Check there is no crash when there is no UidRecord for myUid
70584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.waitForNetworkStateUpdate(TEST_PROC_STATE_SEQ1);
70684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
70784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is no waiting when UidRecord.curProcStateSeq is greater than
70884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // the procStateSeq in the request to wait.
70984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
71084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
71184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
71284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 4, // lastNetworkUpdatedProcStateSeq
71384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 2, // procStateSeqToWait
71484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
71584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
71684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is no waiting when the procStateSeq in the request to wait is
71784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // not dispatched to NPMS.
71884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
71984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
72084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastDsipatchedProcStateSeq
72184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
72284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
72384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
72484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
72584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify there is not waiting when the procStateSeq in the request already has
72684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // an updated network state.
72784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
72884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
72984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
73084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastNetworkUpdatedProcStateSeq
73184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
73284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectWait
73384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
73484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Verify waiting for network works
73584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyWaitingForNetworkStateUpdate(
73684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
73784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastDsipatchedProcStateSeq
73884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1 - 1, // lastNetworkUpdatedProcStateSeq
73984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeqToWait
74084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                true); // expectWait
74184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
74284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
74384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq,
74484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            long lastDispatchedProcStateSeq, long lastNetworkUpdatedProcStateSeq,
74584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final long procStateSeqToWait, boolean expectWait) throws Exception {
74684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final UidRecord record = new UidRecord(Process.myUid());
74784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.curProcStateSeq = curProcStateSeq;
74884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.lastDispatchedProcStateSeq = lastDispatchedProcStateSeq;
74984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
75084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.put(Process.myUid(), record);
75184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
752f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        CustomThread thread = new CustomThread(record.networkStateLock, new Runnable() {
75384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            @Override
75484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            public void run() {
75584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                mAms.waitForNetworkStateUpdate(procStateSeqToWait);
75684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
75784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        });
75884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final String errMsg = "Unexpected state for " + record;
75984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        if (expectWait) {
76084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.startAndWait(errMsg, true);
76184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTimedWaiting(errMsg);
762f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka            synchronized (record.networkStateLock) {
763f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka                record.networkStateLock.notifyAll();
76484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
76584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated(errMsg);
76684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertTrue(thread.mNotified);
76784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertFalse(record.waitingForNetwork);
76884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        } else {
76984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.start();
77084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread.assertTerminated(errMsg);
77184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
77284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
77384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.clear();
77484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
77584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
77651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    private class TestHandler extends Handler {
77751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private static final long WAIT_FOR_MSG_TIMEOUT_MS = 4000; // 4 sec
77851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private static final long WAIT_FOR_MSG_INTERVAL_MS = 400; // 0.4 sec
77951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
78051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        private Set<Integer> mMsgsHandled = new HashSet<>();
78151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
78251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        TestHandler(Looper looper) {
78351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            super(looper);
78451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
78551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
78651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
78751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void handleMessage(Message msg) {
78851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mMsgsHandled.add(msg.what);
78951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
79051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
79151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void waitForMessage(int msg) {
79251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            final long endTime = System.currentTimeMillis() + WAIT_FOR_MSG_TIMEOUT_MS;
79351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            while (!mMsgsHandled.contains(msg) && System.currentTimeMillis() < endTime) {
79451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                SystemClock.sleep(WAIT_FOR_MSG_INTERVAL_MS);
79551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
79651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            if (!mMsgsHandled.contains(msg)) {
79751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka                fail("Timed out waiting for the message to be handled, msg: " + msg);
79851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            }
79951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
80051ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
80151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        public void reset() {
80251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            mMsgsHandled.clear();
80351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
80451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    }
80551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
80684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private class TestInjector extends Injector {
80784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        private boolean mRestricted = true;
80884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
80951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
810deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        public Context getContext() {
811deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka            return mContext;
812deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        }
813deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka
814deeb08fdcb2ccf90d013a9e909122e1a997c40bbSudheer Shanka        @Override
81584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public AppOpsService getAppOpsService(File file, Handler handler) {
81651ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            return mAppOpsService;
81751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
81851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
81951ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        @Override
82084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public Handler getUiHandler(ActivityManagerService service) {
82151ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka            return mHandler;
82251ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        }
82384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
82484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        @Override
82584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public boolean isNetworkRestrictedForUid(int uid) {
82684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            return mRestricted;
82784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
82884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
82984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void setNetworkRestrictedForUid(boolean restricted) {
83084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            mRestricted = restricted;
83184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
8324c9afa87d09a9b6abecbddc956343a70363f0c5fSudheer Shanka    }
83388c4d1ce97f5fa3859dd1854d4a82305e68a2b0eSudheer Shanka}