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