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