Am.java revision c652de8141f5b8e3c6bcf8916842b6e106413b1a
1/* 2** 3** Copyright 2007, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18 19package com.android.commands.am; 20 21import android.app.ActivityManager; 22import android.app.ActivityManagerNative; 23import android.app.IActivityController; 24import android.app.IActivityManager; 25import android.app.IInstrumentationWatcher; 26import android.app.Instrumentation; 27import android.app.UiAutomationConnection; 28import android.content.ComponentName; 29import android.content.IIntentReceiver; 30import android.content.Intent; 31import android.content.pm.IPackageManager; 32import android.content.pm.ResolveInfo; 33import android.net.Uri; 34import android.os.Bundle; 35import android.os.ParcelFileDescriptor; 36import android.os.RemoteException; 37import android.os.ServiceManager; 38import android.os.SystemProperties; 39import android.os.UserHandle; 40import android.util.AndroidException; 41import android.view.IWindowManager; 42 43import java.io.BufferedReader; 44import java.io.File; 45import java.io.FileNotFoundException; 46import java.io.IOException; 47import java.io.InputStreamReader; 48import java.io.PrintStream; 49import java.net.URISyntaxException; 50import java.util.HashSet; 51import java.util.List; 52 53public class Am { 54 55 private IActivityManager mAm; 56 private String[] mArgs; 57 private int mNextArg; 58 private String mCurArgData; 59 60 private int mStartFlags = 0; 61 private boolean mWaitOption = false; 62 private boolean mStopOption = false; 63 64 private int mRepeat = 0; 65 private int mUserId; 66 67 private String mProfileFile; 68 69 // These are magic strings understood by the Eclipse plugin. 70 private static final String FATAL_ERROR_CODE = "Error type 1"; 71 private static final String NO_SYSTEM_ERROR_CODE = "Error type 2"; 72 private static final String NO_CLASS_ERROR_CODE = "Error type 3"; 73 74 /** 75 * Command-line entry point. 76 * 77 * @param args The command-line arguments 78 */ 79 public static void main(String[] args) { 80 try { 81 (new Am()).run(args); 82 } catch (IllegalArgumentException e) { 83 showUsage(); 84 System.err.println("Error: " + e.getMessage()); 85 } catch (Exception e) { 86 e.printStackTrace(System.err); 87 System.exit(1); 88 } 89 } 90 91 private void run(String[] args) throws Exception { 92 if (args.length < 1) { 93 showUsage(); 94 return; 95 } 96 97 mAm = ActivityManagerNative.getDefault(); 98 if (mAm == null) { 99 System.err.println(NO_SYSTEM_ERROR_CODE); 100 throw new AndroidException("Can't connect to activity manager; is the system running?"); 101 } 102 103 mArgs = args; 104 String op = args[0]; 105 mNextArg = 1; 106 107 if (op.equals("start")) { 108 runStart(); 109 } else if (op.equals("startservice")) { 110 runStartService(); 111 } else if (op.equals("force-stop")) { 112 runForceStop(); 113 } else if (op.equals("kill")) { 114 runKill(); 115 } else if (op.equals("kill-all")) { 116 runKillAll(); 117 } else if (op.equals("instrument")) { 118 runInstrument(); 119 } else if (op.equals("broadcast")) { 120 sendBroadcast(); 121 } else if (op.equals("profile")) { 122 runProfile(); 123 } else if (op.equals("dumpheap")) { 124 runDumpHeap(); 125 } else if (op.equals("set-debug-app")) { 126 runSetDebugApp(); 127 } else if (op.equals("clear-debug-app")) { 128 runClearDebugApp(); 129 } else if (op.equals("bug-report")) { 130 runBugReport(); 131 } else if (op.equals("monitor")) { 132 runMonitor(); 133 } else if (op.equals("screen-compat")) { 134 runScreenCompat(); 135 } else if (op.equals("to-uri")) { 136 runToUri(false); 137 } else if (op.equals("to-intent-uri")) { 138 runToUri(true); 139 } else if (op.equals("switch-user")) { 140 runSwitchUser(); 141 } else if (op.equals("stop-user")) { 142 runStopUser(); 143 } else { 144 throw new IllegalArgumentException("Unknown command: " + op); 145 } 146 } 147 148 int parseUserArg(String arg) { 149 int userId; 150 if ("all".equals(arg)) { 151 userId = UserHandle.USER_ALL; 152 } else if ("current".equals(arg) || "cur".equals(arg)) { 153 userId = UserHandle.USER_CURRENT; 154 } else { 155 userId = Integer.parseInt(arg); 156 } 157 return userId; 158 } 159 160 private Intent makeIntent(int defUser) throws URISyntaxException { 161 Intent intent = new Intent(); 162 Intent baseIntent = intent; 163 boolean hasIntentInfo = false; 164 165 mStartFlags = 0; 166 mWaitOption = false; 167 mStopOption = false; 168 mRepeat = 0; 169 mProfileFile = null; 170 mUserId = defUser; 171 Uri data = null; 172 String type = null; 173 174 String opt; 175 while ((opt=nextOption()) != null) { 176 if (opt.equals("-a")) { 177 intent.setAction(nextArgRequired()); 178 if (intent == baseIntent) { 179 hasIntentInfo = true; 180 } 181 } else if (opt.equals("-d")) { 182 data = Uri.parse(nextArgRequired()); 183 if (intent == baseIntent) { 184 hasIntentInfo = true; 185 } 186 } else if (opt.equals("-t")) { 187 type = nextArgRequired(); 188 if (intent == baseIntent) { 189 hasIntentInfo = true; 190 } 191 } else if (opt.equals("-c")) { 192 intent.addCategory(nextArgRequired()); 193 if (intent == baseIntent) { 194 hasIntentInfo = true; 195 } 196 } else if (opt.equals("-e") || opt.equals("--es")) { 197 String key = nextArgRequired(); 198 String value = nextArgRequired(); 199 intent.putExtra(key, value); 200 } else if (opt.equals("--esn")) { 201 String key = nextArgRequired(); 202 intent.putExtra(key, (String) null); 203 } else if (opt.equals("--ei")) { 204 String key = nextArgRequired(); 205 String value = nextArgRequired(); 206 intent.putExtra(key, Integer.valueOf(value)); 207 } else if (opt.equals("--eu")) { 208 String key = nextArgRequired(); 209 String value = nextArgRequired(); 210 intent.putExtra(key, Uri.parse(value)); 211 } else if (opt.equals("--ecn")) { 212 String key = nextArgRequired(); 213 String value = nextArgRequired(); 214 ComponentName cn = ComponentName.unflattenFromString(value); 215 if (cn == null) throw new IllegalArgumentException("Bad component name: " + value); 216 intent.putExtra(key, cn); 217 } else if (opt.equals("--eia")) { 218 String key = nextArgRequired(); 219 String value = nextArgRequired(); 220 String[] strings = value.split(","); 221 int[] list = new int[strings.length]; 222 for (int i = 0; i < strings.length; i++) { 223 list[i] = Integer.valueOf(strings[i]); 224 } 225 intent.putExtra(key, list); 226 } else if (opt.equals("--el")) { 227 String key = nextArgRequired(); 228 String value = nextArgRequired(); 229 intent.putExtra(key, Long.valueOf(value)); 230 } else if (opt.equals("--ela")) { 231 String key = nextArgRequired(); 232 String value = nextArgRequired(); 233 String[] strings = value.split(","); 234 long[] list = new long[strings.length]; 235 for (int i = 0; i < strings.length; i++) { 236 list[i] = Long.valueOf(strings[i]); 237 } 238 intent.putExtra(key, list); 239 hasIntentInfo = true; 240 } else if (opt.equals("--ef")) { 241 String key = nextArgRequired(); 242 String value = nextArgRequired(); 243 intent.putExtra(key, Float.valueOf(value)); 244 hasIntentInfo = true; 245 } else if (opt.equals("--efa")) { 246 String key = nextArgRequired(); 247 String value = nextArgRequired(); 248 String[] strings = value.split(","); 249 float[] list = new float[strings.length]; 250 for (int i = 0; i < strings.length; i++) { 251 list[i] = Float.valueOf(strings[i]); 252 } 253 intent.putExtra(key, list); 254 hasIntentInfo = true; 255 } else if (opt.equals("--ez")) { 256 String key = nextArgRequired(); 257 String value = nextArgRequired(); 258 intent.putExtra(key, Boolean.valueOf(value)); 259 } else if (opt.equals("-n")) { 260 String str = nextArgRequired(); 261 ComponentName cn = ComponentName.unflattenFromString(str); 262 if (cn == null) throw new IllegalArgumentException("Bad component name: " + str); 263 intent.setComponent(cn); 264 if (intent == baseIntent) { 265 hasIntentInfo = true; 266 } 267 } else if (opt.equals("-f")) { 268 String str = nextArgRequired(); 269 intent.setFlags(Integer.decode(str).intValue()); 270 } else if (opt.equals("--grant-read-uri-permission")) { 271 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 272 } else if (opt.equals("--grant-write-uri-permission")) { 273 intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 274 } else if (opt.equals("--exclude-stopped-packages")) { 275 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 276 } else if (opt.equals("--include-stopped-packages")) { 277 intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 278 } else if (opt.equals("--debug-log-resolution")) { 279 intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION); 280 } else if (opt.equals("--activity-brought-to-front")) { 281 intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); 282 } else if (opt.equals("--activity-clear-top")) { 283 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 284 } else if (opt.equals("--activity-clear-when-task-reset")) { 285 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 286 } else if (opt.equals("--activity-exclude-from-recents")) { 287 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 288 } else if (opt.equals("--activity-launched-from-history")) { 289 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 290 } else if (opt.equals("--activity-multiple-task")) { 291 intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 292 } else if (opt.equals("--activity-no-animation")) { 293 intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); 294 } else if (opt.equals("--activity-no-history")) { 295 intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 296 } else if (opt.equals("--activity-no-user-action")) { 297 intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION); 298 } else if (opt.equals("--activity-previous-is-top")) { 299 intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); 300 } else if (opt.equals("--activity-reorder-to-front")) { 301 intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 302 } else if (opt.equals("--activity-reset-task-if-needed")) { 303 intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 304 } else if (opt.equals("--activity-single-top")) { 305 intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 306 } else if (opt.equals("--activity-clear-task")) { 307 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); 308 } else if (opt.equals("--activity-task-on-home")) { 309 intent.addFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME); 310 } else if (opt.equals("--receiver-registered-only")) { 311 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 312 } else if (opt.equals("--receiver-replace-pending")) { 313 intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 314 } else if (opt.equals("--selector")) { 315 intent.setDataAndType(data, type); 316 intent = new Intent(); 317 } else if (opt.equals("-D")) { 318 mStartFlags |= ActivityManager.START_FLAG_DEBUG; 319 } else if (opt.equals("-W")) { 320 mWaitOption = true; 321 } else if (opt.equals("-P")) { 322 mProfileFile = nextArgRequired(); 323 mStartFlags |= ActivityManager.START_FLAG_AUTO_STOP_PROFILER; 324 } else if (opt.equals("--start-profiler")) { 325 mProfileFile = nextArgRequired(); 326 mStartFlags &= ~ActivityManager.START_FLAG_AUTO_STOP_PROFILER; 327 } else if (opt.equals("-R")) { 328 mRepeat = Integer.parseInt(nextArgRequired()); 329 } else if (opt.equals("-S")) { 330 mStopOption = true; 331 } else if (opt.equals("--opengl-trace")) { 332 mStartFlags |= ActivityManager.START_FLAG_OPENGL_TRACES; 333 } else if (opt.equals("--user")) { 334 mUserId = parseUserArg(nextArgRequired()); 335 } else { 336 System.err.println("Error: Unknown option: " + opt); 337 return null; 338 } 339 } 340 intent.setDataAndType(data, type); 341 342 final boolean hasSelector = intent != baseIntent; 343 if (hasSelector) { 344 // A selector was specified; fix up. 345 baseIntent.setSelector(intent); 346 intent = baseIntent; 347 } 348 349 String arg = nextArg(); 350 baseIntent = null; 351 if (arg == null) { 352 if (hasSelector) { 353 // If a selector has been specified, and no arguments 354 // have been supplied for the main Intent, then we can 355 // assume it is ACTION_MAIN CATEGORY_LAUNCHER; we don't 356 // need to have a component name specified yet, the 357 // selector will take care of that. 358 baseIntent = new Intent(Intent.ACTION_MAIN); 359 baseIntent.addCategory(Intent.CATEGORY_LAUNCHER); 360 } 361 } else if (arg.indexOf(':') >= 0) { 362 // The argument is a URI. Fully parse it, and use that result 363 // to fill in any data not specified so far. 364 baseIntent = Intent.parseUri(arg, Intent.URI_INTENT_SCHEME); 365 } else if (arg.indexOf('/') >= 0) { 366 // The argument is a component name. Build an Intent to launch 367 // it. 368 baseIntent = new Intent(Intent.ACTION_MAIN); 369 baseIntent.addCategory(Intent.CATEGORY_LAUNCHER); 370 baseIntent.setComponent(ComponentName.unflattenFromString(arg)); 371 } else { 372 // Assume the argument is a package name. 373 baseIntent = new Intent(Intent.ACTION_MAIN); 374 baseIntent.addCategory(Intent.CATEGORY_LAUNCHER); 375 baseIntent.setPackage(arg); 376 } 377 if (baseIntent != null) { 378 Bundle extras = intent.getExtras(); 379 intent.replaceExtras((Bundle)null); 380 Bundle uriExtras = baseIntent.getExtras(); 381 baseIntent.replaceExtras((Bundle)null); 382 if (intent.getAction() != null && baseIntent.getCategories() != null) { 383 HashSet<String> cats = new HashSet<String>(baseIntent.getCategories()); 384 for (String c : cats) { 385 baseIntent.removeCategory(c); 386 } 387 } 388 intent.fillIn(baseIntent, Intent.FILL_IN_COMPONENT | Intent.FILL_IN_SELECTOR); 389 if (extras == null) { 390 extras = uriExtras; 391 } else if (uriExtras != null) { 392 uriExtras.putAll(extras); 393 extras = uriExtras; 394 } 395 intent.replaceExtras(extras); 396 hasIntentInfo = true; 397 } 398 399 if (!hasIntentInfo) throw new IllegalArgumentException("No intent supplied"); 400 return intent; 401 } 402 403 private void runStartService() throws Exception { 404 Intent intent = makeIntent(UserHandle.USER_CURRENT); 405 if (mUserId == UserHandle.USER_ALL) { 406 System.err.println("Error: Can't start activity with user 'all'"); 407 return; 408 } 409 System.out.println("Starting service: " + intent); 410 ComponentName cn = mAm.startService(null, intent, intent.getType(), mUserId); 411 if (cn == null) { 412 System.err.println("Error: Not found; no service started."); 413 } else if (cn.getPackageName().equals("!")) { 414 System.err.println("Error: Requires permission " + cn.getClassName()); 415 } else if (cn.getPackageName().equals("!!")) { 416 System.err.println("Error: " + cn.getClassName()); 417 } 418 } 419 420 private void runStart() throws Exception { 421 Intent intent = makeIntent(UserHandle.USER_CURRENT); 422 423 if (mUserId == UserHandle.USER_ALL) { 424 System.err.println("Error: Can't start service with user 'all'"); 425 return; 426 } 427 428 String mimeType = intent.getType(); 429 if (mimeType == null && intent.getData() != null 430 && "content".equals(intent.getData().getScheme())) { 431 mimeType = mAm.getProviderMimeType(intent.getData(), mUserId); 432 } 433 434 do { 435 if (mStopOption) { 436 String packageName; 437 if (intent.getComponent() != null) { 438 packageName = intent.getComponent().getPackageName(); 439 } else { 440 IPackageManager pm = IPackageManager.Stub.asInterface( 441 ServiceManager.getService("package")); 442 if (pm == null) { 443 System.err.println("Error: Package manager not running; aborting"); 444 return; 445 } 446 List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0, 447 mUserId); 448 if (activities == null || activities.size() <= 0) { 449 System.err.println("Error: Intent does not match any activities: " 450 + intent); 451 return; 452 } else if (activities.size() > 1) { 453 System.err.println("Error: Intent matches multiple activities; can't stop: " 454 + intent); 455 return; 456 } 457 packageName = activities.get(0).activityInfo.packageName; 458 } 459 System.out.println("Stopping: " + packageName); 460 mAm.forceStopPackage(packageName, mUserId); 461 Thread.sleep(250); 462 } 463 464 System.out.println("Starting: " + intent); 465 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 466 467 ParcelFileDescriptor fd = null; 468 469 if (mProfileFile != null) { 470 try { 471 fd = ParcelFileDescriptor.open( 472 new File(mProfileFile), 473 ParcelFileDescriptor.MODE_CREATE | 474 ParcelFileDescriptor.MODE_TRUNCATE | 475 ParcelFileDescriptor.MODE_READ_WRITE); 476 } catch (FileNotFoundException e) { 477 System.err.println("Error: Unable to open file: " + mProfileFile); 478 return; 479 } 480 } 481 482 IActivityManager.WaitResult result = null; 483 int res; 484 if (mWaitOption) { 485 result = mAm.startActivityAndWait(null, null, intent, mimeType, 486 null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId); 487 res = result.result; 488 } else { 489 res = mAm.startActivityAsUser(null, null, intent, mimeType, 490 null, null, 0, mStartFlags, mProfileFile, fd, null, mUserId); 491 } 492 PrintStream out = mWaitOption ? System.out : System.err; 493 boolean launched = false; 494 switch (res) { 495 case ActivityManager.START_SUCCESS: 496 launched = true; 497 break; 498 case ActivityManager.START_SWITCHES_CANCELED: 499 launched = true; 500 out.println( 501 "Warning: Activity not started because the " 502 + " current activity is being kept for the user."); 503 break; 504 case ActivityManager.START_DELIVERED_TO_TOP: 505 launched = true; 506 out.println( 507 "Warning: Activity not started, intent has " 508 + "been delivered to currently running " 509 + "top-most instance."); 510 break; 511 case ActivityManager.START_RETURN_INTENT_TO_CALLER: 512 launched = true; 513 out.println( 514 "Warning: Activity not started because intent " 515 + "should be handled by the caller"); 516 break; 517 case ActivityManager.START_TASK_TO_FRONT: 518 launched = true; 519 out.println( 520 "Warning: Activity not started, its current " 521 + "task has been brought to the front"); 522 break; 523 case ActivityManager.START_INTENT_NOT_RESOLVED: 524 out.println( 525 "Error: Activity not started, unable to " 526 + "resolve " + intent.toString()); 527 break; 528 case ActivityManager.START_CLASS_NOT_FOUND: 529 out.println(NO_CLASS_ERROR_CODE); 530 out.println("Error: Activity class " + 531 intent.getComponent().toShortString() 532 + " does not exist."); 533 break; 534 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: 535 out.println( 536 "Error: Activity not started, you requested to " 537 + "both forward and receive its result"); 538 break; 539 case ActivityManager.START_PERMISSION_DENIED: 540 out.println( 541 "Error: Activity not started, you do not " 542 + "have permission to access it."); 543 break; 544 default: 545 out.println( 546 "Error: Activity not started, unknown error code " + res); 547 break; 548 } 549 if (mWaitOption && launched) { 550 if (result == null) { 551 result = new IActivityManager.WaitResult(); 552 result.who = intent.getComponent(); 553 } 554 System.out.println("Status: " + (result.timeout ? "timeout" : "ok")); 555 if (result.who != null) { 556 System.out.println("Activity: " + result.who.flattenToShortString()); 557 } 558 if (result.thisTime >= 0) { 559 System.out.println("ThisTime: " + result.thisTime); 560 } 561 if (result.totalTime >= 0) { 562 System.out.println("TotalTime: " + result.totalTime); 563 } 564 System.out.println("Complete"); 565 } 566 mRepeat--; 567 if (mRepeat > 1) { 568 mAm.unhandledBack(); 569 } 570 } while (mRepeat > 1); 571 } 572 573 private void runForceStop() throws Exception { 574 int userId = UserHandle.USER_ALL; 575 576 String opt; 577 while ((opt=nextOption()) != null) { 578 if (opt.equals("--user")) { 579 userId = parseUserArg(nextArgRequired()); 580 } else { 581 System.err.println("Error: Unknown option: " + opt); 582 return; 583 } 584 } 585 mAm.forceStopPackage(nextArgRequired(), userId); 586 } 587 588 private void runKill() throws Exception { 589 int userId = UserHandle.USER_ALL; 590 591 String opt; 592 while ((opt=nextOption()) != null) { 593 if (opt.equals("--user")) { 594 userId = parseUserArg(nextArgRequired()); 595 } else { 596 System.err.println("Error: Unknown option: " + opt); 597 return; 598 } 599 } 600 mAm.killBackgroundProcesses(nextArgRequired(), userId); 601 } 602 603 private void runKillAll() throws Exception { 604 mAm.killAllBackgroundProcesses(); 605 } 606 607 private void sendBroadcast() throws Exception { 608 Intent intent = makeIntent(UserHandle.USER_ALL); 609 IntentReceiver receiver = new IntentReceiver(); 610 System.out.println("Broadcasting: " + intent); 611 mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, null, 612 android.app.AppOpsManager.OP_NONE, true, false, mUserId); 613 receiver.waitForFinish(); 614 } 615 616 private void runInstrument() throws Exception { 617 String profileFile = null; 618 boolean wait = false; 619 boolean rawMode = false; 620 boolean no_window_animation = false; 621 int userId = UserHandle.USER_CURRENT; 622 Bundle args = new Bundle(); 623 String argKey = null, argValue = null; 624 IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window")); 625 626 String opt; 627 while ((opt=nextOption()) != null) { 628 if (opt.equals("-p")) { 629 profileFile = nextArgRequired(); 630 } else if (opt.equals("-w")) { 631 wait = true; 632 } else if (opt.equals("-r")) { 633 rawMode = true; 634 } else if (opt.equals("-e")) { 635 argKey = nextArgRequired(); 636 argValue = nextArgRequired(); 637 args.putString(argKey, argValue); 638 } else if (opt.equals("--no_window_animation") 639 || opt.equals("--no-window-animation")) { 640 no_window_animation = true; 641 } else if (opt.equals("--user")) { 642 userId = parseUserArg(nextArgRequired()); 643 } else { 644 System.err.println("Error: Unknown option: " + opt); 645 return; 646 } 647 } 648 649 if (userId == UserHandle.USER_ALL) { 650 System.err.println("Error: Can't start instrumentation with user 'all'"); 651 return; 652 } 653 654 String cnArg = nextArgRequired(); 655 ComponentName cn = ComponentName.unflattenFromString(cnArg); 656 if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg); 657 658 InstrumentationWatcher watcher = null; 659 UiAutomationConnection connection = null; 660 if (wait) { 661 watcher = new InstrumentationWatcher(); 662 watcher.setRawOutput(rawMode); 663 connection = new UiAutomationConnection(); 664 } 665 666 float[] oldAnims = null; 667 if (no_window_animation) { 668 oldAnims = wm.getAnimationScales(); 669 wm.setAnimationScale(0, 0.0f); 670 wm.setAnimationScale(1, 0.0f); 671 } 672 673 if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId)) { 674 throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString()); 675 } 676 677 if (watcher != null) { 678 if (!watcher.waitForFinish()) { 679 System.out.println("INSTRUMENTATION_ABORTED: System has crashed."); 680 } 681 } 682 683 if (oldAnims != null) { 684 wm.setAnimationScales(oldAnims); 685 } 686 } 687 688 static void removeWallOption() { 689 String props = SystemProperties.get("dalvik.vm.extra-opts"); 690 if (props != null && props.contains("-Xprofile:wallclock")) { 691 props = props.replace("-Xprofile:wallclock", ""); 692 props = props.trim(); 693 SystemProperties.set("dalvik.vm.extra-opts", props); 694 } 695 } 696 697 private void runProfile() throws Exception { 698 String profileFile = null; 699 boolean start = false; 700 boolean wall = false; 701 int userId = UserHandle.USER_CURRENT; 702 int profileType = 0; 703 704 String process = null; 705 706 String cmd = nextArgRequired(); 707 708 if ("start".equals(cmd)) { 709 start = true; 710 String opt; 711 while ((opt=nextOption()) != null) { 712 if (opt.equals("--user")) { 713 userId = parseUserArg(nextArgRequired()); 714 } else if (opt.equals("--wall")) { 715 wall = true; 716 } else { 717 System.err.println("Error: Unknown option: " + opt); 718 return; 719 } 720 } 721 process = nextArgRequired(); 722 } else if ("stop".equals(cmd)) { 723 String opt; 724 while ((opt=nextOption()) != null) { 725 if (opt.equals("--user")) { 726 userId = parseUserArg(nextArgRequired()); 727 } else { 728 System.err.println("Error: Unknown option: " + opt); 729 return; 730 } 731 } 732 process = nextArg(); 733 } else { 734 // Compatibility with old syntax: process is specified first. 735 process = cmd; 736 cmd = nextArgRequired(); 737 if ("start".equals(cmd)) { 738 start = true; 739 } else if (!"stop".equals(cmd)) { 740 throw new IllegalArgumentException("Profile command " + process + " not valid"); 741 } 742 } 743 744 if (userId == UserHandle.USER_ALL) { 745 System.err.println("Error: Can't profile with user 'all'"); 746 return; 747 } 748 749 ParcelFileDescriptor fd = null; 750 751 if (start) { 752 profileFile = nextArgRequired(); 753 try { 754 fd = ParcelFileDescriptor.open( 755 new File(profileFile), 756 ParcelFileDescriptor.MODE_CREATE | 757 ParcelFileDescriptor.MODE_TRUNCATE | 758 ParcelFileDescriptor.MODE_READ_WRITE); 759 } catch (FileNotFoundException e) { 760 System.err.println("Error: Unable to open file: " + profileFile); 761 return; 762 } 763 } 764 765 try { 766 if (wall) { 767 // XXX doesn't work -- this needs to be set before booting. 768 String props = SystemProperties.get("dalvik.vm.extra-opts"); 769 if (props == null || !props.contains("-Xprofile:wallclock")) { 770 props = props + " -Xprofile:wallclock"; 771 //SystemProperties.set("dalvik.vm.extra-opts", props); 772 } 773 } else if (start) { 774 //removeWallOption(); 775 } 776 if (!mAm.profileControl(process, userId, start, profileFile, fd, profileType)) { 777 wall = false; 778 throw new AndroidException("PROFILE FAILED on process " + process); 779 } 780 } finally { 781 if (!wall) { 782 //removeWallOption(); 783 } 784 } 785 } 786 787 private void runDumpHeap() throws Exception { 788 boolean managed = true; 789 int userId = UserHandle.USER_CURRENT; 790 791 String opt; 792 while ((opt=nextOption()) != null) { 793 if (opt.equals("--user")) { 794 userId = parseUserArg(nextArgRequired()); 795 if (userId == UserHandle.USER_ALL) { 796 System.err.println("Error: Can't dump heap with user 'all'"); 797 return; 798 } 799 } else if (opt.equals("-n")) { 800 managed = false; 801 } else { 802 System.err.println("Error: Unknown option: " + opt); 803 return; 804 } 805 } 806 String process = nextArgRequired(); 807 String heapFile = nextArgRequired(); 808 ParcelFileDescriptor fd = null; 809 810 try { 811 File file = new File(heapFile); 812 file.delete(); 813 fd = ParcelFileDescriptor.open(file, 814 ParcelFileDescriptor.MODE_CREATE | 815 ParcelFileDescriptor.MODE_TRUNCATE | 816 ParcelFileDescriptor.MODE_READ_WRITE); 817 } catch (FileNotFoundException e) { 818 System.err.println("Error: Unable to open file: " + heapFile); 819 return; 820 } 821 822 if (!mAm.dumpHeap(process, userId, managed, heapFile, fd)) { 823 throw new AndroidException("HEAP DUMP FAILED on process " + process); 824 } 825 } 826 827 private void runSetDebugApp() throws Exception { 828 boolean wait = false; 829 boolean persistent = false; 830 831 String opt; 832 while ((opt=nextOption()) != null) { 833 if (opt.equals("-w")) { 834 wait = true; 835 } else if (opt.equals("--persistent")) { 836 persistent = true; 837 } else { 838 System.err.println("Error: Unknown option: " + opt); 839 return; 840 } 841 } 842 843 String pkg = nextArgRequired(); 844 mAm.setDebugApp(pkg, wait, persistent); 845 } 846 847 private void runClearDebugApp() throws Exception { 848 mAm.setDebugApp(null, false, true); 849 } 850 851 private void runBugReport() throws Exception { 852 mAm.requestBugReport(); 853 System.out.println("Your lovely bug report is being created; please be patient."); 854 } 855 856 private void runSwitchUser() throws Exception { 857 String user = nextArgRequired(); 858 mAm.switchUser(Integer.parseInt(user)); 859 } 860 861 private void runStopUser() throws Exception { 862 String user = nextArgRequired(); 863 int res = mAm.stopUser(Integer.parseInt(user), null); 864 if (res != ActivityManager.USER_OP_SUCCESS) { 865 String txt = ""; 866 switch (res) { 867 case ActivityManager.USER_OP_IS_CURRENT: 868 txt = " (Can't stop current user)"; 869 break; 870 case ActivityManager.USER_OP_UNKNOWN_USER: 871 txt = " (Unknown user " + user + ")"; 872 break; 873 } 874 System.err.println("Switch failed: " + res + txt); 875 } 876 } 877 878 class MyActivityController extends IActivityController.Stub { 879 final String mGdbPort; 880 881 static final int STATE_NORMAL = 0; 882 static final int STATE_CRASHED = 1; 883 static final int STATE_EARLY_ANR = 2; 884 static final int STATE_ANR = 3; 885 886 int mState; 887 888 static final int RESULT_DEFAULT = 0; 889 890 static final int RESULT_CRASH_DIALOG = 0; 891 static final int RESULT_CRASH_KILL = 1; 892 893 static final int RESULT_EARLY_ANR_CONTINUE = 0; 894 static final int RESULT_EARLY_ANR_KILL = 1; 895 896 static final int RESULT_ANR_DIALOG = 0; 897 static final int RESULT_ANR_KILL = 1; 898 static final int RESULT_ANR_WAIT = 1; 899 900 int mResult; 901 902 Process mGdbProcess; 903 Thread mGdbThread; 904 boolean mGotGdbPrint; 905 906 MyActivityController(String gdbPort) { 907 mGdbPort = gdbPort; 908 } 909 910 @Override 911 public boolean activityResuming(String pkg) throws RemoteException { 912 synchronized (this) { 913 System.out.println("** Activity resuming: " + pkg); 914 } 915 return true; 916 } 917 918 @Override 919 public boolean activityStarting(Intent intent, String pkg) throws RemoteException { 920 synchronized (this) { 921 System.out.println("** Activity starting: " + pkg); 922 } 923 return true; 924 } 925 926 @Override 927 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg, 928 long timeMillis, String stackTrace) throws RemoteException { 929 synchronized (this) { 930 System.out.println("** ERROR: PROCESS CRASHED"); 931 System.out.println("processName: " + processName); 932 System.out.println("processPid: " + pid); 933 System.out.println("shortMsg: " + shortMsg); 934 System.out.println("longMsg: " + longMsg); 935 System.out.println("timeMillis: " + timeMillis); 936 System.out.println("stack:"); 937 System.out.print(stackTrace); 938 System.out.println("#"); 939 int result = waitControllerLocked(pid, STATE_CRASHED); 940 return result == RESULT_CRASH_KILL ? false : true; 941 } 942 } 943 944 @Override 945 public int appEarlyNotResponding(String processName, int pid, String annotation) 946 throws RemoteException { 947 synchronized (this) { 948 System.out.println("** ERROR: EARLY PROCESS NOT RESPONDING"); 949 System.out.println("processName: " + processName); 950 System.out.println("processPid: " + pid); 951 System.out.println("annotation: " + annotation); 952 int result = waitControllerLocked(pid, STATE_EARLY_ANR); 953 if (result == RESULT_EARLY_ANR_KILL) return -1; 954 return 0; 955 } 956 } 957 958 @Override 959 public int appNotResponding(String processName, int pid, String processStats) 960 throws RemoteException { 961 synchronized (this) { 962 System.out.println("** ERROR: PROCESS NOT RESPONDING"); 963 System.out.println("processName: " + processName); 964 System.out.println("processPid: " + pid); 965 System.out.println("processStats:"); 966 System.out.print(processStats); 967 System.out.println("#"); 968 int result = waitControllerLocked(pid, STATE_ANR); 969 if (result == RESULT_ANR_KILL) return -1; 970 if (result == RESULT_ANR_WAIT) return 1; 971 return 0; 972 } 973 } 974 975 void killGdbLocked() { 976 mGotGdbPrint = false; 977 if (mGdbProcess != null) { 978 System.out.println("Stopping gdbserver"); 979 mGdbProcess.destroy(); 980 mGdbProcess = null; 981 } 982 if (mGdbThread != null) { 983 mGdbThread.interrupt(); 984 mGdbThread = null; 985 } 986 } 987 988 int waitControllerLocked(int pid, int state) { 989 if (mGdbPort != null) { 990 killGdbLocked(); 991 992 try { 993 System.out.println("Starting gdbserver on port " + mGdbPort); 994 System.out.println("Do the following:"); 995 System.out.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort); 996 System.out.println(" gdbclient app_process :" + mGdbPort); 997 998 mGdbProcess = Runtime.getRuntime().exec(new String[] { 999 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid) 1000 }); 1001 final InputStreamReader converter = new InputStreamReader( 1002 mGdbProcess.getInputStream()); 1003 mGdbThread = new Thread() { 1004 @Override 1005 public void run() { 1006 BufferedReader in = new BufferedReader(converter); 1007 String line; 1008 int count = 0; 1009 while (true) { 1010 synchronized (MyActivityController.this) { 1011 if (mGdbThread == null) { 1012 return; 1013 } 1014 if (count == 2) { 1015 mGotGdbPrint = true; 1016 MyActivityController.this.notifyAll(); 1017 } 1018 } 1019 try { 1020 line = in.readLine(); 1021 if (line == null) { 1022 return; 1023 } 1024 System.out.println("GDB: " + line); 1025 count++; 1026 } catch (IOException e) { 1027 return; 1028 } 1029 } 1030 } 1031 }; 1032 mGdbThread.start(); 1033 1034 // Stupid waiting for .5s. Doesn't matter if we end early. 1035 try { 1036 this.wait(500); 1037 } catch (InterruptedException e) { 1038 } 1039 1040 } catch (IOException e) { 1041 System.err.println("Failure starting gdbserver: " + e); 1042 killGdbLocked(); 1043 } 1044 } 1045 mState = state; 1046 System.out.println(""); 1047 printMessageForState(); 1048 1049 while (mState != STATE_NORMAL) { 1050 try { 1051 wait(); 1052 } catch (InterruptedException e) { 1053 } 1054 } 1055 1056 killGdbLocked(); 1057 1058 return mResult; 1059 } 1060 1061 void resumeController(int result) { 1062 synchronized (this) { 1063 mState = STATE_NORMAL; 1064 mResult = result; 1065 notifyAll(); 1066 } 1067 } 1068 1069 void printMessageForState() { 1070 switch (mState) { 1071 case STATE_NORMAL: 1072 System.out.println("Monitoring activity manager... available commands:"); 1073 break; 1074 case STATE_CRASHED: 1075 System.out.println("Waiting after crash... available commands:"); 1076 System.out.println("(c)ontinue: show crash dialog"); 1077 System.out.println("(k)ill: immediately kill app"); 1078 break; 1079 case STATE_EARLY_ANR: 1080 System.out.println("Waiting after early ANR... available commands:"); 1081 System.out.println("(c)ontinue: standard ANR processing"); 1082 System.out.println("(k)ill: immediately kill app"); 1083 break; 1084 case STATE_ANR: 1085 System.out.println("Waiting after ANR... available commands:"); 1086 System.out.println("(c)ontinue: show ANR dialog"); 1087 System.out.println("(k)ill: immediately kill app"); 1088 System.out.println("(w)ait: wait some more"); 1089 break; 1090 } 1091 System.out.println("(q)uit: finish monitoring"); 1092 } 1093 1094 void run() throws RemoteException { 1095 try { 1096 printMessageForState(); 1097 1098 mAm.setActivityController(this); 1099 mState = STATE_NORMAL; 1100 1101 InputStreamReader converter = new InputStreamReader(System.in); 1102 BufferedReader in = new BufferedReader(converter); 1103 String line; 1104 1105 while ((line = in.readLine()) != null) { 1106 boolean addNewline = true; 1107 if (line.length() <= 0) { 1108 addNewline = false; 1109 } else if ("q".equals(line) || "quit".equals(line)) { 1110 resumeController(RESULT_DEFAULT); 1111 break; 1112 } else if (mState == STATE_CRASHED) { 1113 if ("c".equals(line) || "continue".equals(line)) { 1114 resumeController(RESULT_CRASH_DIALOG); 1115 } else if ("k".equals(line) || "kill".equals(line)) { 1116 resumeController(RESULT_CRASH_KILL); 1117 } else { 1118 System.out.println("Invalid command: " + line); 1119 } 1120 } else if (mState == STATE_ANR) { 1121 if ("c".equals(line) || "continue".equals(line)) { 1122 resumeController(RESULT_ANR_DIALOG); 1123 } else if ("k".equals(line) || "kill".equals(line)) { 1124 resumeController(RESULT_ANR_KILL); 1125 } else if ("w".equals(line) || "wait".equals(line)) { 1126 resumeController(RESULT_ANR_WAIT); 1127 } else { 1128 System.out.println("Invalid command: " + line); 1129 } 1130 } else if (mState == STATE_EARLY_ANR) { 1131 if ("c".equals(line) || "continue".equals(line)) { 1132 resumeController(RESULT_EARLY_ANR_CONTINUE); 1133 } else if ("k".equals(line) || "kill".equals(line)) { 1134 resumeController(RESULT_EARLY_ANR_KILL); 1135 } else { 1136 System.out.println("Invalid command: " + line); 1137 } 1138 } else { 1139 System.out.println("Invalid command: " + line); 1140 } 1141 1142 synchronized (this) { 1143 if (addNewline) { 1144 System.out.println(""); 1145 } 1146 printMessageForState(); 1147 } 1148 } 1149 1150 } catch (IOException e) { 1151 e.printStackTrace(); 1152 } finally { 1153 mAm.setActivityController(null); 1154 } 1155 } 1156 } 1157 1158 private void runMonitor() throws Exception { 1159 String opt; 1160 String gdbPort = null; 1161 while ((opt=nextOption()) != null) { 1162 if (opt.equals("--gdb")) { 1163 gdbPort = nextArgRequired(); 1164 } else { 1165 System.err.println("Error: Unknown option: " + opt); 1166 return; 1167 } 1168 } 1169 1170 MyActivityController controller = new MyActivityController(gdbPort); 1171 controller.run(); 1172 } 1173 1174 private void runScreenCompat() throws Exception { 1175 String mode = nextArgRequired(); 1176 boolean enabled; 1177 if ("on".equals(mode)) { 1178 enabled = true; 1179 } else if ("off".equals(mode)) { 1180 enabled = false; 1181 } else { 1182 System.err.println("Error: enabled mode must be 'on' or 'off' at " + mode); 1183 return; 1184 } 1185 1186 String packageName = nextArgRequired(); 1187 do { 1188 try { 1189 mAm.setPackageScreenCompatMode(packageName, enabled 1190 ? ActivityManager.COMPAT_MODE_ENABLED 1191 : ActivityManager.COMPAT_MODE_DISABLED); 1192 } catch (RemoteException e) { 1193 } 1194 packageName = nextArg(); 1195 } while (packageName != null); 1196 } 1197 1198 private void runToUri(boolean intentScheme) throws Exception { 1199 Intent intent = makeIntent(UserHandle.USER_CURRENT); 1200 System.out.println(intent.toUri(intentScheme ? Intent.URI_INTENT_SCHEME : 0)); 1201 } 1202 1203 private class IntentReceiver extends IIntentReceiver.Stub { 1204 private boolean mFinished = false; 1205 1206 @Override 1207 public void performReceive(Intent intent, int resultCode, String data, Bundle extras, 1208 boolean ordered, boolean sticky, int sendingUser) throws RemoteException { 1209 String line = "Broadcast completed: result=" + resultCode; 1210 if (data != null) line = line + ", data=\"" + data + "\""; 1211 if (extras != null) line = line + ", extras: " + extras; 1212 System.out.println(line); 1213 synchronized (this) { 1214 mFinished = true; 1215 notifyAll(); 1216 } 1217 } 1218 1219 public synchronized void waitForFinish() { 1220 try { 1221 while (!mFinished) wait(); 1222 } catch (InterruptedException e) { 1223 throw new IllegalStateException(e); 1224 } 1225 } 1226 } 1227 1228 private class InstrumentationWatcher extends IInstrumentationWatcher.Stub { 1229 private boolean mFinished = false; 1230 private boolean mRawMode = false; 1231 1232 /** 1233 * Set or reset "raw mode". In "raw mode", all bundles are dumped. In "pretty mode", 1234 * if a bundle includes Instrumentation.REPORT_KEY_STREAMRESULT, just print that. 1235 * @param rawMode true for raw mode, false for pretty mode. 1236 */ 1237 public void setRawOutput(boolean rawMode) { 1238 mRawMode = rawMode; 1239 } 1240 1241 public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) { 1242 synchronized (this) { 1243 // pretty printer mode? 1244 String pretty = null; 1245 if (!mRawMode && results != null) { 1246 pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT); 1247 } 1248 if (pretty != null) { 1249 System.out.print(pretty); 1250 } else { 1251 if (results != null) { 1252 for (String key : results.keySet()) { 1253 System.out.println( 1254 "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key)); 1255 } 1256 } 1257 System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode); 1258 } 1259 notifyAll(); 1260 } 1261 } 1262 1263 public void instrumentationFinished(ComponentName name, int resultCode, 1264 Bundle results) { 1265 synchronized (this) { 1266 // pretty printer mode? 1267 String pretty = null; 1268 if (!mRawMode && results != null) { 1269 pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT); 1270 } 1271 if (pretty != null) { 1272 System.out.println(pretty); 1273 } else { 1274 if (results != null) { 1275 for (String key : results.keySet()) { 1276 System.out.println( 1277 "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key)); 1278 } 1279 } 1280 System.out.println("INSTRUMENTATION_CODE: " + resultCode); 1281 } 1282 mFinished = true; 1283 notifyAll(); 1284 } 1285 } 1286 1287 public boolean waitForFinish() { 1288 synchronized (this) { 1289 while (!mFinished) { 1290 try { 1291 if (!mAm.asBinder().pingBinder()) { 1292 return false; 1293 } 1294 wait(1000); 1295 } catch (InterruptedException e) { 1296 throw new IllegalStateException(e); 1297 } 1298 } 1299 } 1300 return true; 1301 } 1302 } 1303 1304 private String nextOption() { 1305 if (mCurArgData != null) { 1306 String prev = mArgs[mNextArg - 1]; 1307 throw new IllegalArgumentException("No argument expected after \"" + prev + "\""); 1308 } 1309 if (mNextArg >= mArgs.length) { 1310 return null; 1311 } 1312 String arg = mArgs[mNextArg]; 1313 if (!arg.startsWith("-")) { 1314 return null; 1315 } 1316 mNextArg++; 1317 if (arg.equals("--")) { 1318 return null; 1319 } 1320 if (arg.length() > 1 && arg.charAt(1) != '-') { 1321 if (arg.length() > 2) { 1322 mCurArgData = arg.substring(2); 1323 return arg.substring(0, 2); 1324 } else { 1325 mCurArgData = null; 1326 return arg; 1327 } 1328 } 1329 mCurArgData = null; 1330 return arg; 1331 } 1332 1333 private String nextArg() { 1334 if (mCurArgData != null) { 1335 String arg = mCurArgData; 1336 mCurArgData = null; 1337 return arg; 1338 } else if (mNextArg < mArgs.length) { 1339 return mArgs[mNextArg++]; 1340 } else { 1341 return null; 1342 } 1343 } 1344 1345 private String nextArgRequired() { 1346 String arg = nextArg(); 1347 if (arg == null) { 1348 String prev = mArgs[mNextArg - 1]; 1349 throw new IllegalArgumentException("Argument expected after \"" + prev + "\""); 1350 } 1351 return arg; 1352 } 1353 1354 private static void showUsage() { 1355 System.err.println( 1356 "usage: am [subcommand] [options]\n" + 1357 "usage: am start [-D] [-W] [-P <FILE>] [--start-profiler <FILE>]\n" + 1358 " [--R COUNT] [-S] [--opengl-trace]\n" + 1359 " [--user <USER_ID> | current] <INTENT>\n" + 1360 " am startservice [--user <USER_ID> | current] <INTENT>\n" + 1361 " am force-stop [--user <USER_ID> | all | current] <PACKAGE>\n" + 1362 " am kill [--user <USER_ID> | all | current] <PACKAGE>\n" + 1363 " am kill-all\n" + 1364 " am broadcast [--user <USER_ID> | all | current] <INTENT>\n" + 1365 " am instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]\n" + 1366 " [--user <USER_ID> | current]\n" + 1367 " [--no-window-animation] <COMPONENT>\n" + 1368 " am profile start [--user <USER_ID> current] <PROCESS> <FILE>\n" + 1369 " am profile stop [--user <USER_ID> current] [<PROCESS>]\n" + 1370 " am dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>\n" + 1371 " am set-debug-app [-w] [--persistent] <PACKAGE>\n" + 1372 " am clear-debug-app\n" + 1373 " am monitor [--gdb <port>]\n" + 1374 " am screen-compat [on|off] <PACKAGE>\n" + 1375 " am to-uri [INTENT]\n" + 1376 " am to-intent-uri [INTENT]\n" + 1377 " am switch-user <USER_ID>\n" + 1378 " am stop-user <USER_ID>\n" + 1379 "\n" + 1380 "am start: start an Activity. Options are:\n" + 1381 " -D: enable debugging\n" + 1382 " -W: wait for launch to complete\n" + 1383 " --start-profiler <FILE>: start profiler and send results to <FILE>\n" + 1384 " -P <FILE>: like above, but profiling stops when app goes idle\n" + 1385 " -R: repeat the activity launch <COUNT> times. Prior to each repeat,\n" + 1386 " the top activity will be finished.\n" + 1387 " -S: force stop the target app before starting the activity\n" + 1388 " --opengl-trace: enable tracing of OpenGL functions\n" + 1389 " --user <USER_ID> | current: Specify which user to run as; if not\n" + 1390 " specified then run as the current user.\n" + 1391 "\n" + 1392 "am startservice: start a Service. Options are:\n" + 1393 " --user <USER_ID> | current: Specify which user to run as; if not\n" + 1394 " specified then run as the current user.\n" + 1395 "\n" + 1396 "am force-stop: force stop everything associated with <PACKAGE>.\n" + 1397 " --user <USER_ID> | all | current: Specify user to force stop;\n" + 1398 " all users if not specified.\n" + 1399 "\n" + 1400 "am kill: Kill all processes associated with <PACKAGE>. Only kills.\n" + 1401 " processes that are safe to kill -- that is, will not impact the user\n" + 1402 " experience.\n" + 1403 " --user <USER_ID> | all | current: Specify user whose processes to kill;\n" + 1404 " all users if not specified.\n" + 1405 "\n" + 1406 "am kill-all: Kill all background processes.\n" + 1407 "\n" + 1408 "am broadcast: send a broadcast Intent. Options are:\n" + 1409 " --user <USER_ID> | all | current: Specify which user to send to; if not\n" + 1410 " specified then send to all users.\n" + 1411 "\n" + 1412 "am instrument: start an Instrumentation. Typically this target <COMPONENT>\n" + 1413 " is the form <TEST_PACKAGE>/<RUNNER_CLASS>. Options are:\n" + 1414 " -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with\n" + 1415 " [-e perf true] to generate raw output for performance measurements.\n" + 1416 " -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a\n" + 1417 " common form is [-e <testrunner_flag> <value>[,<value>...]].\n" + 1418 " -p <FILE>: write profiling data to <FILE>\n" + 1419 " -w: wait for instrumentation to finish before returning. Required for\n" + 1420 " test runners.\n" + 1421 " --user <USER_ID> | current: Specify user instrumentation runs in;\n" + 1422 " current user if not specified.\n" + 1423 " --no-window-animation: turn off window animations will running.\n" + 1424 "\n" + 1425 "am profile: start and stop profiler on a process. The given <PROCESS> argument\n" + 1426 " may be either a process name or pid. Options are:\n" + 1427 " --user <USER_ID> | current: When supplying a process name,\n" + 1428 " specify user of process to profile; uses current user if not specified.\n" + 1429 "\n" + 1430 "am dumpheap: dump the heap of a process. The given <PROCESS> argument may\n" + 1431 " be either a process name or pid. Options are:\n" + 1432 " -n: dump native heap instead of managed heap\n" + 1433 " --user <USER_ID> | current: When supplying a process name,\n" + 1434 " specify user of process to dump; uses current user if not specified.\n" + 1435 "\n" + 1436 "am set-debug-app: set application <PACKAGE> to debug. Options are:\n" + 1437 " -w: wait for debugger when application starts\n" + 1438 " --persistent: retain this value\n" + 1439 "\n" + 1440 "am clear-debug-app: clear the previously set-debug-app.\n" + 1441 "\n" + 1442 "am bug-report: request bug report generation; will launch UI\n" + 1443 " when done to select where it should be delivered.\n" + 1444 "\n" + 1445 "am monitor: start monitoring for crashes or ANRs.\n" + 1446 " --gdb: start gdbserv on the given port at crash/ANR\n" + 1447 "\n" + 1448 "am screen-compat: control screen compatibility mode of <PACKAGE>.\n" + 1449 "\n" + 1450 "am to-uri: print the given Intent specification as a URI.\n" + 1451 "\n" + 1452 "am to-intent-uri: print the given Intent specification as an intent: URI.\n" + 1453 "\n" + 1454 "am switch-user: switch to put USER_ID in the foreground, starting\n" + 1455 " execution of that user if it is currently stopped.\n" + 1456 "\n" + 1457 "am stop-user: stop execution of USER_ID, not allowing it to run any\n" + 1458 " code until a later explicit switch to it.\n" + 1459 "\n" + 1460 "<INTENT> specifications include these flags and arguments:\n" + 1461 " [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" + 1462 " [-c <CATEGORY> [-c <CATEGORY>] ...]\n" + 1463 " [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]\n" + 1464 " [--esn <EXTRA_KEY> ...]\n" + 1465 " [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]\n" + 1466 " [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]\n" + 1467 " [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]\n" + 1468 " [--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE> ...]\n" + 1469 " [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" + 1470 " [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]\n" + 1471 " [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" + 1472 " [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" + 1473 " [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" + 1474 " [-n <COMPONENT>] [-f <FLAGS>]\n" + 1475 " [--grant-read-uri-permission] [--grant-write-uri-permission]\n" + 1476 " [--debug-log-resolution] [--exclude-stopped-packages]\n" + 1477 " [--include-stopped-packages]\n" + 1478 " [--activity-brought-to-front] [--activity-clear-top]\n" + 1479 " [--activity-clear-when-task-reset] [--activity-exclude-from-recents]\n" + 1480 " [--activity-launched-from-history] [--activity-multiple-task]\n" + 1481 " [--activity-no-animation] [--activity-no-history]\n" + 1482 " [--activity-no-user-action] [--activity-previous-is-top]\n" + 1483 " [--activity-reorder-to-front] [--activity-reset-task-if-needed]\n" + 1484 " [--activity-single-top] [--activity-clear-task]\n" + 1485 " [--activity-task-on-home]\n" + 1486 " [--receiver-registered-only] [--receiver-replace-pending]\n" + 1487 " [--selector]\n" + 1488 " [<URI> | <PACKAGE> | <COMPONENT>]\n" 1489 ); 1490 } 1491} 1492