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 testCallActivityOnResume()332 public void testCallActivityOnResume() throws Throwable { 333 mActivity.setOnResume(false); 334 runTestOnUiThread(new Runnable() { 335 public void run() { 336 mInstrumentation.callActivityOnResume(mActivity); 337 } 338 }); 339 mInstrumentation.waitForIdleSync(); 340 assertTrue(mActivity.isOnResume()); 341 } 342 343 @Test testMisc()344 public void testMisc() throws Exception { 345 } 346 347 @Test testPerformanceSnapshot()348 public void testPerformanceSnapshot() throws Exception { 349 mInstrumentation.setAutomaticPerformanceSnapshots(); 350 mInstrumentation.startPerformanceSnapshot(); 351 mInstrumentation.endPerformanceSnapshot(); 352 } 353 354 @Test testProfiling()355 public void testProfiling() throws Exception { 356 // by default, profiling was disabled. but after set the handleProfiling attribute in the 357 // manifest file for this Instrumentation to true, the profiling was also disabled. 358 assertFalse(mInstrumentation.isProfiling()); 359 360 mInstrumentation.startProfiling(); 361 mInstrumentation.stopProfiling(); 362 } 363 364 @Test testInvokeContextMenuAction()365 public void testInvokeContextMenuAction() throws Exception { 366 mActivity.runOnUiThread(new Runnable() { 367 public void run() { 368 mMockActivity = new MockActivity(); 369 } 370 }); 371 mInstrumentation.waitForIdleSync(); 372 final int id = 1; 373 final int flag = 2; 374 mInstrumentation.invokeContextMenuAction(mMockActivity, id, flag); 375 mInstrumentation.waitForIdleSync(); 376 377 assertEquals(id, mMockActivity.mWindow.mId); 378 assertEquals(flag, mMockActivity.mWindow.mFlags); 379 } 380 381 @Test testSendStringSync()382 public void testSendStringSync() { 383 final String text = "abcd"; 384 mInstrumentation.sendStringSync(text); 385 mInstrumentation.waitForIdleSync(); 386 387 List<KeyEvent> keyUpList = mActivity.getKeyUpList(); 388 List<KeyEvent> keyDownList = mActivity.getKeyDownList(); 389 assertEquals(text.length(), keyDownList.size()); 390 assertEquals(text.length(), keyUpList.size()); 391 392 KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); 393 KeyEvent[] keyEvents = kcm.getEvents(text.toCharArray()); 394 395 int i = 0; 396 for (int j = 0; j < keyDownList.size(); j++) { 397 assertEquals(keyEvents[i++].getKeyCode(), keyDownList.get(j).getKeyCode()); 398 assertEquals(keyEvents[i++].getKeyCode(), keyUpList.get(j).getKeyCode()); 399 } 400 } 401 402 @Test testCallActivityOnSaveInstanceState()403 public void testCallActivityOnSaveInstanceState() throws Throwable { 404 final Bundle bundle = new Bundle(); 405 mActivity.setOnSaveInstanceState(false); 406 runTestOnUiThread(new Runnable() { 407 public void run() { 408 mInstrumentation.callActivityOnSaveInstanceState(mActivity, bundle); 409 } 410 }); 411 mInstrumentation.waitForIdleSync(); 412 413 assertTrue(mActivity.isOnSaveInstanceState()); 414 assertSame(bundle, mActivity.getBundle()); 415 } 416 417 @Test testSendPointerSync()418 public void testSendPointerSync() throws Exception { 419 mInstrumentation.waitForIdleSync(); 420 mInstrumentation.setInTouchMode(true); 421 422 // Send a touch event to the middle of the activity. 423 // We assume that the Activity is empty so there won't be anything in the middle 424 // to handle the touch. Consequently the Activity should receive onTouchEvent 425 // because nothing else handled it. 426 final Rect bounds = mActivity.getWindowManager().getCurrentWindowMetrics().getBounds(); 427 final int x = bounds.centerX(); 428 final int y = bounds.centerY(); 429 long now = SystemClock.uptimeMillis(); 430 MotionEvent orig = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 431 x, y, 0); 432 mInstrumentation.sendPointerSync(orig); 433 434 mInstrumentation.waitForIdleSync(); 435 assertTrue(mActivity.isOnTouchEventCalled()); 436 mActivity.setOnTouchEventCalled(false); 437 } 438 439 @Test testGetComponentName()440 public void testGetComponentName() throws Exception { 441 ComponentName com = mInstrumentation.getComponentName(); 442 assertNotNull(com.getPackageName()); 443 assertNotNull(com.getClassName()); 444 assertNotNull(com.getShortClassName()); 445 } 446 447 @Test testNewApplication()448 public void testNewApplication() throws Exception { 449 final String className = "android.app.stubs.MockApplication"; 450 ClassLoader cl = getClass().getClassLoader(); 451 452 Application app = mInstrumentation.newApplication(cl, className, mContext); 453 assertEquals(className, app.getClass().getName()); 454 455 app = Instrumentation.newApplication(MockApplication.class, mContext); 456 assertEquals(className, app.getClass().getName()); 457 } 458 459 @Test testRunOnMainSync()460 public void testRunOnMainSync() throws Exception { 461 mRunOnMainSyncResult = false; 462 mInstrumentation.runOnMainSync(new Runnable() { 463 public void run() { 464 mRunOnMainSyncResult = true; 465 } 466 }); 467 mInstrumentation.waitForIdleSync(); 468 assertTrue(mRunOnMainSyncResult); 469 } 470 471 @Test testCallActivityOnPause()472 public void testCallActivityOnPause() throws Throwable { 473 mActivity.setOnPauseCalled(false); 474 runTestOnUiThread(() -> { 475 mInstrumentation.callActivityOnPause(mActivity); 476 }); 477 mInstrumentation.waitForIdleSync(); 478 assertTrue(mActivity.isOnPauseCalled()); 479 } 480 481 @Test testSendKeyDownUpSync()482 public void testSendKeyDownUpSync() throws Exception { 483 mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_0); 484 mInstrumentation.waitForIdleSync(); 485 assertEquals(1, mActivity.getKeyUpList().size()); 486 assertEquals(1, mActivity.getKeyDownList().size()); 487 assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpList().get(0).getKeyCode()); 488 assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownList().get(0).getKeyCode()); 489 } 490 491 @Test 492 @UiThreadTest testNewActivity()493 public void testNewActivity() throws Exception { 494 Intent intent = new Intent(); 495 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 496 497 ClassLoader cl = getClass().getClassLoader(); 498 Activity activity = mInstrumentation.newActivity(cl, InstrumentationTestActivity.class 499 .getName(), intent); 500 assertEquals(InstrumentationTestActivity.class.getName(), activity.getClass().getName()); 501 activity.finish(); 502 activity = null; 503 504 intent = new Intent(mContext, InstrumentationTestActivity.class); 505 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 506 507 Activity father = new Activity(); 508 ActivityInfo info = new ActivityInfo(); 509 510 activity = mInstrumentation 511 .newActivity(InstrumentationTestActivity.class, mContext, null, null, intent, info, 512 InstrumentationTestActivity.class.getName(), father, null, null); 513 514 assertEquals(father, activity.getParent()); 515 assertEquals(InstrumentationTestActivity.class.getName(), activity.getClass().getName()); 516 activity.finish(); 517 } 518 519 @Test testCallActivityOnStart()520 public void testCallActivityOnStart() throws Exception { 521 mActivity.setOnStart(false); 522 mInstrumentation.callActivityOnStart(mActivity); 523 mInstrumentation.waitForIdleSync(); 524 assertTrue(mActivity.isOnStart()); 525 } 526 527 @Test testWaitForIdle()528 public void testWaitForIdle() throws Exception { 529 MockRunnable mr = new MockRunnable(); 530 assertFalse(mr.isRunCalled()); 531 mInstrumentation.waitForIdle(mr); 532 Thread.sleep(WAIT_TIME); 533 assertTrue(mr.isRunCalled()); 534 } 535 536 @Test testSendCharacterSync()537 public void testSendCharacterSync() throws Exception { 538 mInstrumentation.sendCharacterSync(KeyEvent.KEYCODE_0); 539 mInstrumentation.waitForIdleSync(); 540 assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownCode()); 541 assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyUpCode()); 542 } 543 544 @Test testCallActivityOnRestart()545 public void testCallActivityOnRestart() throws Exception { 546 mActivity.setOnRestart(false); 547 mInstrumentation.callActivityOnRestart(mActivity); 548 mInstrumentation.waitForIdleSync(); 549 assertTrue(mActivity.isOnRestart()); 550 } 551 552 @Test testCallActivityOnStop()553 public void testCallActivityOnStop() throws Exception { 554 mActivity.setOnStop(false); 555 mInstrumentation.callActivityOnStop(mActivity); 556 mInstrumentation.waitForIdleSync(); 557 assertTrue(mActivity.isOnStop()); 558 } 559 560 @Test testCallActivityOnUserLeaving()561 public void testCallActivityOnUserLeaving() throws Exception { 562 assertFalse(mActivity.isOnLeave()); 563 mInstrumentation.callActivityOnUserLeaving(mActivity); 564 mInstrumentation.waitForIdleSync(); 565 assertTrue(mActivity.isOnLeave()); 566 } 567 568 @Test testCallActivityOnRestoreInstanceState()569 public void testCallActivityOnRestoreInstanceState() throws Exception { 570 mActivity.setOnRestoreInstanceState(false); 571 mInstrumentation.callActivityOnRestoreInstanceState(mActivity, new Bundle()); 572 mInstrumentation.waitForIdleSync(); 573 assertTrue(mActivity.isOnRestoreInstanceState()); 574 } 575 576 @Test testSendKeySync()577 public void testSendKeySync() throws Exception { 578 KeyEvent key = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0); 579 mInstrumentation.sendKeySync(key); 580 mInstrumentation.waitForIdleSync(); 581 assertEquals(KeyEvent.KEYCODE_0, mActivity.getKeyDownCode()); 582 } 583 584 private static class MockRunnable implements Runnable { 585 private boolean mIsRunCalled ; 586 run()587 public void run() { 588 mIsRunCalled = true; 589 } 590 isRunCalled()591 public boolean isRunCalled() { 592 return mIsRunCalled; 593 } 594 } 595 596 private class MockActivity extends Activity { 597 MockWindow mWindow = new MockWindow(mContext); 598 599 @Override getWindow()600 public Window getWindow() { 601 return mWindow; 602 } 603 604 private class MockWindow extends Window { 605 606 public int mId; 607 public int mFlags; 608 MockWindow(Context context)609 public MockWindow(Context context) { 610 super(context); 611 } 612 613 @Override addContentView(View view, LayoutParams params)614 public void addContentView(View view, LayoutParams params) { 615 } 616 617 @Override closeAllPanels()618 public void closeAllPanels() { 619 } 620 621 @Override closePanel(int featureId)622 public void closePanel(int featureId) { 623 } 624 625 @Override getCurrentFocus()626 public View getCurrentFocus() { 627 return null; 628 } 629 630 @Override getDecorView()631 public View getDecorView() { 632 return null; 633 } 634 635 @Override getLayoutInflater()636 public LayoutInflater getLayoutInflater() { 637 return null; 638 } 639 640 @Override getVolumeControlStream()641 public int getVolumeControlStream() { 642 return 0; 643 } 644 645 @Override isFloating()646 public boolean isFloating() { 647 return false; 648 } 649 650 @Override isShortcutKey(int keyCode, KeyEvent event)651 public boolean isShortcutKey(int keyCode, KeyEvent event) { 652 return false; 653 } 654 655 @Override onActive()656 protected void onActive() { 657 } 658 659 @Override onConfigurationChanged(Configuration newConfig)660 public void onConfigurationChanged(Configuration newConfig) { 661 } 662 663 @Override openPanel(int featureId, KeyEvent event)664 public void openPanel(int featureId, KeyEvent event) { 665 } 666 alwaysReadCloseOnTouchAttr()667 public void alwaysReadCloseOnTouchAttr() { 668 } 669 670 @Override peekDecorView()671 public View peekDecorView() { 672 return null; 673 } 674 675 @Override performContextMenuIdentifierAction(int id, int flags)676 public boolean performContextMenuIdentifierAction(int id, int flags) { 677 mId = id; 678 mFlags = flags; 679 return false; 680 } 681 682 @Override performPanelIdentifierAction(int featureId, int id, int flags)683 public boolean performPanelIdentifierAction(int featureId, int id, int flags) { 684 return false; 685 } 686 687 @Override performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags)688 public boolean performPanelShortcut(int featureId, int keyCode, 689 KeyEvent event, int flags) { 690 return false; 691 } 692 693 @Override restoreHierarchyState(Bundle savedInstanceState)694 public void restoreHierarchyState(Bundle savedInstanceState) { 695 } 696 697 @Override saveHierarchyState()698 public Bundle saveHierarchyState() { 699 return null; 700 } 701 702 @Override setBackgroundDrawable(Drawable drawable)703 public void setBackgroundDrawable(Drawable drawable) { 704 } 705 706 @Override setChildDrawable(int featureId, Drawable drawable)707 public void setChildDrawable(int featureId, Drawable drawable) { 708 } 709 710 @Override setChildInt(int featureId, int value)711 public void setChildInt(int featureId, int value) { 712 } 713 714 @Override setContentView(int layoutResID)715 public void setContentView(int layoutResID) { 716 } 717 718 @Override setContentView(View view)719 public void setContentView(View view) { 720 } 721 722 @Override setContentView(View view, LayoutParams params)723 public void setContentView(View view, LayoutParams params) { 724 } 725 726 @Override setFeatureDrawable(int featureId, Drawable drawable)727 public void setFeatureDrawable(int featureId, Drawable drawable) { 728 } 729 730 @Override setFeatureDrawableAlpha(int featureId, int alpha)731 public void setFeatureDrawableAlpha(int featureId, int alpha) { 732 } 733 734 @Override setFeatureDrawableResource(int featureId, int resId)735 public void setFeatureDrawableResource(int featureId, int resId) { 736 } 737 738 @Override setFeatureDrawableUri(int featureId, Uri uri)739 public void setFeatureDrawableUri(int featureId, Uri uri) { 740 } 741 742 @Override setFeatureInt(int featureId, int value)743 public void setFeatureInt(int featureId, int value) { 744 } 745 746 @Override setTitle(CharSequence title)747 public void setTitle(CharSequence title) { 748 } 749 750 @Override setTitleColor(int textColor)751 public void setTitleColor(int textColor) { 752 } 753 754 @Override setVolumeControlStream(int streamType)755 public void setVolumeControlStream(int streamType) { 756 } 757 758 @Override superDispatchKeyEvent(KeyEvent event)759 public boolean superDispatchKeyEvent(KeyEvent event) { 760 return false; 761 } 762 763 @Override superDispatchKeyShortcutEvent(KeyEvent event)764 public boolean superDispatchKeyShortcutEvent(KeyEvent event) { 765 return false; 766 } 767 768 @Override superDispatchTouchEvent(MotionEvent event)769 public boolean superDispatchTouchEvent(MotionEvent event) { 770 return false; 771 } 772 773 @Override superDispatchTrackballEvent(MotionEvent event)774 public boolean superDispatchTrackballEvent(MotionEvent event) { 775 return false; 776 } 777 778 @Override superDispatchGenericMotionEvent(MotionEvent event)779 public boolean superDispatchGenericMotionEvent(MotionEvent event) { 780 return false; 781 } 782 783 @Override takeKeyEvents(boolean get)784 public void takeKeyEvents(boolean get) { 785 } 786 787 @Override togglePanel(int featureId, KeyEvent event)788 public void togglePanel(int featureId, KeyEvent event) { 789 } 790 791 @Override invalidatePanelMenu(int featureId)792 public void invalidatePanelMenu(int featureId) { 793 } 794 795 @Override takeSurface(SurfaceHolder.Callback2 callback)796 public void takeSurface(SurfaceHolder.Callback2 callback) { 797 } 798 799 @Override takeInputQueue(InputQueue.Callback queue)800 public void takeInputQueue(InputQueue.Callback queue) { 801 } 802 803 @Override setStatusBarColor(int color)804 public void setStatusBarColor(int color) { 805 } 806 807 @Override getStatusBarColor()808 public int getStatusBarColor() { 809 return 0; 810 } 811 812 @Override setNavigationBarColor(int color)813 public void setNavigationBarColor(int color) { 814 } 815 816 @Override setDecorCaptionShade(int decorCaptionShade)817 public void setDecorCaptionShade(int decorCaptionShade) { 818 } 819 820 @Override setResizingCaptionDrawable(Drawable drawable)821 public void setResizingCaptionDrawable(Drawable drawable) { 822 } 823 824 @Override getNavigationBarColor()825 public int getNavigationBarColor() { 826 return 0; 827 } 828 } 829 } 830 831 private static class InstrumentationTestStub extends Application { 832 boolean mIsOnCreateCalled = false; 833 834 @Override onCreate()835 public void onCreate() { 836 super.onCreate(); 837 mIsOnCreateCalled = true; 838 } 839 } 840 runTestOnUiThread(final Runnable r)841 private void runTestOnUiThread(final Runnable r) throws Throwable { 842 final Throwable[] exceptions = new Throwable[1]; 843 mInstrumentation.runOnMainSync(new Runnable() { 844 public void run() { 845 try { 846 r.run(); 847 } catch (Throwable throwable) { 848 exceptions[0] = throwable; 849 } 850 } 851 }); 852 if (exceptions[0] != null) { 853 throw exceptions[0]; 854 } 855 } 856 } 857