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