1e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka/*
2e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * Copyright (C) 2017 The Android Open Source Project
3e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *
4e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * Licensed under the Apache License, Version 2.0 (the "License");
5e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * you may not use this file except in compliance with the License.
6e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * You may obtain a copy of the License at
7e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *
8e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *      http://www.apache.org/licenses/LICENSE-2.0
9e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *
10e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * Unless required by applicable law or agreed to in writing, software
11e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * distributed under the License is distributed on an "AS IS" BASIS,
12e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * See the License for the specific language governing permissions and
14e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * limitations under the License
15e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka */
16e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
17e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankapackage com.android.server.am;
18e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
19e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankaimport static org.junit.Assert.assertEquals;
2084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport static org.junit.Assert.assertTrue;
21e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
22e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankaimport android.app.ActivityManagerInternal;
2384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport android.os.SystemClock;
2484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shankaimport android.support.test.filters.MediumTest;
25e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankaimport android.support.test.runner.AndroidJUnit4;
26e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
27e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankaimport org.junit.Before;
28e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankaimport org.junit.Test;
29e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankaimport org.junit.runner.RunWith;
3051ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport org.mockito.Mock;
3151ab3acf270c655ed90706895b43915433d022c7Sudheer Shankaimport org.mockito.MockitoAnnotations;
32e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
33e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka/**
34e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * Test class for {@link ActivityManagerInternal}.
35e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *
36e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * To run the tests, use
37e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *
38e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * runtest -c com.android.server.am.ActivityManagerInternalTest frameworks-services
39e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *
40e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * or the following steps:
41e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *
42e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * Build: m FrameworksServicesTests
43e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * Install: adb install -r \
44e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
45e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerInternalTest -w \
46e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
47e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka */
48e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka@RunWith(AndroidJUnit4.class)
49e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shankapublic class ActivityManagerInternalTest {
5084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private static final int TEST_UID1 = 111;
5184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private static final int TEST_UID2 = 112;
5284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
5384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private static final long TEST_PROC_STATE_SEQ1 = 1111;
5484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private static final long TEST_PROC_STATE_SEQ2 = 1112;
5584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private static final long TEST_PROC_STATE_SEQ3 = 1113;
5684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
5751ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka    @Mock private ActivityManagerService.Injector mMockInjector;
5851ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
59e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    private ActivityManagerService mAms;
60e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    private ActivityManagerInternal mAmi;
61e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    @Before
62e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    public void setUp() {
6351ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        MockitoAnnotations.initMocks(this);
6451ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka
6551ab3acf270c655ed90706895b43915433d022c7Sudheer Shanka        mAms = new ActivityManagerService(mMockInjector);
66e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka        mAmi = mAms.new LocalService();
67e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    }
68e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
6984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    @MediumTest
70e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    @Test
7184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    public void testNotifyNetworkPolicyRulesUpdated() throws Exception {
7284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Check there is no crash when there are no active uid records.
7384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAmi.notifyNetworkPolicyRulesUpdated(TEST_UID1, TEST_PROC_STATE_SEQ1);
7484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
7584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Notify that network policy rules are updated for TEST_UID1 and verify that
7684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // UidRecord.lastNetworkUpdateProcStateSeq is updated and any blocked threads are notified.
7784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyNetworkUpdatedProcStateSeq(
7884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ2, // curProcStateSeq
7984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastNetworkUpdateProcStateSeq
8084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ2, // procStateSeq to notify
8184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                true); // expectNotify
8284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
8384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Notify that network policy rules are updated for TEST_UID1 with already handled
8484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // procStateSeq and verify that there is no notify call.
8584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyNetworkUpdatedProcStateSeq(
8684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // curProcStateSeq
8784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastNetworkUpdateProcStateSeq
8884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // procStateSeq to notify
8984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
9084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
9184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // Notify that network policy rules are updated for TEST_UID1 with procStateSeq older
9284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        // than it's UidRecord.curProcStateSeq and verify that there is no notify call.
9384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        verifyNetworkUpdatedProcStateSeq(
9484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ3, // curProcStateSeq
9584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ1, // lastNetworkUpdateProcStateSeq
9684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                TEST_PROC_STATE_SEQ2, // procStateSeq to notify
9784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                false); // expectNotify
9884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
9984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
10084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private void verifyNetworkUpdatedProcStateSeq(long curProcStateSeq,
10184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            long lastNetworkUpdatedProcStateSeq, long expectedProcStateSeq, boolean expectNotify)
10284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            throws Exception {
10384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final UidRecord record1 = addActiveUidRecord(TEST_UID1, curProcStateSeq,
10484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                lastNetworkUpdatedProcStateSeq);
10584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        final UidRecord record2 = addActiveUidRecord(TEST_UID2, curProcStateSeq,
10684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                lastNetworkUpdatedProcStateSeq);
10784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
108f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        final CustomThread thread1 = new CustomThread(record1.networkStateLock);
10984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        thread1.startAndWait("Unexpected state for " + record1);
110f4923ea0b25edb6e6ca6804ed4c66f57a8ec29c2Sudheer Shanka        final CustomThread thread2 = new CustomThread(record2.networkStateLock);
11184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        thread2.startAndWait("Unexpected state for " + record2);
11284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
11384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAmi.notifyNetworkPolicyRulesUpdated(TEST_UID1, expectedProcStateSeq);
11484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(record1 + " should be updated",
11584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                expectedProcStateSeq, record1.lastNetworkUpdatedProcStateSeq);
11684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        assertEquals(record2 + " should not be updated",
11784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                lastNetworkUpdatedProcStateSeq, record2.lastNetworkUpdatedProcStateSeq);
11884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
11984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        if (expectNotify) {
12084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread1.assertTerminated("Unexpected state for " + record1);
12184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertTrue("Threads waiting for network should be notified: " + record1,
12284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    thread1.mNotified);
12384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        } else {
12484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread1.assertWaiting("Unexpected state for " + record1);
12584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            thread1.interrupt();
12684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
12784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        thread2.assertWaiting("Unexpected state for " + record2);
12884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        thread2.interrupt();
12984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
13084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        mAms.mActiveUids.clear();
131e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    }
132e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka
13384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    private UidRecord addActiveUidRecord(int uid, long curProcStateSeq,
13484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            long lastNetworkUpdatedProcStateSeq) {
135e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka        final UidRecord record = new UidRecord(uid);
136e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka        record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
13784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.curProcStateSeq = curProcStateSeq;
13884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        record.waitingForNetwork = true;
139e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka        mAms.mActiveUids.put(uid, record);
140e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka        return record;
141e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka    }
14284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
14384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    static class CustomThread extends Thread {
14484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        private static final long WAIT_TIMEOUT_MS = 1000;
14584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        private static final long WAIT_INTERVAL_MS = 100;
14684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
14784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        private final Object mLock;
14884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        private Runnable mRunnable;
14984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        boolean mNotified;
15084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
15184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public CustomThread(Object lock) {
15284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            mLock = lock;
15384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
15484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
15584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public CustomThread(Object lock, Runnable runnable) {
15684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            super(runnable);
15784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            mLock = lock;
15884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            mRunnable = runnable;
15984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
16084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
16184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        @Override
16284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void run() {
16384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            if (mRunnable != null) {
16484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                mRunnable.run();
16584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            } else {
16684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                synchronized (mLock) {
16784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    try {
16884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                        mLock.wait();
16984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    } catch (InterruptedException e) {
17084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                        Thread.currentThread().interrupted();
17184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    }
17284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                }
17384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
17484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            mNotified = !Thread.interrupted();
17584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
17684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
17784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void startAndWait(String errMsg) throws Exception {
17884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            startAndWait(errMsg, false);
17984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
18084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
18184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void startAndWait(String errMsg, boolean timedWaiting) throws Exception {
18284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            start();
18384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final long endTime = SystemClock.elapsedRealtime() + WAIT_TIMEOUT_MS;
18484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final Thread.State stateToReach = timedWaiting
18584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    ? Thread.State.TIMED_WAITING : Thread.State.WAITING;
18684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            while (getState() != stateToReach
18784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    && SystemClock.elapsedRealtime() < endTime) {
18884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                Thread.sleep(WAIT_INTERVAL_MS);
18984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
19084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            if (timedWaiting) {
19184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                assertTimedWaiting(errMsg);
19284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            } else {
19384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                assertWaiting(errMsg);
19484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
19584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
19684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
19784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void assertWaiting(String errMsg) {
19884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertEquals(errMsg, Thread.State.WAITING, getState());
19984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
20084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
20184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void assertTimedWaiting(String errMsg) {
20284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertEquals(errMsg, Thread.State.TIMED_WAITING, getState());
20384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
20484a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka
20584a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        public void assertTerminated(String errMsg) throws Exception {
20684a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            final long endTime = SystemClock.elapsedRealtime() + WAIT_TIMEOUT_MS;
20784a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            while (getState() != Thread.State.TERMINATED
20884a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                    && SystemClock.elapsedRealtime() < endTime) {
20984a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka                Thread.sleep(WAIT_INTERVAL_MS);
21084a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            }
21184a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka            assertEquals(errMsg, Thread.State.TERMINATED, getState());
21284a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka        }
21384a4895c9c1eb7f381d99fb8eb298d8335d4e480Sudheer Shanka    }
214e736185ee90e0f19a7092542cadab4cf561a5703Sudheer Shanka}
215