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