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