• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNotSame;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertSame;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assume.assumeFalse;
27 
28 import android.app.Activity;
29 import android.app.Application;
30 import android.app.Instrumentation;
31 import android.app.Instrumentation.ActivityMonitor;
32 import android.app.Instrumentation.ActivityResult;
33 import android.app.stubs.InstrumentationTestActivity;
34 import android.app.stubs.MockApplication;
35 import android.app.stubs.R;
36 import android.content.ComponentName;
37 import android.content.Context;
38 import android.content.Intent;
39 import android.content.IntentFilter;
40 import android.content.pm.ActivityInfo;
41 import android.content.res.Configuration;
42 import android.graphics.Rect;
43 import android.graphics.drawable.Drawable;
44 import android.net.Uri;
45 import android.os.Build;
46 import android.os.Bundle;
47 import android.os.Debug;
48 import android.os.SystemClock;
49 import android.test.UiThreadTest;
50 import android.view.InputQueue;
51 import android.view.KeyCharacterMap;
52 import android.view.KeyEvent;
53 import android.view.LayoutInflater;
54 import android.view.MotionEvent;
55 import android.view.SurfaceHolder;
56 import android.view.View;
57 import android.view.ViewGroup.LayoutParams;
58 import android.view.Window;
59 
60 import androidx.test.InstrumentationRegistry;
61 import androidx.test.runner.AndroidJUnit4;
62 
63 import com.android.compatibility.common.util.SystemUtil;
64 import com.android.compatibility.common.util.UserHelper;
65 import com.android.compatibility.common.util.WindowUtil;
66 
67 import org.junit.After;
68 import org.junit.Before;
69 import org.junit.Test;
70 import org.junit.runner.RunWith;
71 
72 import java.util.List;
73 
74 @RunWith(AndroidJUnit4.class)
75 public class InstrumentationTest {
76 
77     private static final int WAIT_TIME = 1000;
78 
79     // Secondary apk we can run tests against.
80     static final String SIMPLE_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp";
81     private static final String TEST_ACTION = "com.android.app.cts.TEST_ACTION";
82 
83     private Instrumentation mInstrumentation;
84     private InstrumentationTestActivity mActivity;
85     private Intent mIntent;
86     private boolean mRunOnMainSyncResult;
87     private Context mContext;
88     private int mTestRunningUserId;
89     private MockActivity mMockActivity;
90 
91     private final UserHelper mUserHelper = new UserHelper();
92 
93     @Before
setUp()94     public void setUp() throws Exception {
95         mInstrumentation = InstrumentationRegistry.getInstrumentation();
96         mContext = mInstrumentation.getTargetContext();
97         mTestRunningUserId = mContext.getUserId();
98         mIntent = new Intent(mContext, InstrumentationTestActivity.class);
99         mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
100         mActivity = (InstrumentationTestActivity) mInstrumentation.startActivitySync(mIntent);
101         WindowUtil.waitForFocus(mActivity);
102     }
103 
104     @After
tearDown()105     public void tearDown() throws Exception {
106         mInstrumentation = null;
107         mIntent = null;
108         if (mActivity != null) {
109             mActivity.finish();
110             mActivity = null;
111         }
112     }
113 
114     @Test
testDefaultProcessInstrumentation()115     public void testDefaultProcessInstrumentation() throws Exception {
116         String cmd = "am instrument --user " + mTestRunningUserId
117                 + " -w android.app.cts/.DefaultProcessInstrumentation";
118         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
119         assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + "=true" +
120                 "\nINSTRUMENTATION_CODE: -1\n", result);
121     }
122 
123     @Test
testAltProcessInstrumentation()124     public void testAltProcessInstrumentation() throws Exception {
125         String cmd = "am instrument --user " + mTestRunningUserId
126                 + " -w android.app.cts/.AltProcessInstrumentation";
127         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
128         assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + ":other=true" +
129                 "\nINSTRUMENTATION_CODE: -1\n", result);
130     }
131 
132     @Test
testWildcardProcessInstrumentation()133     public void testWildcardProcessInstrumentation() throws Exception {
134         String cmd = "am instrument --user " + mTestRunningUserId
135                 + " -w android.app.cts/.WildcardProcessInstrumentation";
136         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
137         assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + "=true" +
138                 "\nINSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + ":receiver=true" +
139                 "\nINSTRUMENTATION_CODE: -1\n", result);
140     }
141 
142     @Test
testMultiProcessInstrumentation()143     public void testMultiProcessInstrumentation() throws Exception {
144         String cmd = "am instrument --user " + mTestRunningUserId
145                 + " -w android.app.cts/.MultiProcessInstrumentation";
146         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
147         assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + "=true" +
148                 "\nINSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + ":other=true" +
149                 "\nINSTRUMENTATION_CODE: -1\n", result);
150     }
151 
152     @Test
testEnforceStartFromShell()153     public void testEnforceStartFromShell() throws Exception {
154         assumeFalse(Build.isDebuggable());
155         // Start the instrumentation from shell, it should succeed.
156         final String defaultInstrumentationName = "android.app.cts/.DefaultProcessInstrumentation";
157         String cmd = "am instrument --user " + mTestRunningUserId
158                 + " -w " + defaultInstrumentationName;
159         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
160         assertEquals("INSTRUMENTATION_RESULT: " + SIMPLE_PACKAGE_NAME + "=true"
161                 + "\nINSTRUMENTATION_CODE: -1\n", result);
162         // Start the instrumentation by ourselves, it should succeed (chained instrumentation).
163         mContext.startInstrumentation(
164                 ComponentName.unflattenFromString(defaultInstrumentationName), null, null);
165         // Start the instrumentation from another process, this time it should fail.
166         SystemUtil.runShellCommand(mInstrumentation,
167                 "cmd deviceidle tempwhitelist -u " + mTestRunningUserId + " android.app.cts");
168         try {
169             assertFalse(InstrumentationHelperService.startInstrumentation(
170                     mContext, defaultInstrumentationName));
171         } finally {
172             SystemUtil.runShellCommand(mInstrumentation,
173                     "cmd deviceidle tempwhitelist -u "
174                     + mTestRunningUserId + " -r android.app.cts");
175         }
176     }
177 
178     @Test
testChainedInstrumentation()179     public void testChainedInstrumentation() throws Exception {
180         final String testPkg1 = "com.android.test.cantsavestate1";
181         final String testPkg2 = "com.android.test.cantsavestate2";
182         String cmd = "am instrument --user " + mTestRunningUserId
183                 + " -w android.app.cts/.ChainedInstrumentationFirst";
184         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
185         assertEquals("INSTRUMENTATION_RESULT: " + testPkg1 + "=true"
186                 + "\nINSTRUMENTATION_RESULT: " + testPkg2 + "=true"
187                 + "\nINSTRUMENTATION_CODE: -1\n", result);
188     }
189 
190     @Test
testMonitor()191     public void testMonitor() throws Exception {
192         if (mActivity != null)
193             mActivity.finish();
194         ActivityResult result = new ActivityResult(Activity.RESULT_OK, new Intent());
195         ActivityMonitor monitor = new ActivityMonitor(
196                 InstrumentationTestActivity.class.getName(), result, false);
197         mInstrumentation.addMonitor(monitor);
198         Intent intent = new Intent(mContext, InstrumentationTestActivity.class);
199         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
200         mContext.startActivity(intent);
201         Activity activity = mInstrumentation.waitForMonitorWithTimeout(monitor, WAIT_TIME);
202         assertTrue(activity instanceof InstrumentationTestActivity);
203         assertTrue(mInstrumentation.checkMonitorHit(monitor, 1));
204         activity.finish();
205 
206         mInstrumentation.addMonitor(monitor);
207         mInstrumentation.removeMonitor(monitor);
208         Activity a = mInstrumentation.startActivitySync(intent);
209         assertTrue(a instanceof InstrumentationTestActivity);
210         activity = mInstrumentation.waitForMonitorWithTimeout(monitor, WAIT_TIME);
211         assertNull(activity);
212         a.finish();
213 
214         IntentFilter filter = new IntentFilter(TEST_ACTION);
215         ActivityMonitor am = mInstrumentation.addMonitor(filter, result, false);
216         intent.setAction(TEST_ACTION);
217         mContext.startActivity(intent);
218         mInstrumentation.waitForIdleSync();
219         activity = am.waitForActivity();
220         assertTrue(activity instanceof InstrumentationTestActivity);
221         activity.finish();
222         mInstrumentation.removeMonitor(am);
223         am = mInstrumentation
224                 .addMonitor(InstrumentationTestActivity.class.getName(), result, false);
225         mContext.startActivity(intent);
226         activity = am.waitForActivity();
227         assertTrue(activity instanceof InstrumentationTestActivity);
228         activity.finish();
229         mInstrumentation.removeMonitor(am);
230     }
231 
232     @Test
testCallActivityOnCreate()233     public void testCallActivityOnCreate() throws Throwable {
234         mActivity.setOnCreateCalled(false);
235         runTestOnUiThread(new Runnable() {
236             public void run() {
237                 mInstrumentation.callActivityOnCreate(mActivity, new Bundle());
238             }
239         });
240         mInstrumentation.waitForIdleSync();
241         assertTrue(mActivity.isOnCreateCalled());
242     }
243 
244     @Test
testAllocCounting()245     public void testAllocCounting() throws Exception {
246         mInstrumentation.startAllocCounting();
247 
248         Bundle b = mInstrumentation.getAllocCounts();
249         assertTrue(b.size() > 0);
250         b = mInstrumentation.getBinderCounts();
251         assertTrue(b.size() > 0);
252 
253         int globeAllocCount = Debug.getGlobalAllocCount();
254         int globeAllocSize = Debug.getGlobalAllocSize();
255         int globeExternalAllCount = Debug.getGlobalExternalAllocCount();
256         int globeExternalAllSize = Debug.getGlobalExternalAllocSize();
257         int threadAllocCount = Debug.getThreadAllocCount();
258 
259         assertTrue(Debug.getGlobalAllocCount() >= globeAllocCount);
260         assertTrue(Debug.getGlobalAllocSize() >= globeAllocSize);
261         assertTrue(Debug.getGlobalExternalAllocCount() >= globeExternalAllCount);
262         assertTrue(Debug.getGlobalExternalAllocSize() >= globeExternalAllSize);
263         assertTrue(Debug.getThreadAllocCount() >= threadAllocCount);
264 
265         mInstrumentation.stopAllocCounting();
266 
267         globeAllocCount = Debug.getGlobalAllocCount();
268         globeAllocSize = Debug.getGlobalAllocSize();
269         globeExternalAllCount = Debug.getGlobalExternalAllocCount();
270         globeExternalAllSize = Debug.getGlobalExternalAllocSize();
271         threadAllocCount = Debug.getThreadAllocCount();
272         assertEquals(globeAllocCount, Debug.getGlobalAllocCount());
273         assertEquals(globeAllocSize, Debug.getGlobalAllocSize());
274         assertEquals(globeExternalAllCount, Debug.getGlobalExternalAllocCount());
275         assertEquals(globeExternalAllSize, Debug.getGlobalExternalAllocSize());
276         assertEquals(threadAllocCount, Debug.getThreadAllocCount());
277     }
278 
279     @Test
testSendTrackballEventSync()280     public void testSendTrackballEventSync() throws Exception {
281         long now = SystemClock.uptimeMillis();
282         MotionEvent orig = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
283                 100, 100, 0);
284         mUserHelper.injectDisplayIdIfNeeded(orig);
285         mInstrumentation.sendTrackballEventSync(orig);
286         mInstrumentation.waitForIdleSync();
287 
288         MotionEvent motionEvent = mActivity.getMotionEvent();
289         assertEquals(orig.getMetaState(), motionEvent.getMetaState());
290         assertEquals(orig.getEventTime(), motionEvent.getEventTime());
291         assertEquals(orig.getDownTime(), motionEvent.getDownTime());
292     }
293 
294     @Test
testCallApplicationOnCreate()295     public void testCallApplicationOnCreate() throws Exception {
296         InstrumentationTestStub ca = new InstrumentationTestStub();
297         mInstrumentation.callApplicationOnCreate(ca);
298         assertTrue(ca.mIsOnCreateCalled);
299     }
300 
301     @Test
testContext()302     public void testContext() throws Exception {
303         Context c1 = mInstrumentation.getContext();
304         Context c2 = mInstrumentation.getTargetContext();
305         assertNotSame(c1.getPackageName(), c2.getPackageName());
306     }
307 
308     @Test
testInvokeMenuActionSync()309     public void testInvokeMenuActionSync() throws Exception {
310         final int resId = R.id.goto_menu_id;
311         if (mActivity.getWindow().hasFeature(Window.FEATURE_OPTIONS_PANEL)) {
312             mInstrumentation.invokeMenuActionSync(mActivity, resId, 0);
313             mInstrumentation.waitForIdleSync();
314 
315             assertEquals(resId, mActivity.getMenuID());
316         }
317     }
318 
319     @Test
testCallActivityOnPostCreate()320     public void testCallActivityOnPostCreate() throws Throwable {
321         mActivity.setOnPostCreate(false);
322         runTestOnUiThread(new Runnable() {
323             public void run() {
324                 mInstrumentation.callActivityOnPostCreate(mActivity, new Bundle());
325             }
326         });
327         mInstrumentation.waitForIdleSync();
328         assertTrue(mActivity.isOnPostCreate());
329     }
330 
331     @Test
testCallActivityOnNewIntent()332     public void testCallActivityOnNewIntent() throws Throwable {
333         mActivity.setOnNewIntentCalled(false);
334         runTestOnUiThread(new Runnable() {
335             public void run() {
336                 mInstrumentation.callActivityOnNewIntent(mActivity, null);
337             }
338         });
339         mInstrumentation.waitForIdleSync();
340 
341         assertTrue(mActivity.isOnNewIntentCalled());
342     }
343 
344     @Test
testCallActivityOnNewIntentCaller()345     public void testCallActivityOnNewIntentCaller() throws Throwable {
346         mActivity.setOnNewIntentCalled(false);
347         runTestOnUiThread(new Runnable() {
348             public void run() {
349                 mInstrumentation.callActivityOnNewIntent(mActivity, new Intent(),
350                         mActivity.getInitialCaller());
351             }
352         });
353         mInstrumentation.waitForIdleSync();
354 
355         assertTrue(mActivity.isOnNewIntentCalled());
356     }
357 
358     @Test
testCallActivityOnResume()359     public void testCallActivityOnResume() throws Throwable {
360         mActivity.setOnResume(false);
361         runTestOnUiThread(new Runnable() {
362             public void run() {
363                 mInstrumentation.callActivityOnResume(mActivity);
364             }
365         });
366         mInstrumentation.waitForIdleSync();
367         assertTrue(mActivity.isOnResume());
368     }
369 
370     @Test
testMisc()371     public void testMisc() throws Exception {
372     }
373 
374     @Test
testPerformanceSnapshot()375     public void testPerformanceSnapshot() throws Exception {
376         mInstrumentation.setAutomaticPerformanceSnapshots();
377         mInstrumentation.startPerformanceSnapshot();
378         mInstrumentation.endPerformanceSnapshot();
379     }
380 
381     @Test
testProfiling()382     public void testProfiling() throws Exception {
383         // by default, profiling was disabled. but after set the handleProfiling attribute in the
384         // manifest file for this Instrumentation to true, the profiling was also disabled.
385         assertFalse(mInstrumentation.isProfiling());
386 
387         mInstrumentation.startProfiling();
388         mInstrumentation.stopProfiling();
389     }
390 
391     @Test
testInvokeContextMenuAction()392     public void testInvokeContextMenuAction() throws Exception {
393         mActivity.runOnUiThread(new Runnable() {
394             public void run() {
395                 mMockActivity = new MockActivity();
396             }
397         });
398         mInstrumentation.waitForIdleSync();
399         final int id = 1;
400         final int flag = 2;
401         mInstrumentation.invokeContextMenuAction(mMockActivity, id, flag);
402         mInstrumentation.waitForIdleSync();
403 
404         assertEquals(id, mMockActivity.mWindow.mId);
405         assertEquals(flag, mMockActivity.mWindow.mFlags);
406     }
407 
408     @Test
testSendStringSync()409     public void testSendStringSync() {
410         final String text = "abcd";
411         mInstrumentation.sendStringSync(text);
412         mInstrumentation.waitForIdleSync();
413 
414         List<KeyEvent> keyUpList = mActivity.getKeyUpList();
415         List<KeyEvent> keyDownList = mActivity.getKeyDownList();
416         assertEquals(text.length(), keyDownList.size());
417         assertEquals(text.length(), keyUpList.size());
418 
419         KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
420         KeyEvent[] keyEvents = kcm.getEvents(text.toCharArray());
421 
422         int i = 0;
423         for (int j = 0; j < keyDownList.size(); j++) {
424             assertEquals(keyEvents[i++].getKeyCode(), keyDownList.get(j).getKeyCode());
425             assertEquals(keyEvents[i++].getKeyCode(), keyUpList.get(j).getKeyCode());
426         }
427     }
428 
429     @Test
testCallActivityOnSaveInstanceState()430     public void testCallActivityOnSaveInstanceState() throws Throwable {
431         final Bundle bundle = new Bundle();
432         mActivity.setOnSaveInstanceState(false);
433         runTestOnUiThread(new Runnable() {
434             public void run() {
435                 mInstrumentation.callActivityOnSaveInstanceState(mActivity, bundle);
436             }
437         });
438         mInstrumentation.waitForIdleSync();
439 
440         assertTrue(mActivity.isOnSaveInstanceState());
441         assertSame(bundle, mActivity.getBundle());
442     }
443 
444     @Test
testSendPointerSync()445     public void testSendPointerSync() throws Exception {
446         mInstrumentation.waitForIdleSync();
447         mInstrumentation.setInTouchMode(true);
448 
449         // Send a touch event to the middle of the activity.
450         // We assume that the Activity is empty so there won't be anything in the middle
451         // to handle the touch.  Consequently the Activity should receive onTouchEvent
452         // because nothing else handled it.
453         final Rect bounds = mActivity.getWindowManager().getCurrentWindowMetrics().getBounds();
454         final int x = bounds.centerX();
455         final int y = bounds.centerY();
456         long now = SystemClock.uptimeMillis();
457         MotionEvent orig = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN,
458                 x, y, 0);
459         mUserHelper.injectDisplayIdIfNeeded(orig);
460         mInstrumentation.sendPointerSync(orig);
461 
462         mInstrumentation.waitForIdleSync();
463         assertTrue(mActivity.isOnTouchEventCalled());
464         mActivity.setOnTouchEventCalled(false);
465     }
466 
467     @Test
testGetComponentName()468     public void testGetComponentName() throws Exception {
469         ComponentName com = mInstrumentation.getComponentName();
470         assertNotNull(com.getPackageName());
471         assertNotNull(com.getClassName());
472         assertNotNull(com.getShortClassName());
473     }
474 
475     @Test
testNewApplication()476     public void testNewApplication() throws Exception {
477         final String className = "android.app.stubs.MockApplication";
478         ClassLoader cl = getClass().getClassLoader();
479 
480         Application app = mInstrumentation.newApplication(cl, className, mContext);
481         assertEquals(className, app.getClass().getName());
482 
483         app = Instrumentation.newApplication(MockApplication.class, mContext);
484         assertEquals(className, app.getClass().getName());
485     }
486 
487     @Test
testRunOnMainSync()488     public void testRunOnMainSync() throws Exception {
489         mRunOnMainSyncResult = false;
490         mInstrumentation.runOnMainSync(new Runnable() {
491             public void run() {
492                 mRunOnMainSyncResult = true;
493             }
494         });
495         mInstrumentation.waitForIdleSync();
496         assertTrue(mRunOnMainSyncResult);
497     }
498 
499     @Test
testCallActivityOnPause()500     public void testCallActivityOnPause() throws Throwable {
501         mActivity.setOnPauseCalled(false);
502         runTestOnUiThread(() -> {
503             mInstrumentation.callActivityOnPause(mActivity);
504         });
505         mInstrumentation.waitForIdleSync();
506         assertTrue(mActivity.isOnPauseCalled());
507     }
508 
509     @Test
testSendKeyDownUpSync()510     public void testSendKeyDownUpSync() throws Exception {
511         mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0);
512         mInstrumentation.waitForIdleSync();
513         assertEquals(1, mActivity.getKeyUpList().size());
514         assertEquals(1, mActivity.getKeyDownList().size());
515         assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpList().get(0).getKeyCode());
516         assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownList().get(0).getKeyCode());
517     }
518 
519     @Test
520     @UiThreadTest
testNewActivity()521     public void testNewActivity() throws Exception {
522         Intent intent = new Intent();
523         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
524 
525         ClassLoader cl = getClass().getClassLoader();
526         Activity activity = mInstrumentation.newActivity(cl, InstrumentationTestActivity.class
527                 .getName(), intent);
528         assertEquals(InstrumentationTestActivity.class.getName(), activity.getClass().getName());
529         activity.finish();
530         activity = null;
531 
532         intent = new Intent(mContext, InstrumentationTestActivity.class);
533         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
534 
535         Activity father = new Activity();
536         ActivityInfo info = new ActivityInfo();
537 
538         activity = mInstrumentation
539                 .newActivity(InstrumentationTestActivity.class, mContext, null, null, intent, info,
540                         InstrumentationTestActivity.class.getName(), father, null, null);
541 
542         assertEquals(father, activity.getParent());
543         assertEquals(InstrumentationTestActivity.class.getName(), activity.getClass().getName());
544         activity.finish();
545     }
546 
547     @Test
testCallActivityOnStart()548     public void testCallActivityOnStart() throws Exception {
549         mActivity.setOnStart(false);
550         mInstrumentation.callActivityOnStart(mActivity);
551         mInstrumentation.waitForIdleSync();
552         assertTrue(mActivity.isOnStart());
553     }
554 
555     @Test
testWaitForIdle()556     public void testWaitForIdle() throws Exception {
557         MockRunnable mr = new MockRunnable();
558         assertFalse(mr.isRunCalled());
559         mInstrumentation.waitForIdle(mr);
560         Thread.sleep(WAIT_TIME);
561         assertTrue(mr.isRunCalled());
562     }
563 
564     @Test
testSendCharacterSync()565     public void testSendCharacterSync() throws Exception {
566         mInstrumentation.sendCharacterSync(KeyEvent.KEYCODE_0);
567         mInstrumentation.waitForIdleSync();
568         assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownCode());
569         assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpCode());
570     }
571 
572     @Test
testCallActivityOnRestart()573     public void testCallActivityOnRestart() throws Exception {
574         mActivity.setOnRestart(false);
575         mInstrumentation.callActivityOnRestart(mActivity);
576         mInstrumentation.waitForIdleSync();
577         assertTrue(mActivity.isOnRestart());
578     }
579 
580     @Test
testCallActivityOnStop()581     public void testCallActivityOnStop() throws Exception {
582         mActivity.setOnStop(false);
583         mInstrumentation.callActivityOnStop(mActivity);
584         mInstrumentation.waitForIdleSync();
585         assertTrue(mActivity.isOnStop());
586     }
587 
588     @Test
testCallActivityOnUserLeaving()589     public void testCallActivityOnUserLeaving() throws Exception {
590         assertFalse(mActivity.isOnLeave());
591         mInstrumentation.callActivityOnUserLeaving(mActivity);
592         mInstrumentation.waitForIdleSync();
593         assertTrue(mActivity.isOnLeave());
594     }
595 
596     @Test
testCallActivityOnRestoreInstanceState()597     public void testCallActivityOnRestoreInstanceState() throws Exception {
598         mActivity.setOnRestoreInstanceState(false);
599         mInstrumentation.callActivityOnRestoreInstanceState(mActivity, new Bundle());
600         mInstrumentation.waitForIdleSync();
601         assertTrue(mActivity.isOnRestoreInstanceState());
602     }
603 
604     @Test
testSendKeySync()605     public void testSendKeySync() throws Exception {
606         KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0);
607         mInstrumentation.sendKeySync(key);
608         mInstrumentation.waitForIdleSync();
609         assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownCode());
610     }
611 
612     private static class MockRunnable implements Runnable {
613         private boolean mIsRunCalled ;
614 
run()615         public void run() {
616             mIsRunCalled = true;
617         }
618 
isRunCalled()619         public boolean isRunCalled() {
620             return mIsRunCalled;
621         }
622     }
623 
624     private class MockActivity extends Activity {
625         MockWindow mWindow = new MockWindow(mContext);
626 
627         @Override
getWindow()628         public Window getWindow() {
629             return mWindow;
630         }
631 
632         private class MockWindow extends Window {
633 
634             public int mId;
635             public int mFlags;
636 
MockWindow(Context context)637             public MockWindow(Context context) {
638                 super(context);
639             }
640 
641             @Override
addContentView(View view, LayoutParams params)642             public void addContentView(View view, LayoutParams params) {
643             }
644 
645             @Override
closeAllPanels()646             public void closeAllPanels() {
647             }
648 
649             @Override
closePanel(int featureId)650             public void closePanel(int featureId) {
651             }
652 
653             @Override
getCurrentFocus()654             public View getCurrentFocus() {
655                 return null;
656             }
657 
658             @Override
getDecorView()659             public View getDecorView() {
660                 return null;
661             }
662 
663             @Override
getLayoutInflater()664             public LayoutInflater getLayoutInflater() {
665                 return null;
666             }
667 
668             @Override
getVolumeControlStream()669             public int getVolumeControlStream() {
670                 return 0;
671             }
672 
673             @Override
isFloating()674             public boolean isFloating() {
675                 return false;
676             }
677 
678             @Override
isShortcutKey(int keyCode, KeyEvent event)679             public boolean isShortcutKey(int keyCode, KeyEvent event) {
680                 return false;
681             }
682 
683             @Override
onActive()684             protected void onActive() {
685             }
686 
687             @Override
onConfigurationChanged(Configuration newConfig)688             public void onConfigurationChanged(Configuration newConfig) {
689             }
690 
691             @Override
openPanel(int featureId, KeyEvent event)692             public void openPanel(int featureId, KeyEvent event) {
693             }
694 
alwaysReadCloseOnTouchAttr()695             public void alwaysReadCloseOnTouchAttr() {
696             }
697 
698             @Override
peekDecorView()699             public View peekDecorView() {
700                 return null;
701             }
702 
703             @Override
performContextMenuIdentifierAction(int id, int flags)704             public boolean performContextMenuIdentifierAction(int id, int flags) {
705                 mId = id;
706                 mFlags = flags;
707                 return false;
708             }
709 
710             @Override
performPanelIdentifierAction(int featureId, int id, int flags)711             public boolean performPanelIdentifierAction(int featureId, int id, int flags) {
712                 return false;
713             }
714 
715             @Override
performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags)716             public boolean performPanelShortcut(int featureId, int keyCode,
717                     KeyEvent event, int flags) {
718                 return false;
719             }
720 
721             @Override
restoreHierarchyState(Bundle savedInstanceState)722             public void restoreHierarchyState(Bundle savedInstanceState) {
723             }
724 
725             @Override
saveHierarchyState()726             public Bundle saveHierarchyState() {
727                 return null;
728             }
729 
730             @Override
setBackgroundDrawable(Drawable drawable)731             public void setBackgroundDrawable(Drawable drawable) {
732             }
733 
734             @Override
setChildDrawable(int featureId, Drawable drawable)735             public void setChildDrawable(int featureId, Drawable drawable) {
736             }
737 
738             @Override
setChildInt(int featureId, int value)739             public void setChildInt(int featureId, int value) {
740             }
741 
742             @Override
setContentView(int layoutResID)743             public void setContentView(int layoutResID) {
744             }
745 
746             @Override
setContentView(View view)747             public void setContentView(View view) {
748             }
749 
750             @Override
setContentView(View view, LayoutParams params)751             public void setContentView(View view, LayoutParams params) {
752             }
753 
754             @Override
setFeatureDrawable(int featureId, Drawable drawable)755             public void setFeatureDrawable(int featureId, Drawable drawable) {
756             }
757 
758             @Override
setFeatureDrawableAlpha(int featureId, int alpha)759             public void setFeatureDrawableAlpha(int featureId, int alpha) {
760             }
761 
762             @Override
setFeatureDrawableResource(int featureId, int resId)763             public void setFeatureDrawableResource(int featureId, int resId) {
764             }
765 
766             @Override
setFeatureDrawableUri(int featureId, Uri uri)767             public void setFeatureDrawableUri(int featureId, Uri uri) {
768             }
769 
770             @Override
setFeatureInt(int featureId, int value)771             public void setFeatureInt(int featureId, int value) {
772             }
773 
774             @Override
setTitle(CharSequence title)775             public void setTitle(CharSequence title) {
776             }
777 
778             @Override
setTitleColor(int textColor)779             public void setTitleColor(int textColor) {
780             }
781 
782             @Override
setVolumeControlStream(int streamType)783             public void setVolumeControlStream(int streamType) {
784             }
785 
786             @Override
superDispatchKeyEvent(KeyEvent event)787             public boolean superDispatchKeyEvent(KeyEvent event) {
788                 return false;
789             }
790 
791             @Override
superDispatchKeyShortcutEvent(KeyEvent event)792             public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
793                 return false;
794             }
795 
796             @Override
superDispatchTouchEvent(MotionEvent event)797             public boolean superDispatchTouchEvent(MotionEvent event) {
798                 return false;
799             }
800 
801             @Override
superDispatchTrackballEvent(MotionEvent event)802             public boolean superDispatchTrackballEvent(MotionEvent event) {
803                 return false;
804             }
805 
806             @Override
superDispatchGenericMotionEvent(MotionEvent event)807             public boolean superDispatchGenericMotionEvent(MotionEvent event) {
808                 return false;
809             }
810 
811             @Override
takeKeyEvents(boolean get)812             public void takeKeyEvents(boolean get) {
813             }
814 
815             @Override
togglePanel(int featureId, KeyEvent event)816             public void togglePanel(int featureId, KeyEvent event) {
817             }
818 
819             @Override
invalidatePanelMenu(int featureId)820             public void invalidatePanelMenu(int featureId) {
821             }
822 
823             @Override
takeSurface(SurfaceHolder.Callback2 callback)824             public void takeSurface(SurfaceHolder.Callback2 callback) {
825             }
826 
827             @Override
takeInputQueue(InputQueue.Callback queue)828             public void takeInputQueue(InputQueue.Callback queue) {
829             }
830 
831             @Override
setStatusBarColor(int color)832             public void setStatusBarColor(int color) {
833             }
834 
835             @Override
getStatusBarColor()836             public int getStatusBarColor() {
837                 return 0;
838             }
839 
840             @Override
setNavigationBarColor(int color)841             public void setNavigationBarColor(int color) {
842             }
843 
844             @Override
setDecorCaptionShade(int decorCaptionShade)845             public void setDecorCaptionShade(int decorCaptionShade) {
846             }
847 
848             @Override
setResizingCaptionDrawable(Drawable drawable)849             public void setResizingCaptionDrawable(Drawable drawable) {
850             }
851 
852             @Override
getNavigationBarColor()853             public int getNavigationBarColor() {
854                 return 0;
855             }
856         }
857     }
858 
859     private static class InstrumentationTestStub extends Application {
860         boolean mIsOnCreateCalled = false;
861 
862         @Override
onCreate()863         public void onCreate() {
864             super.onCreate();
865             mIsOnCreateCalled = true;
866         }
867     }
868 
runTestOnUiThread(final Runnable r)869     private void runTestOnUiThread(final Runnable r) throws Throwable {
870         final Throwable[] exceptions = new Throwable[1];
871         mInstrumentation.runOnMainSync(new Runnable() {
872             public void run() {
873                 try {
874                     r.run();
875                 } catch (Throwable throwable) {
876                     exceptions[0] = throwable;
877                 }
878             }
879         });
880         if (exceptions[0] != null) {
881             throw exceptions[0];
882         }
883     }
884 }
885