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