PackageManagerShellCommand.java revision bdd94d9979e28c39539e25fbb98621df3cbe86f2
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
20import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
21import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
22import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
23import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
24
25import android.accounts.IAccountManager;
26import android.app.ActivityManager;
27import android.app.ActivityManagerInternal;
28import android.app.Application;
29import android.content.ComponentName;
30import android.content.Context;
31import android.content.IIntentReceiver;
32import android.content.IIntentSender;
33import android.content.Intent;
34import android.content.IntentSender;
35import android.content.pm.ApplicationInfo;
36import android.content.pm.FeatureInfo;
37import android.content.pm.IPackageDataObserver;
38import android.content.pm.IPackageInstaller;
39import android.content.pm.IPackageManager;
40import android.content.pm.InstrumentationInfo;
41import android.content.pm.PackageInfo;
42import android.content.pm.PackageInstaller;
43import android.content.pm.PackageInstaller.SessionParams;
44import android.content.pm.PackageItemInfo;
45import android.content.pm.PackageManager;
46import android.content.pm.PackageManager.NameNotFoundException;
47import android.content.pm.PackageParser;
48import android.content.pm.PackageParser.ApkLite;
49import android.content.pm.PackageParser.PackageLite;
50import android.content.pm.PackageParser.PackageParserException;
51import android.content.pm.ParceledListSlice;
52import android.content.pm.PermissionGroupInfo;
53import android.content.pm.PermissionInfo;
54import android.content.pm.ResolveInfo;
55import android.content.pm.UserInfo;
56import android.content.pm.VersionedPackage;
57import android.content.pm.dex.ArtManager;
58import android.content.pm.dex.DexMetadataHelper;
59import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
60import android.content.res.AssetManager;
61import android.content.res.Resources;
62import android.net.Uri;
63import android.os.Binder;
64import android.os.Build;
65import android.os.Bundle;
66import android.os.IBinder;
67import android.os.IUserManager;
68import android.os.ParcelFileDescriptor;
69import android.os.ParcelFileDescriptor.AutoCloseInputStream;
70import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
71import android.os.PersistableBundle;
72import android.os.Process;
73import android.os.RemoteException;
74import android.os.ServiceManager;
75import android.os.ShellCommand;
76import android.os.SystemClock;
77import android.os.SystemProperties;
78import android.os.UserHandle;
79import android.os.UserManager;
80import android.os.storage.StorageManager;
81import android.system.ErrnoException;
82import android.system.Os;
83import android.text.TextUtils;
84import android.text.format.DateUtils;
85import android.util.ArraySet;
86import android.util.PrintWriterPrinter;
87import com.android.internal.content.PackageHelper;
88import com.android.internal.util.ArrayUtils;
89import com.android.server.LocalServices;
90import com.android.server.SystemConfig;
91import dalvik.system.DexFile;
92import java.io.File;
93import java.io.FileOutputStream;
94import java.io.IOException;
95import java.io.InputStream;
96import java.io.OutputStream;
97import java.io.PrintWriter;
98import java.net.URISyntaxException;
99import java.nio.file.Files;
100import java.nio.file.Paths;
101import java.nio.file.StandardCopyOption;
102import java.nio.file.attribute.FileAttribute;
103import java.util.ArrayList;
104import java.util.Collections;
105import java.util.Comparator;
106import java.util.LinkedList;
107import java.util.List;
108import java.util.Map;
109import java.util.Objects;
110import java.util.WeakHashMap;
111import java.util.concurrent.CountDownLatch;
112import java.util.concurrent.SynchronousQueue;
113import java.util.concurrent.TimeUnit;
114import libcore.io.IoUtils;
115import libcore.io.Streams;
116
117class PackageManagerShellCommand extends ShellCommand {
118    /** Path for streaming APK content */
119    private static final String STDIN_PATH = "-";
120    /** Path where ART profiles snapshots are dumped for the shell user */
121    private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
122
123    final IPackageManager mInterface;
124    final private WeakHashMap<String, Resources> mResourceCache =
125            new WeakHashMap<String, Resources>();
126    int mTargetUser;
127    boolean mBrief;
128    boolean mComponents;
129
130    PackageManagerShellCommand(PackageManagerService service) {
131        mInterface = service;
132    }
133
134    @Override
135    public int onCommand(String cmd) {
136        if (cmd == null) {
137            return handleDefaultCommands(cmd);
138        }
139
140        final PrintWriter pw = getOutPrintWriter();
141        try {
142            switch(cmd) {
143                case "path":
144                    return runPath();
145                case "dump":
146                    return runDump();
147                case "list":
148                    return runList();
149                case "resolve-activity":
150                    return runResolveActivity();
151                case "query-activities":
152                    return runQueryIntentActivities();
153                case "query-services":
154                    return runQueryIntentServices();
155                case "query-receivers":
156                    return runQueryIntentReceivers();
157                case "install":
158                    return runInstall();
159                case "install-abandon":
160                case "install-destroy":
161                    return runInstallAbandon();
162                case "install-commit":
163                    return runInstallCommit();
164                case "install-create":
165                    return runInstallCreate();
166                case "install-remove":
167                    return runInstallRemove();
168                case "install-write":
169                    return runInstallWrite();
170                case "install-existing":
171                    return runInstallExisting();
172                case "set-install-location":
173                    return runSetInstallLocation();
174                case "get-install-location":
175                    return runGetInstallLocation();
176                case "move-package":
177                    return runMovePackage();
178                case "move-primary-storage":
179                    return runMovePrimaryStorage();
180                case "compile":
181                    return runCompile();
182                case "reconcile-secondary-dex-files":
183                    return runreconcileSecondaryDexFiles();
184                case "force-dex-opt":
185                    return runForceDexOpt();
186                case "bg-dexopt-job":
187                    return runDexoptJob();
188                case "dump-profiles":
189                    return runDumpProfiles();
190                case "snapshot-profile":
191                    return runSnapshotProfile();
192                case "uninstall":
193                    return runUninstall();
194                case "clear":
195                    return runClear();
196                case "enable":
197                    return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
198                case "disable":
199                    return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
200                case "disable-user":
201                    return runSetEnabledSetting(
202                            PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
203                case "disable-until-used":
204                    return runSetEnabledSetting(
205                            PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
206                case "default-state":
207                    return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
208                case "hide":
209                    return runSetHiddenSetting(true);
210                case "unhide":
211                    return runSetHiddenSetting(false);
212                case "suspend":
213                    return runSuspend(true);
214                case "unsuspend":
215                    return runSuspend(false);
216                case "grant":
217                    return runGrantRevokePermission(true);
218                case "revoke":
219                    return runGrantRevokePermission(false);
220                case "reset-permissions":
221                    return runResetPermissions();
222                case "set-permission-enforced":
223                    return runSetPermissionEnforced();
224                case "get-privapp-permissions":
225                    return runGetPrivappPermissions();
226                case "get-privapp-deny-permissions":
227                    return runGetPrivappDenyPermissions();
228                case "get-oem-permissions":
229                    return runGetOemPermissions();
230                case "set-app-link":
231                    return runSetAppLink();
232                case "get-app-link":
233                    return runGetAppLink();
234                case "trim-caches":
235                    return runTrimCaches();
236                case "create-user":
237                    return runCreateUser();
238                case "remove-user":
239                    return runRemoveUser();
240                case "set-user-restriction":
241                    return runSetUserRestriction();
242                case "get-max-users":
243                    return runGetMaxUsers();
244                case "get-max-running-users":
245                    return runGetMaxRunningUsers();
246                case "set-home-activity":
247                    return runSetHomeActivity();
248                case "set-installer":
249                    return runSetInstaller();
250                case "get-instantapp-resolver":
251                    return runGetInstantAppResolver();
252                case "has-feature":
253                    return runHasFeature();
254                case "set-harmful-app-warning":
255                    return runSetHarmfulAppWarning();
256                case "get-harmful-app-warning":
257                    return runGetHarmfulAppWarning();
258                case "uninstall-system-updates":
259                    return uninstallSystemUpdates();
260                default: {
261                    String nextArg = getNextArg();
262                    if (nextArg == null) {
263                        if (cmd.equalsIgnoreCase("-l")) {
264                            return runListPackages(false);
265                        } else if (cmd.equalsIgnoreCase("-lf")) {
266                            return runListPackages(true);
267                        }
268                    } else if (getNextArg() == null) {
269                        if (cmd.equalsIgnoreCase("-p")) {
270                            return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
271                        }
272                    }
273                    return handleDefaultCommands(cmd);
274                }
275            }
276        } catch (RemoteException e) {
277            pw.println("Remote exception: " + e);
278        }
279        return -1;
280    }
281
282    private int uninstallSystemUpdates() {
283        final PrintWriter pw = getOutPrintWriter();
284        List<String> failedUninstalls = new LinkedList<>();
285        try {
286            final ParceledListSlice<ApplicationInfo> packages =
287                    mInterface.getInstalledApplications(
288                            PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
289            final IPackageInstaller installer = mInterface.getPackageInstaller();
290            List<ApplicationInfo> list = packages.getList();
291            for (ApplicationInfo info : list) {
292                if (info.isUpdatedSystemApp()) {
293                    pw.println("Uninstalling updates to " + info.packageName + "...");
294                    final LocalIntentReceiver receiver = new LocalIntentReceiver();
295                    installer.uninstall(new VersionedPackage(info.packageName,
296                                    info.versionCode), null /*callerPackageName*/, 0 /* flags */,
297                            receiver.getIntentSender(), 0);
298
299                    final Intent result = receiver.getResult();
300                    final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
301                            PackageInstaller.STATUS_FAILURE);
302                    if (status != PackageInstaller.STATUS_SUCCESS) {
303                        failedUninstalls.add(info.packageName);
304                    }
305                }
306            }
307        } catch (RemoteException e) {
308            pw.println("Failure ["
309                    + e.getClass().getName() + " - "
310                    + e.getMessage() + "]");
311            return 0;
312        }
313        if (!failedUninstalls.isEmpty()) {
314            pw.println("Failure [Couldn't uninstall packages: "
315                    + TextUtils.join(", ", failedUninstalls)
316                    + "]");
317            return 0;
318        }
319        pw.println("Success");
320        return 1;
321    }
322
323    private void setParamsSize(InstallParams params, String inPath) {
324        if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
325            final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
326            if (fd == null) {
327                getErrPrintWriter().println("Error: Can't open file: " + inPath);
328                throw new IllegalArgumentException("Error: Can't open file: " + inPath);
329            }
330            try {
331                ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
332                PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
333                        null, null);
334                params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
335                        pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
336            } catch (PackageParserException | IOException e) {
337                getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
338                throw new IllegalArgumentException(
339                        "Error: Failed to parse APK file: " + inPath, e);
340            } finally {
341                try {
342                    fd.close();
343                } catch (IOException e) {
344                }
345            }
346        }
347    }
348    /**
349     * Displays the package file for a package.
350     * @param pckg
351     */
352    private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
353        PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId);
354        if (info != null && info.applicationInfo != null) {
355            final PrintWriter pw = getOutPrintWriter();
356            pw.print("package:");
357            pw.println(info.applicationInfo.sourceDir);
358            if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
359                for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
360                    pw.print("package:");
361                    pw.println(splitSourceDir);
362                }
363            }
364            return 0;
365        }
366        return 1;
367    }
368
369    private int runPath() throws RemoteException {
370        int userId = UserHandle.USER_SYSTEM;
371        String option = getNextOption();
372        if (option != null && option.equals("--user")) {
373            userId = UserHandle.parseUserArg(getNextArgRequired());
374        }
375
376        String pkg = getNextArgRequired();
377        if (pkg == null) {
378            getErrPrintWriter().println("Error: no package specified");
379            return 1;
380        }
381        return displayPackageFilePath(pkg, userId);
382    }
383
384    private int runList() throws RemoteException {
385        final PrintWriter pw = getOutPrintWriter();
386        final String type = getNextArg();
387        if (type == null) {
388            pw.println("Error: didn't specify type of data to list");
389            return -1;
390        }
391        switch(type) {
392            case "features":
393                return runListFeatures();
394            case "instrumentation":
395                return runListInstrumentation();
396            case "libraries":
397                return runListLibraries();
398            case "package":
399            case "packages":
400                return runListPackages(false /*showSourceDir*/);
401            case "permission-groups":
402                return runListPermissionGroups();
403            case "permissions":
404                return runListPermissions();
405            case "users":
406                ServiceManager.getService("user").shellCommand(
407                        getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
408                        new String[] { "list" }, getShellCallback(), adoptResultReceiver());
409                return 0;
410        }
411        pw.println("Error: unknown list type '" + type + "'");
412        return -1;
413    }
414
415    private int runListFeatures() throws RemoteException {
416        final PrintWriter pw = getOutPrintWriter();
417        final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
418
419        // sort by name
420        Collections.sort(list, new Comparator<FeatureInfo>() {
421            public int compare(FeatureInfo o1, FeatureInfo o2) {
422                if (o1.name == o2.name) return 0;
423                if (o1.name == null) return -1;
424                if (o2.name == null) return 1;
425                return o1.name.compareTo(o2.name);
426            }
427        });
428
429        final int count = (list != null) ? list.size() : 0;
430        for (int p = 0; p < count; p++) {
431            FeatureInfo fi = list.get(p);
432            pw.print("feature:");
433            if (fi.name != null) {
434                pw.print(fi.name);
435                if (fi.version > 0) {
436                    pw.print("=");
437                    pw.print(fi.version);
438                }
439                pw.println();
440            } else {
441                pw.println("reqGlEsVersion=0x"
442                        + Integer.toHexString(fi.reqGlEsVersion));
443            }
444        }
445        return 0;
446    }
447
448    private int runListInstrumentation() throws RemoteException {
449        final PrintWriter pw = getOutPrintWriter();
450        boolean showSourceDir = false;
451        String targetPackage = null;
452
453        try {
454            String opt;
455            while ((opt = getNextArg()) != null) {
456                switch (opt) {
457                    case "-f":
458                        showSourceDir = true;
459                        break;
460                    default:
461                        if (opt.charAt(0) != '-') {
462                            targetPackage = opt;
463                        } else {
464                            pw.println("Error: Unknown option: " + opt);
465                            return -1;
466                        }
467                        break;
468                }
469            }
470        } catch (RuntimeException ex) {
471            pw.println("Error: " + ex.toString());
472            return -1;
473        }
474
475        final List<InstrumentationInfo> list =
476                mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
477
478        // sort by target package
479        Collections.sort(list, new Comparator<InstrumentationInfo>() {
480            public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
481                return o1.targetPackage.compareTo(o2.targetPackage);
482            }
483        });
484
485        final int count = (list != null) ? list.size() : 0;
486        for (int p = 0; p < count; p++) {
487            final InstrumentationInfo ii = list.get(p);
488            pw.print("instrumentation:");
489            if (showSourceDir) {
490                pw.print(ii.sourceDir);
491                pw.print("=");
492            }
493            final ComponentName cn = new ComponentName(ii.packageName, ii.name);
494            pw.print(cn.flattenToShortString());
495            pw.print(" (target=");
496            pw.print(ii.targetPackage);
497            pw.println(")");
498        }
499        return 0;
500    }
501
502    private int runListLibraries() throws RemoteException {
503        final PrintWriter pw = getOutPrintWriter();
504        final List<String> list = new ArrayList<String>();
505        final String[] rawList = mInterface.getSystemSharedLibraryNames();
506        for (int i = 0; i < rawList.length; i++) {
507            list.add(rawList[i]);
508        }
509
510        // sort by name
511        Collections.sort(list, new Comparator<String>() {
512            public int compare(String o1, String o2) {
513                if (o1 == o2) return 0;
514                if (o1 == null) return -1;
515                if (o2 == null) return 1;
516                return o1.compareTo(o2);
517            }
518        });
519
520        final int count = (list != null) ? list.size() : 0;
521        for (int p = 0; p < count; p++) {
522            String lib = list.get(p);
523            pw.print("library:");
524            pw.println(lib);
525        }
526        return 0;
527    }
528
529    private int runListPackages(boolean showSourceDir) throws RemoteException {
530        final PrintWriter pw = getOutPrintWriter();
531        int getFlags = 0;
532        boolean listDisabled = false, listEnabled = false;
533        boolean listSystem = false, listThirdParty = false;
534        boolean listInstaller = false;
535        boolean showUid = false;
536        boolean showVersionCode = false;
537        int uid = -1;
538        int userId = UserHandle.USER_SYSTEM;
539        try {
540            String opt;
541            while ((opt = getNextOption()) != null) {
542                switch (opt) {
543                    case "-d":
544                        listDisabled = true;
545                        break;
546                    case "-e":
547                        listEnabled = true;
548                        break;
549                    case "-f":
550                        showSourceDir = true;
551                        break;
552                    case "-i":
553                        listInstaller = true;
554                        break;
555                    case "-l":
556                        // old compat
557                        break;
558                    case "-s":
559                        listSystem = true;
560                        break;
561                    case "-U":
562                        showUid = true;
563                        break;
564                    case "-u":
565                        getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
566                        break;
567                    case "-3":
568                        listThirdParty = true;
569                        break;
570                    case "--show-versioncode":
571                        showVersionCode = true;
572                        break;
573                    case "--user":
574                        userId = UserHandle.parseUserArg(getNextArgRequired());
575                        break;
576                    case "--uid":
577                        showUid = true;
578                        uid = Integer.parseInt(getNextArgRequired());
579                        break;
580                    default:
581                        pw.println("Error: Unknown option: " + opt);
582                        return -1;
583                }
584            }
585        } catch (RuntimeException ex) {
586            pw.println("Error: " + ex.toString());
587            return -1;
588        }
589
590        final String filter = getNextArg();
591
592        @SuppressWarnings("unchecked")
593        final ParceledListSlice<PackageInfo> slice =
594                mInterface.getInstalledPackages(getFlags, userId);
595        final List<PackageInfo> packages = slice.getList();
596
597        final int count = packages.size();
598        for (int p = 0; p < count; p++) {
599            final PackageInfo info = packages.get(p);
600            if (filter != null && !info.packageName.contains(filter)) {
601                continue;
602            }
603            if (uid != -1 && info.applicationInfo.uid != uid) {
604                continue;
605            }
606            final boolean isSystem =
607                    (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
608            if ((!listDisabled || !info.applicationInfo.enabled) &&
609                    (!listEnabled || info.applicationInfo.enabled) &&
610                    (!listSystem || isSystem) &&
611                    (!listThirdParty || !isSystem)) {
612                pw.print("package:");
613                if (showSourceDir) {
614                    pw.print(info.applicationInfo.sourceDir);
615                    pw.print("=");
616                }
617                pw.print(info.packageName);
618                if (showVersionCode) {
619                    pw.print(" versionCode:");
620                    pw.print(info.applicationInfo.versionCode);
621                }
622                if (listInstaller) {
623                    pw.print("  installer=");
624                    pw.print(mInterface.getInstallerPackageName(info.packageName));
625                }
626                if (showUid) {
627                    pw.print(" uid:");
628                    pw.print(info.applicationInfo.uid);
629                }
630                pw.println();
631            }
632        }
633        return 0;
634    }
635
636    private int runListPermissionGroups() throws RemoteException {
637        final PrintWriter pw = getOutPrintWriter();
638        final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
639
640        final int count = pgs.size();
641        for (int p = 0; p < count ; p++) {
642            final PermissionGroupInfo pgi = pgs.get(p);
643            pw.print("permission group:");
644            pw.println(pgi.name);
645        }
646        return 0;
647    }
648
649    private int runListPermissions() throws RemoteException {
650        final PrintWriter pw = getOutPrintWriter();
651        boolean labels = false;
652        boolean groups = false;
653        boolean userOnly = false;
654        boolean summary = false;
655        boolean dangerousOnly = false;
656        String opt;
657        while ((opt = getNextOption()) != null) {
658            switch (opt) {
659                case "-d":
660                    dangerousOnly = true;
661                    break;
662                case "-f":
663                    labels = true;
664                    break;
665                case "-g":
666                    groups = true;
667                    break;
668                case "-s":
669                    groups = true;
670                    labels = true;
671                    summary = true;
672                    break;
673                case "-u":
674                    userOnly = true;
675                    break;
676                default:
677                    pw.println("Error: Unknown option: " + opt);
678                    return 1;
679            }
680        }
681
682        final ArrayList<String> groupList = new ArrayList<String>();
683        if (groups) {
684            final List<PermissionGroupInfo> infos =
685                    mInterface.getAllPermissionGroups(0 /*flags*/).getList();
686            final int count = infos.size();
687            for (int i = 0; i < count; i++) {
688                groupList.add(infos.get(i).name);
689            }
690            groupList.add(null);
691        } else {
692            final String grp = getNextArg();
693            groupList.add(grp);
694        }
695
696        if (dangerousOnly) {
697            pw.println("Dangerous Permissions:");
698            pw.println("");
699            doListPermissions(groupList, groups, labels, summary,
700                    PermissionInfo.PROTECTION_DANGEROUS,
701                    PermissionInfo.PROTECTION_DANGEROUS);
702            if (userOnly) {
703                pw.println("Normal Permissions:");
704                pw.println("");
705                doListPermissions(groupList, groups, labels, summary,
706                        PermissionInfo.PROTECTION_NORMAL,
707                        PermissionInfo.PROTECTION_NORMAL);
708            }
709        } else if (userOnly) {
710            pw.println("Dangerous and Normal Permissions:");
711            pw.println("");
712            doListPermissions(groupList, groups, labels, summary,
713                    PermissionInfo.PROTECTION_NORMAL,
714                    PermissionInfo.PROTECTION_DANGEROUS);
715        } else {
716            pw.println("All Permissions:");
717            pw.println("");
718            doListPermissions(groupList, groups, labels, summary,
719                    -10000, 10000);
720        }
721        return 0;
722    }
723
724    private Intent parseIntentAndUser() throws URISyntaxException {
725        mTargetUser = UserHandle.USER_CURRENT;
726        mBrief = false;
727        mComponents = false;
728        Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
729            @Override
730            public boolean handleOption(String opt, ShellCommand cmd) {
731                if ("--user".equals(opt)) {
732                    mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
733                    return true;
734                } else if ("--brief".equals(opt)) {
735                    mBrief = true;
736                    return true;
737                } else if ("--components".equals(opt)) {
738                    mComponents = true;
739                    return true;
740                }
741                return false;
742            }
743        });
744        mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
745                Binder.getCallingUid(), mTargetUser, false, false, null, null);
746        return intent;
747    }
748
749    private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
750            boolean brief, boolean components) {
751        if (brief || components) {
752            final ComponentName comp;
753            if (ri.activityInfo != null) {
754                comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
755            } else if (ri.serviceInfo != null) {
756                comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
757            } else if (ri.providerInfo != null) {
758                comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
759            } else {
760                comp = null;
761            }
762            if (comp != null) {
763                if (!components) {
764                    pr.println(prefix + "priority=" + ri.priority
765                            + " preferredOrder=" + ri.preferredOrder
766                            + " match=0x" + Integer.toHexString(ri.match)
767                            + " specificIndex=" + ri.specificIndex
768                            + " isDefault=" + ri.isDefault);
769                }
770                pr.println(prefix + comp.flattenToShortString());
771                return;
772            }
773        }
774        ri.dump(pr, prefix);
775    }
776
777    private int runResolveActivity() {
778        Intent intent;
779        try {
780            intent = parseIntentAndUser();
781        } catch (URISyntaxException e) {
782            throw new RuntimeException(e.getMessage(), e);
783        }
784        try {
785            ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
786            PrintWriter pw = getOutPrintWriter();
787            if (ri == null) {
788                pw.println("No activity found");
789            } else {
790                PrintWriterPrinter pr = new PrintWriterPrinter(pw);
791                printResolveInfo(pr, "", ri, mBrief, mComponents);
792            }
793        } catch (RemoteException e) {
794            throw new RuntimeException("Failed calling service", e);
795        }
796        return 0;
797    }
798
799    private int runQueryIntentActivities() {
800        Intent intent;
801        try {
802            intent = parseIntentAndUser();
803        } catch (URISyntaxException e) {
804            throw new RuntimeException(e.getMessage(), e);
805        }
806        try {
807            List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
808                    mTargetUser).getList();
809            PrintWriter pw = getOutPrintWriter();
810            if (result == null || result.size() <= 0) {
811                pw.println("No activities found");
812            } else {
813                if (!mComponents) {
814                    pw.print(result.size()); pw.println(" activities found:");
815                    PrintWriterPrinter pr = new PrintWriterPrinter(pw);
816                    for (int i = 0; i < result.size(); i++) {
817                        pw.print("  Activity #"); pw.print(i); pw.println(":");
818                        printResolveInfo(pr, "    ", result.get(i), mBrief, mComponents);
819                    }
820                } else {
821                    PrintWriterPrinter pr = new PrintWriterPrinter(pw);
822                    for (int i = 0; i < result.size(); i++) {
823                        printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
824                    }
825                }
826            }
827        } catch (RemoteException e) {
828            throw new RuntimeException("Failed calling service", e);
829        }
830        return 0;
831    }
832
833    private int runQueryIntentServices() {
834        Intent intent;
835        try {
836            intent = parseIntentAndUser();
837        } catch (URISyntaxException e) {
838            throw new RuntimeException(e.getMessage(), e);
839        }
840        try {
841            List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
842                    mTargetUser).getList();
843            PrintWriter pw = getOutPrintWriter();
844            if (result == null || result.size() <= 0) {
845                pw.println("No services found");
846            } else {
847                if (!mComponents) {
848                    pw.print(result.size()); pw.println(" services found:");
849                    PrintWriterPrinter pr = new PrintWriterPrinter(pw);
850                    for (int i = 0; i < result.size(); i++) {
851                        pw.print("  Service #"); pw.print(i); pw.println(":");
852                        printResolveInfo(pr, "    ", result.get(i), mBrief, mComponents);
853                    }
854                } else {
855                    PrintWriterPrinter pr = new PrintWriterPrinter(pw);
856                    for (int i = 0; i < result.size(); i++) {
857                        printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
858                    }
859                }
860            }
861        } catch (RemoteException e) {
862            throw new RuntimeException("Failed calling service", e);
863        }
864        return 0;
865    }
866
867    private int runQueryIntentReceivers() {
868        Intent intent;
869        try {
870            intent = parseIntentAndUser();
871        } catch (URISyntaxException e) {
872            throw new RuntimeException(e.getMessage(), e);
873        }
874        try {
875            List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
876                    mTargetUser).getList();
877            PrintWriter pw = getOutPrintWriter();
878            if (result == null || result.size() <= 0) {
879                pw.println("No receivers found");
880            } else {
881                if (!mComponents) {
882                    pw.print(result.size()); pw.println(" receivers found:");
883                    PrintWriterPrinter pr = new PrintWriterPrinter(pw);
884                    for (int i = 0; i < result.size(); i++) {
885                        pw.print("  Receiver #"); pw.print(i); pw.println(":");
886                        printResolveInfo(pr, "    ", result.get(i), mBrief, mComponents);
887                    }
888                } else {
889                    PrintWriterPrinter pr = new PrintWriterPrinter(pw);
890                    for (int i = 0; i < result.size(); i++) {
891                        printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
892                    }
893                }
894            }
895        } catch (RemoteException e) {
896            throw new RuntimeException("Failed calling service", e);
897        }
898        return 0;
899    }
900
901    private int runInstall() throws RemoteException {
902        final PrintWriter pw = getOutPrintWriter();
903        final InstallParams params = makeInstallParams();
904        final String inPath = getNextArg();
905
906        setParamsSize(params, inPath);
907        final int sessionId = doCreateSession(params.sessionParams,
908                params.installerPackageName, params.userId);
909        boolean abandonSession = true;
910        try {
911            if (inPath == null && params.sessionParams.sizeBytes == -1) {
912                pw.println("Error: must either specify a package size or an APK file");
913                return 1;
914            }
915            if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk",
916                    false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
917                return 1;
918            }
919            if (doCommitSession(sessionId, false /*logSuccess*/)
920                    != PackageInstaller.STATUS_SUCCESS) {
921                return 1;
922            }
923            abandonSession = false;
924            pw.println("Success");
925            return 0;
926        } finally {
927            if (abandonSession) {
928                try {
929                    doAbandonSession(sessionId, false /*logSuccess*/);
930                } catch (Exception ignore) {
931                }
932            }
933        }
934    }
935
936    private int runInstallAbandon() throws RemoteException {
937        final int sessionId = Integer.parseInt(getNextArg());
938        return doAbandonSession(sessionId, true /*logSuccess*/);
939    }
940
941    private int runInstallCommit() throws RemoteException {
942        final int sessionId = Integer.parseInt(getNextArg());
943        return doCommitSession(sessionId, true /*logSuccess*/);
944    }
945
946    private int runInstallCreate() throws RemoteException {
947        final PrintWriter pw = getOutPrintWriter();
948        final InstallParams installParams = makeInstallParams();
949        final int sessionId = doCreateSession(installParams.sessionParams,
950                installParams.installerPackageName, installParams.userId);
951
952        // NOTE: adb depends on parsing this string
953        pw.println("Success: created install session [" + sessionId + "]");
954        return 0;
955    }
956
957    private int runInstallWrite() throws RemoteException {
958        long sizeBytes = -1;
959
960        String opt;
961        while ((opt = getNextOption()) != null) {
962            if (opt.equals("-S")) {
963                sizeBytes = Long.parseLong(getNextArg());
964            } else {
965                throw new IllegalArgumentException("Unknown option: " + opt);
966            }
967        }
968
969        final int sessionId = Integer.parseInt(getNextArg());
970        final String splitName = getNextArg();
971        final String path = getNextArg();
972        return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
973    }
974
975    private int runInstallRemove() throws RemoteException {
976        final PrintWriter pw = getOutPrintWriter();
977
978        final int sessionId = Integer.parseInt(getNextArg());
979
980        final String splitName = getNextArg();
981        if (splitName == null) {
982            pw.println("Error: split name not specified");
983            return 1;
984        }
985        return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
986    }
987
988    private int runInstallExisting() throws RemoteException {
989        final PrintWriter pw = getOutPrintWriter();
990        int userId = UserHandle.USER_SYSTEM;
991        int installFlags = 0;
992        String opt;
993        while ((opt = getNextOption()) != null) {
994            switch (opt) {
995                case "--user":
996                    userId = UserHandle.parseUserArg(getNextArgRequired());
997                    break;
998                case "--ephemeral":
999                case "--instant":
1000                    installFlags |= PackageManager.INSTALL_INSTANT_APP;
1001                    installFlags &= ~PackageManager.INSTALL_FULL_APP;
1002                    break;
1003                case "--full":
1004                    installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1005                    installFlags |= PackageManager.INSTALL_FULL_APP;
1006                    break;
1007                default:
1008                    pw.println("Error: Unknown option: " + opt);
1009                    return 1;
1010            }
1011        }
1012
1013        final String packageName = getNextArg();
1014        if (packageName == null) {
1015            pw.println("Error: package name not specified");
1016            return 1;
1017        }
1018
1019        try {
1020            final int res = mInterface.installExistingPackageAsUser(packageName, userId,
1021                    installFlags, PackageManager.INSTALL_REASON_UNKNOWN);
1022            if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
1023                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1024            }
1025            pw.println("Package " + packageName + " installed for user: " + userId);
1026            return 0;
1027        } catch (RemoteException | NameNotFoundException e) {
1028            pw.println(e.toString());
1029            return 1;
1030        }
1031    }
1032
1033    private int runSetInstallLocation() throws RemoteException {
1034        int loc;
1035
1036        String arg = getNextArg();
1037        if (arg == null) {
1038            getErrPrintWriter().println("Error: no install location specified.");
1039            return 1;
1040        }
1041        try {
1042            loc = Integer.parseInt(arg);
1043        } catch (NumberFormatException e) {
1044            getErrPrintWriter().println("Error: install location has to be a number.");
1045            return 1;
1046        }
1047        if (!mInterface.setInstallLocation(loc)) {
1048            getErrPrintWriter().println("Error: install location has to be a number.");
1049            return 1;
1050        }
1051        return 0;
1052    }
1053
1054    private int runGetInstallLocation() throws RemoteException {
1055        int loc = mInterface.getInstallLocation();
1056        String locStr = "invalid";
1057        if (loc == PackageHelper.APP_INSTALL_AUTO) {
1058            locStr = "auto";
1059        } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
1060            locStr = "internal";
1061        } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
1062            locStr = "external";
1063        }
1064        getOutPrintWriter().println(loc + "[" + locStr + "]");
1065        return 0;
1066    }
1067
1068    public int runMovePackage() throws RemoteException {
1069        final String packageName = getNextArg();
1070        if (packageName == null) {
1071            getErrPrintWriter().println("Error: package name not specified");
1072            return 1;
1073        }
1074        String volumeUuid = getNextArg();
1075        if ("internal".equals(volumeUuid)) {
1076            volumeUuid = null;
1077        }
1078
1079        final int moveId = mInterface.movePackage(packageName, volumeUuid);
1080
1081        int status = mInterface.getMoveStatus(moveId);
1082        while (!PackageManager.isMoveStatusFinished(status)) {
1083            SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1084            status = mInterface.getMoveStatus(moveId);
1085        }
1086
1087        if (status == PackageManager.MOVE_SUCCEEDED) {
1088            getOutPrintWriter().println("Success");
1089            return 0;
1090        } else {
1091            getErrPrintWriter().println("Failure [" + status + "]");
1092            return 1;
1093        }
1094    }
1095
1096    public int runMovePrimaryStorage() throws RemoteException {
1097        String volumeUuid = getNextArg();
1098        if ("internal".equals(volumeUuid)) {
1099            volumeUuid = null;
1100        }
1101
1102        final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1103
1104        int status = mInterface.getMoveStatus(moveId);
1105        while (!PackageManager.isMoveStatusFinished(status)) {
1106            SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1107            status = mInterface.getMoveStatus(moveId);
1108        }
1109
1110        if (status == PackageManager.MOVE_SUCCEEDED) {
1111            getOutPrintWriter().println("Success");
1112            return 0;
1113        } else {
1114            getErrPrintWriter().println("Failure [" + status + "]");
1115            return 1;
1116        }
1117    }
1118
1119    private int runCompile() throws RemoteException {
1120        final PrintWriter pw = getOutPrintWriter();
1121        boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1122        boolean forceCompilation = false;
1123        boolean allPackages = false;
1124        boolean clearProfileData = false;
1125        String compilerFilter = null;
1126        String compilationReason = null;
1127        String checkProfilesRaw = null;
1128        boolean secondaryDex = false;
1129        String split = null;
1130
1131        String opt;
1132        while ((opt = getNextOption()) != null) {
1133            switch (opt) {
1134                case "-a":
1135                    allPackages = true;
1136                    break;
1137                case "-c":
1138                    clearProfileData = true;
1139                    break;
1140                case "-f":
1141                    forceCompilation = true;
1142                    break;
1143                case "-m":
1144                    compilerFilter = getNextArgRequired();
1145                    break;
1146                case "-r":
1147                    compilationReason = getNextArgRequired();
1148                    break;
1149                case "--check-prof":
1150                    checkProfilesRaw = getNextArgRequired();
1151                    break;
1152                case "--reset":
1153                    forceCompilation = true;
1154                    clearProfileData = true;
1155                    compilationReason = "install";
1156                    break;
1157                case "--secondary-dex":
1158                    secondaryDex = true;
1159                    break;
1160                case "--split":
1161                    split = getNextArgRequired();
1162                    break;
1163                default:
1164                    pw.println("Error: Unknown option: " + opt);
1165                    return 1;
1166            }
1167        }
1168
1169        if (checkProfilesRaw != null) {
1170            if ("true".equals(checkProfilesRaw)) {
1171                checkProfiles = true;
1172            } else if ("false".equals(checkProfilesRaw)) {
1173                checkProfiles = false;
1174            } else {
1175                pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1176                return 1;
1177            }
1178        }
1179
1180        if (compilerFilter != null && compilationReason != null) {
1181            pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
1182                    "at the same time");
1183            return 1;
1184        }
1185        if (compilerFilter == null && compilationReason == null) {
1186            pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " +
1187                    "reason (\"-r\") at the same time");
1188            return 1;
1189        }
1190
1191        if (allPackages && split != null) {
1192            pw.println("-a cannot be specified together with --split");
1193            return 1;
1194        }
1195
1196        if (secondaryDex && split != null) {
1197            pw.println("--secondary-dex cannot be specified together with --split");
1198            return 1;
1199        }
1200
1201        String targetCompilerFilter;
1202        if (compilerFilter != null) {
1203            if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1204                pw.println("Error: \"" + compilerFilter +
1205                        "\" is not a valid compilation filter.");
1206                return 1;
1207            }
1208            targetCompilerFilter = compilerFilter;
1209        } else {
1210            int reason = -1;
1211            for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1212                if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1213                        compilationReason)) {
1214                    reason = i;
1215                    break;
1216                }
1217            }
1218            if (reason == -1) {
1219                pw.println("Error: Unknown compilation reason: " + compilationReason);
1220                return 1;
1221            }
1222            targetCompilerFilter =
1223                    PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1224        }
1225
1226
1227        List<String> packageNames = null;
1228        if (allPackages) {
1229            packageNames = mInterface.getAllPackages();
1230        } else {
1231            String packageName = getNextArg();
1232            if (packageName == null) {
1233                pw.println("Error: package name not specified");
1234                return 1;
1235            }
1236            packageNames = Collections.singletonList(packageName);
1237        }
1238
1239        List<String> failedPackages = new ArrayList<>();
1240        int index = 0;
1241        for (String packageName : packageNames) {
1242            if (clearProfileData) {
1243                mInterface.clearApplicationProfileData(packageName);
1244            }
1245
1246            if (allPackages) {
1247                pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1248                pw.flush();
1249            }
1250
1251            boolean result = secondaryDex
1252                    ? mInterface.performDexOptSecondary(packageName,
1253                            targetCompilerFilter, forceCompilation)
1254                    : mInterface.performDexOptMode(packageName,
1255                            checkProfiles, targetCompilerFilter, forceCompilation,
1256                            true /* bootComplete */, split);
1257            if (!result) {
1258                failedPackages.add(packageName);
1259            }
1260        }
1261
1262        if (failedPackages.isEmpty()) {
1263            pw.println("Success");
1264            return 0;
1265        } else if (failedPackages.size() == 1) {
1266            pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1267            return 1;
1268        } else {
1269            pw.print("Failure: the following packages could not be compiled: ");
1270            boolean is_first = true;
1271            for (String packageName : failedPackages) {
1272                if (is_first) {
1273                    is_first = false;
1274                } else {
1275                    pw.print(", ");
1276                }
1277                pw.print(packageName);
1278            }
1279            pw.println();
1280            return 1;
1281        }
1282    }
1283
1284    private int runreconcileSecondaryDexFiles() throws RemoteException {
1285        String packageName = getNextArg();
1286        mInterface.reconcileSecondaryDexFiles(packageName);
1287        return 0;
1288    }
1289
1290    public int runForceDexOpt() throws RemoteException {
1291        mInterface.forceDexOpt(getNextArgRequired());
1292        return 0;
1293    }
1294
1295    private int runDexoptJob() throws RemoteException {
1296        String arg;
1297        List<String> packageNames = new ArrayList<>();
1298        while ((arg = getNextArg()) != null) {
1299            packageNames.add(arg);
1300        }
1301        boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1302                packageNames);
1303        return result ? 0 : -1;
1304    }
1305
1306    private int runDumpProfiles() throws RemoteException {
1307        String packageName = getNextArg();
1308        mInterface.dumpProfiles(packageName);
1309        return 0;
1310    }
1311
1312    private int runSnapshotProfile() throws RemoteException {
1313        PrintWriter pw = getOutPrintWriter();
1314
1315        // Parse the arguments
1316        final String packageName = getNextArg();
1317        final boolean isBootImage = "android".equals(packageName);
1318
1319        String codePath = null;
1320        String opt;
1321        while ((opt = getNextArg()) != null) {
1322            switch (opt) {
1323                case "--code-path":
1324                    if (isBootImage) {
1325                        pw.write("--code-path cannot be used for the boot image.");
1326                        return -1;
1327                    }
1328                    codePath = getNextArg();
1329                    break;
1330                default:
1331                    pw.write("Unknown arg: " + opt);
1332                    return -1;
1333            }
1334        }
1335
1336        // If no code path was explicitly requested, select the base code path.
1337        String baseCodePath = null;
1338        if (!isBootImage) {
1339            PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
1340                    /* userId */0);
1341            if (packageInfo == null) {
1342                pw.write("Package not found " + packageName);
1343                return -1;
1344            }
1345            baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
1346            if (codePath == null) {
1347                codePath = baseCodePath;
1348            }
1349        }
1350
1351        // Create the profile snapshot.
1352        final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
1353        // The calling package is needed to debug permission access.
1354        final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
1355                ? "root" : "com.android.shell";
1356        final int profileType = isBootImage
1357                ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
1358        if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
1359            pw.println("Error: Runtime profiling is not enabled");
1360            return -1;
1361        }
1362        mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
1363                codePath, callback, callingPackage);
1364        if (!callback.waitTillDone()) {
1365            pw.println("Error: callback not called");
1366            return callback.mErrCode;
1367        }
1368
1369        // Copy the snapshot profile to the output profile file.
1370        try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
1371            final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
1372                    ? "" : ("-" + new File(codePath).getName());
1373            final String outputProfilePath =
1374                    ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
1375            try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
1376                Streams.copy(inStream, outStream);
1377            }
1378            // Give read permissions to the other group.
1379            Os.chmod(outputProfilePath, /*mode*/ 0644 );
1380        } catch (IOException | ErrnoException e) {
1381            pw.println("Error when reading the profile fd: " + e.getMessage());
1382            e.printStackTrace(pw);
1383            return -1;
1384        }
1385        return 0;
1386    }
1387
1388    private static class SnapshotRuntimeProfileCallback
1389            extends ISnapshotRuntimeProfileCallback.Stub {
1390        private boolean mSuccess = false;
1391        private int mErrCode = -1;
1392        private ParcelFileDescriptor mProfileReadFd = null;
1393        private CountDownLatch mDoneSignal = new CountDownLatch(1);
1394
1395        @Override
1396        public void onSuccess(ParcelFileDescriptor profileReadFd) {
1397            mSuccess = true;
1398            try {
1399                // We need to dup the descriptor. We are in the same process as system server
1400                // and we will be receiving the same object (which will be closed on the
1401                // server side).
1402                mProfileReadFd = profileReadFd.dup();
1403            } catch (IOException e) {
1404                e.printStackTrace();
1405            }
1406            mDoneSignal.countDown();
1407        }
1408
1409        @Override
1410        public void onError(int errCode) {
1411            mSuccess = false;
1412            mErrCode = errCode;
1413            mDoneSignal.countDown();
1414        }
1415
1416        boolean waitTillDone() {
1417            boolean done = false;
1418            try {
1419                // The time-out is an arbitrary large value. Since this is a local call the result
1420                // will come very fast.
1421                done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS);
1422            } catch (InterruptedException ignored) {
1423            }
1424            return done && mSuccess;
1425        }
1426    }
1427
1428    private int runUninstall() throws RemoteException {
1429        final PrintWriter pw = getOutPrintWriter();
1430        int flags = 0;
1431        int userId = UserHandle.USER_ALL;
1432        long versionCode = PackageManager.VERSION_CODE_HIGHEST;
1433
1434        String opt;
1435        while ((opt = getNextOption()) != null) {
1436            switch (opt) {
1437                case "-k":
1438                    flags |= PackageManager.DELETE_KEEP_DATA;
1439                    break;
1440                case "--user":
1441                    userId = UserHandle.parseUserArg(getNextArgRequired());
1442                    break;
1443                case "--versionCode":
1444                    versionCode = Long.parseLong(getNextArgRequired());
1445                    break;
1446                default:
1447                    pw.println("Error: Unknown option: " + opt);
1448                    return 1;
1449            }
1450        }
1451
1452        final String packageName = getNextArg();
1453        if (packageName == null) {
1454            pw.println("Error: package name not specified");
1455            return 1;
1456        }
1457
1458        // if a split is specified, just remove it and not the whole package
1459        final String splitName = getNextArg();
1460        if (splitName != null) {
1461            return runRemoveSplit(packageName, splitName);
1462        }
1463
1464        userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
1465        if (userId == UserHandle.USER_ALL) {
1466            userId = UserHandle.USER_SYSTEM;
1467            flags |= PackageManager.DELETE_ALL_USERS;
1468        } else {
1469            final PackageInfo info = mInterface.getPackageInfo(packageName,
1470                    PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1471            if (info == null) {
1472                pw.println("Failure [not installed for " + userId + "]");
1473                return 1;
1474            }
1475            final boolean isSystem =
1476                    (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1477            // If we are being asked to delete a system app for just one
1478            // user set flag so it disables rather than reverting to system
1479            // version of the app.
1480            if (isSystem) {
1481                flags |= PackageManager.DELETE_SYSTEM_APP;
1482            }
1483        }
1484
1485        final LocalIntentReceiver receiver = new LocalIntentReceiver();
1486        mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1487                versionCode), null /*callerPackageName*/, flags,
1488                receiver.getIntentSender(), userId);
1489
1490        final Intent result = receiver.getResult();
1491        final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1492                PackageInstaller.STATUS_FAILURE);
1493        if (status == PackageInstaller.STATUS_SUCCESS) {
1494            pw.println("Success");
1495            return 0;
1496        } else {
1497            pw.println("Failure ["
1498                    + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1499            return 1;
1500        }
1501    }
1502
1503    private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1504        final PrintWriter pw = getOutPrintWriter();
1505        final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1506        sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1507        sessionParams.appPackageName = packageName;
1508        final int sessionId =
1509                doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1510        boolean abandonSession = true;
1511        try {
1512            if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1513                    != PackageInstaller.STATUS_SUCCESS) {
1514                return 1;
1515            }
1516            if (doCommitSession(sessionId, false /*logSuccess*/)
1517                    != PackageInstaller.STATUS_SUCCESS) {
1518                return 1;
1519            }
1520            abandonSession = false;
1521            pw.println("Success");
1522            return 0;
1523        } finally {
1524            if (abandonSession) {
1525                try {
1526                    doAbandonSession(sessionId, false /*logSuccess*/);
1527                } catch (Exception ignore) {
1528                }
1529            }
1530        }
1531    }
1532
1533    static class ClearDataObserver extends IPackageDataObserver.Stub {
1534        boolean finished;
1535        boolean result;
1536
1537        @Override
1538        public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1539            synchronized (this) {
1540                finished = true;
1541                result = succeeded;
1542                notifyAll();
1543            }
1544        }
1545    }
1546
1547    private int runClear() throws RemoteException {
1548        int userId = UserHandle.USER_SYSTEM;
1549        String option = getNextOption();
1550        if (option != null && option.equals("--user")) {
1551            userId = UserHandle.parseUserArg(getNextArgRequired());
1552        }
1553
1554        String pkg = getNextArg();
1555        if (pkg == null) {
1556            getErrPrintWriter().println("Error: no package specified");
1557            return 1;
1558        }
1559
1560        ClearDataObserver obs = new ClearDataObserver();
1561        ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
1562        synchronized (obs) {
1563            while (!obs.finished) {
1564                try {
1565                    obs.wait();
1566                } catch (InterruptedException e) {
1567                }
1568            }
1569        }
1570
1571        if (obs.result) {
1572            getOutPrintWriter().println("Success");
1573            return 0;
1574        } else {
1575            getErrPrintWriter().println("Failed");
1576            return 1;
1577        }
1578    }
1579
1580    private static String enabledSettingToString(int state) {
1581        switch (state) {
1582            case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1583                return "default";
1584            case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1585                return "enabled";
1586            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1587                return "disabled";
1588            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1589                return "disabled-user";
1590            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1591                return "disabled-until-used";
1592        }
1593        return "unknown";
1594    }
1595
1596    private int runSetEnabledSetting(int state) throws RemoteException {
1597        int userId = UserHandle.USER_SYSTEM;
1598        String option = getNextOption();
1599        if (option != null && option.equals("--user")) {
1600            userId = UserHandle.parseUserArg(getNextArgRequired());
1601        }
1602
1603        String pkg = getNextArg();
1604        if (pkg == null) {
1605            getErrPrintWriter().println("Error: no package or component specified");
1606            return 1;
1607        }
1608        ComponentName cn = ComponentName.unflattenFromString(pkg);
1609        if (cn == null) {
1610            mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1611                    "shell:" + android.os.Process.myUid());
1612            getOutPrintWriter().println("Package " + pkg + " new state: "
1613                    + enabledSettingToString(
1614                    mInterface.getApplicationEnabledSetting(pkg, userId)));
1615            return 0;
1616        } else {
1617            mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1618            getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1619                    + enabledSettingToString(
1620                    mInterface.getComponentEnabledSetting(cn, userId)));
1621            return 0;
1622        }
1623    }
1624
1625    private int runSetHiddenSetting(boolean state) throws RemoteException {
1626        int userId = UserHandle.USER_SYSTEM;
1627        String option = getNextOption();
1628        if (option != null && option.equals("--user")) {
1629            userId = UserHandle.parseUserArg(getNextArgRequired());
1630        }
1631
1632        String pkg = getNextArg();
1633        if (pkg == null) {
1634            getErrPrintWriter().println("Error: no package or component specified");
1635            return 1;
1636        }
1637        mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1638        getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1639                + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1640        return 0;
1641    }
1642
1643    private int runSuspend(boolean suspendedState) {
1644        final PrintWriter pw = getOutPrintWriter();
1645        int userId = UserHandle.USER_SYSTEM;
1646        String dialogMessage = null;
1647        final PersistableBundle appExtras = new PersistableBundle();
1648        final PersistableBundle launcherExtras = new PersistableBundle();
1649        String opt;
1650        while ((opt = getNextOption()) != null) {
1651            switch (opt) {
1652                case "--user":
1653                    userId = UserHandle.parseUserArg(getNextArgRequired());
1654                    break;
1655                case "--dialogMessage":
1656                    dialogMessage = getNextArgRequired();
1657                    break;
1658                case "--ael":
1659                case "--aes":
1660                case "--aed":
1661                case "--lel":
1662                case "--les":
1663                case "--led":
1664                    final String key = getNextArgRequired();
1665                    final String val = getNextArgRequired();
1666                    if (!suspendedState) {
1667                        break;
1668                    }
1669                    final PersistableBundle bundleToInsert =
1670                            opt.startsWith("--a") ? appExtras : launcherExtras;
1671                    switch (opt.charAt(4)) {
1672                        case 'l':
1673                            bundleToInsert.putLong(key, Long.valueOf(val));
1674                            break;
1675                        case 'd':
1676                            bundleToInsert.putDouble(key, Double.valueOf(val));
1677                            break;
1678                        case 's':
1679                            bundleToInsert.putString(key, val);
1680                            break;
1681                    }
1682                    break;
1683                default:
1684                    pw.println("Error: Unknown option: " + opt);
1685                    return 1;
1686            }
1687        }
1688
1689        final String packageName = getNextArg();
1690        if (packageName == null) {
1691            pw.println("Error: package name not specified");
1692            return 1;
1693        }
1694        final String callingPackage =
1695                (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
1696        try {
1697            mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
1698                    appExtras, launcherExtras, dialogMessage, callingPackage, userId);
1699            pw.println("Package " + packageName + " new suspended state: "
1700                    + mInterface.isPackageSuspendedForUser(packageName, userId));
1701            return 0;
1702        } catch (RemoteException | IllegalArgumentException e) {
1703            pw.println(e.toString());
1704            return 1;
1705        }
1706    }
1707
1708    private int runGrantRevokePermission(boolean grant) throws RemoteException {
1709        int userId = UserHandle.USER_SYSTEM;
1710
1711        String opt = null;
1712        while ((opt = getNextOption()) != null) {
1713            if (opt.equals("--user")) {
1714                userId = UserHandle.parseUserArg(getNextArgRequired());
1715            }
1716        }
1717
1718        String pkg = getNextArg();
1719        if (pkg == null) {
1720            getErrPrintWriter().println("Error: no package specified");
1721            return 1;
1722        }
1723        String perm = getNextArg();
1724        if (perm == null) {
1725            getErrPrintWriter().println("Error: no permission specified");
1726            return 1;
1727        }
1728
1729        if (grant) {
1730            mInterface.grantRuntimePermission(pkg, perm, userId);
1731        } else {
1732            mInterface.revokeRuntimePermission(pkg, perm, userId);
1733        }
1734        return 0;
1735    }
1736
1737    private int runResetPermissions() throws RemoteException {
1738        mInterface.resetRuntimePermissions();
1739        return 0;
1740    }
1741
1742    private int runSetPermissionEnforced() throws RemoteException {
1743        final String permission = getNextArg();
1744        if (permission == null) {
1745            getErrPrintWriter().println("Error: no permission specified");
1746            return 1;
1747        }
1748        final String enforcedRaw = getNextArg();
1749        if (enforcedRaw == null) {
1750            getErrPrintWriter().println("Error: no enforcement specified");
1751            return 1;
1752        }
1753        mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
1754        return 0;
1755    }
1756
1757    private boolean isVendorApp(String pkg) {
1758        try {
1759            final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1760            return info != null && info.applicationInfo.isVendor();
1761        } catch (RemoteException e) {
1762            return false;
1763        }
1764    }
1765
1766    private boolean isProductApp(String pkg) {
1767        try {
1768            final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1769            return info != null && info.applicationInfo.isProduct();
1770        } catch (RemoteException e) {
1771            return false;
1772        }
1773    }
1774
1775    private int runGetPrivappPermissions() {
1776        final String pkg = getNextArg();
1777        if (pkg == null) {
1778            getErrPrintWriter().println("Error: no package specified.");
1779            return 1;
1780        }
1781
1782        ArraySet<String> privAppPermissions = null;
1783        if (isVendorApp(pkg)) {
1784            privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
1785        } else if (isProductApp(pkg)) {
1786            privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
1787        } else {
1788            privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
1789        }
1790
1791        getOutPrintWriter().println(privAppPermissions == null
1792                ? "{}" : privAppPermissions.toString());
1793        return 0;
1794    }
1795
1796    private int runGetPrivappDenyPermissions() {
1797        final String pkg = getNextArg();
1798        if (pkg == null) {
1799            getErrPrintWriter().println("Error: no package specified.");
1800            return 1;
1801        }
1802
1803        ArraySet<String> privAppPermissions = null;
1804        if (isVendorApp(pkg)) {
1805            privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
1806        } else if (isProductApp(pkg)) {
1807            privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
1808        } else {
1809            privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
1810        }
1811
1812        getOutPrintWriter().println(privAppPermissions == null
1813                ? "{}" : privAppPermissions.toString());
1814        return 0;
1815    }
1816
1817    private int runGetOemPermissions() {
1818        final String pkg = getNextArg();
1819        if (pkg == null) {
1820            getErrPrintWriter().println("Error: no package specified.");
1821            return 1;
1822        }
1823        final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
1824                .getOemPermissions(pkg);
1825        if (oemPermissions == null || oemPermissions.isEmpty()) {
1826            getOutPrintWriter().println("{}");
1827        } else {
1828            oemPermissions.forEach((permission, granted) ->
1829                    getOutPrintWriter().println(permission + " granted:" + granted)
1830            );
1831        }
1832        return 0;
1833    }
1834
1835    private String linkStateToString(int state) {
1836        switch (state) {
1837            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
1838            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
1839            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
1840            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
1841            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
1842        }
1843        return "Unknown link state: " + state;
1844    }
1845
1846    // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
1847    private int runSetAppLink() throws RemoteException {
1848        int userId = UserHandle.USER_SYSTEM;
1849
1850        String opt;
1851        while ((opt = getNextOption()) != null) {
1852            if (opt.equals("--user")) {
1853                userId = UserHandle.parseUserArg(getNextArgRequired());
1854            } else {
1855                getErrPrintWriter().println("Error: unknown option: " + opt);
1856                return 1;
1857            }
1858        }
1859
1860        // Package name to act on; required
1861        final String pkg = getNextArg();
1862        if (pkg == null) {
1863            getErrPrintWriter().println("Error: no package specified.");
1864            return 1;
1865        }
1866
1867        // State to apply; {always|ask|never|undefined}, required
1868        final String modeString = getNextArg();
1869        if (modeString == null) {
1870            getErrPrintWriter().println("Error: no app link state specified.");
1871            return 1;
1872        }
1873
1874        final int newMode;
1875        switch (modeString.toLowerCase()) {
1876            case "undefined":
1877                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1878                break;
1879
1880            case "always":
1881                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1882                break;
1883
1884            case "ask":
1885                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1886                break;
1887
1888            case "always-ask":
1889                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
1890                break;
1891
1892            case "never":
1893                newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
1894                break;
1895
1896            default:
1897                getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
1898                return 1;
1899        }
1900
1901        final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1902        if (info == null) {
1903            getErrPrintWriter().println("Error: package " + pkg + " not found.");
1904            return 1;
1905        }
1906
1907        if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1908            getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1909            return 1;
1910        }
1911
1912        if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
1913            getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
1914            return 1;
1915        }
1916
1917        return 0;
1918    }
1919
1920    // pm get-app-link [--user USER_ID] PACKAGE
1921    private int runGetAppLink() throws RemoteException {
1922        int userId = UserHandle.USER_SYSTEM;
1923
1924        String opt;
1925        while ((opt = getNextOption()) != null) {
1926            if (opt.equals("--user")) {
1927                userId = UserHandle.parseUserArg(getNextArgRequired());
1928            } else {
1929                getErrPrintWriter().println("Error: unknown option: " + opt);
1930                return 1;
1931            }
1932        }
1933
1934        // Package name to act on; required
1935        final String pkg = getNextArg();
1936        if (pkg == null) {
1937            getErrPrintWriter().println("Error: no package specified.");
1938            return 1;
1939        }
1940
1941        final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1942        if (info == null) {
1943            getErrPrintWriter().println("Error: package " + pkg + " not found.");
1944            return 1;
1945        }
1946
1947        if ((info.applicationInfo.privateFlags
1948                & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1949            getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1950            return 1;
1951        }
1952
1953        getOutPrintWriter().println(linkStateToString(
1954                mInterface.getIntentVerificationStatus(pkg, userId)));
1955
1956        return 0;
1957    }
1958
1959    private int runTrimCaches() throws RemoteException {
1960        String size = getNextArg();
1961        if (size == null) {
1962            getErrPrintWriter().println("Error: no size specified");
1963            return 1;
1964        }
1965        long multiplier = 1;
1966        int len = size.length();
1967        char c = size.charAt(len - 1);
1968        if (c < '0' || c > '9') {
1969            if (c == 'K' || c == 'k') {
1970                multiplier = 1024L;
1971            } else if (c == 'M' || c == 'm') {
1972                multiplier = 1024L*1024L;
1973            } else if (c == 'G' || c == 'g') {
1974                multiplier = 1024L*1024L*1024L;
1975            } else {
1976                getErrPrintWriter().println("Invalid suffix: " + c);
1977                return 1;
1978            }
1979            size = size.substring(0, len-1);
1980        }
1981        long sizeVal;
1982        try {
1983            sizeVal = Long.parseLong(size) * multiplier;
1984        } catch (NumberFormatException e) {
1985            getErrPrintWriter().println("Error: expected number at: " + size);
1986            return 1;
1987        }
1988        String volumeUuid = getNextArg();
1989        if ("internal".equals(volumeUuid)) {
1990            volumeUuid = null;
1991        }
1992        ClearDataObserver obs = new ClearDataObserver();
1993        mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
1994                StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
1995        synchronized (obs) {
1996            while (!obs.finished) {
1997                try {
1998                    obs.wait();
1999                } catch (InterruptedException e) {
2000                }
2001            }
2002        }
2003        return 0;
2004    }
2005
2006    private static boolean isNumber(String s) {
2007        try {
2008            Integer.parseInt(s);
2009        } catch (NumberFormatException nfe) {
2010            return false;
2011        }
2012        return true;
2013    }
2014
2015    public int runCreateUser() throws RemoteException {
2016        String name;
2017        int userId = -1;
2018        int flags = 0;
2019        String opt;
2020        while ((opt = getNextOption()) != null) {
2021            if ("--profileOf".equals(opt)) {
2022                userId = UserHandle.parseUserArg(getNextArgRequired());
2023            } else if ("--managed".equals(opt)) {
2024                flags |= UserInfo.FLAG_MANAGED_PROFILE;
2025            } else if ("--restricted".equals(opt)) {
2026                flags |= UserInfo.FLAG_RESTRICTED;
2027            } else if ("--ephemeral".equals(opt)) {
2028                flags |= UserInfo.FLAG_EPHEMERAL;
2029            } else if ("--guest".equals(opt)) {
2030                flags |= UserInfo.FLAG_GUEST;
2031            } else if ("--demo".equals(opt)) {
2032                flags |= UserInfo.FLAG_DEMO;
2033            } else {
2034                getErrPrintWriter().println("Error: unknown option " + opt);
2035                return 1;
2036            }
2037        }
2038        String arg = getNextArg();
2039        if (arg == null) {
2040            getErrPrintWriter().println("Error: no user name specified.");
2041            return 1;
2042        }
2043        name = arg;
2044        UserInfo info;
2045        IUserManager um = IUserManager.Stub.asInterface(
2046                ServiceManager.getService(Context.USER_SERVICE));
2047        IAccountManager accm = IAccountManager.Stub.asInterface(
2048                ServiceManager.getService(Context.ACCOUNT_SERVICE));
2049        if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
2050            // In non-split user mode, userId can only be SYSTEM
2051            int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
2052            info = um.createRestrictedProfile(name, parentUserId);
2053            accm.addSharedAccountsFromParentUser(parentUserId, userId,
2054                    (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
2055        } else if (userId < 0) {
2056            info = um.createUser(name, flags);
2057        } else {
2058            info = um.createProfileForUser(name, flags, userId, null);
2059        }
2060
2061        if (info != null) {
2062            getOutPrintWriter().println("Success: created user id " + info.id);
2063            return 0;
2064        } else {
2065            getErrPrintWriter().println("Error: couldn't create User.");
2066            return 1;
2067        }
2068    }
2069
2070    public int runRemoveUser() throws RemoteException {
2071        int userId;
2072        String arg = getNextArg();
2073        if (arg == null) {
2074            getErrPrintWriter().println("Error: no user id specified.");
2075            return 1;
2076        }
2077        userId = UserHandle.parseUserArg(arg);
2078        IUserManager um = IUserManager.Stub.asInterface(
2079                ServiceManager.getService(Context.USER_SERVICE));
2080        if (um.removeUser(userId)) {
2081            getOutPrintWriter().println("Success: removed user");
2082            return 0;
2083        } else {
2084            getErrPrintWriter().println("Error: couldn't remove user id " + userId);
2085            return 1;
2086        }
2087    }
2088
2089    public int runSetUserRestriction() throws RemoteException {
2090        int userId = UserHandle.USER_SYSTEM;
2091        String opt = getNextOption();
2092        if (opt != null && "--user".equals(opt)) {
2093            userId = UserHandle.parseUserArg(getNextArgRequired());
2094        }
2095
2096        String restriction = getNextArg();
2097        String arg = getNextArg();
2098        boolean value;
2099        if ("1".equals(arg)) {
2100            value = true;
2101        } else if ("0".equals(arg)) {
2102            value = false;
2103        } else {
2104            getErrPrintWriter().println("Error: valid value not specified");
2105            return 1;
2106        }
2107        IUserManager um = IUserManager.Stub.asInterface(
2108                ServiceManager.getService(Context.USER_SERVICE));
2109        um.setUserRestriction(restriction, value, userId);
2110        return 0;
2111    }
2112
2113    public int runGetMaxUsers() {
2114        getOutPrintWriter().println("Maximum supported users: "
2115                + UserManager.getMaxSupportedUsers());
2116        return 0;
2117    }
2118
2119    public int runGetMaxRunningUsers() {
2120        ActivityManagerInternal activityManagerInternal =
2121                LocalServices.getService(ActivityManagerInternal.class);
2122        getOutPrintWriter().println("Maximum supported running users: "
2123                + activityManagerInternal.getMaxRunningUsers());
2124        return 0;
2125    }
2126
2127    private static class InstallParams {
2128        SessionParams sessionParams;
2129        String installerPackageName;
2130        int userId = UserHandle.USER_ALL;
2131    }
2132
2133    private InstallParams makeInstallParams() {
2134        final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
2135        final InstallParams params = new InstallParams();
2136        params.sessionParams = sessionParams;
2137        String opt;
2138        boolean replaceExisting = true;
2139        while ((opt = getNextOption()) != null) {
2140            switch (opt) {
2141                case "-l":
2142                    sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
2143                    break;
2144                case "-r": // ignore
2145                    break;
2146                case "-R":
2147                    replaceExisting = false;
2148                    break;
2149                case "-i":
2150                    params.installerPackageName = getNextArg();
2151                    if (params.installerPackageName == null) {
2152                        throw new IllegalArgumentException("Missing installer package");
2153                    }
2154                    break;
2155                case "-t":
2156                    sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
2157                    break;
2158                case "-s":
2159                    sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL;
2160                    break;
2161                case "-f":
2162                    sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
2163                    break;
2164                case "-d":
2165                    sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
2166                    break;
2167                case "-g":
2168                    sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
2169                    break;
2170                case "--dont-kill":
2171                    sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
2172                    break;
2173                case "--originating-uri":
2174                    sessionParams.originatingUri = Uri.parse(getNextArg());
2175                    break;
2176                case "--referrer":
2177                    sessionParams.referrerUri = Uri.parse(getNextArg());
2178                    break;
2179                case "-p":
2180                    sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
2181                    sessionParams.appPackageName = getNextArg();
2182                    if (sessionParams.appPackageName == null) {
2183                        throw new IllegalArgumentException("Missing inherit package name");
2184                    }
2185                    break;
2186                case "--pkg":
2187                    sessionParams.appPackageName = getNextArg();
2188                    if (sessionParams.appPackageName == null) {
2189                        throw new IllegalArgumentException("Missing package name");
2190                    }
2191                    break;
2192                case "-S":
2193                    final long sizeBytes = Long.parseLong(getNextArg());
2194                    if (sizeBytes <= 0) {
2195                        throw new IllegalArgumentException("Size must be positive");
2196                    }
2197                    sessionParams.setSize(sizeBytes);
2198                    break;
2199                case "--abi":
2200                    sessionParams.abiOverride = checkAbiArgument(getNextArg());
2201                    break;
2202                case "--ephemeral":
2203                case "--instant":
2204                case "--instantapp":
2205                    sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
2206                    break;
2207                case "--full":
2208                    sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
2209                    break;
2210                case "--preload":
2211                    sessionParams.setInstallAsVirtualPreload();
2212                    break;
2213                case "--user":
2214                    params.userId = UserHandle.parseUserArg(getNextArgRequired());
2215                    break;
2216                case "--install-location":
2217                    sessionParams.installLocation = Integer.parseInt(getNextArg());
2218                    break;
2219                case "--force-uuid":
2220                    sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
2221                    sessionParams.volumeUuid = getNextArg();
2222                    if ("internal".equals(sessionParams.volumeUuid)) {
2223                        sessionParams.volumeUuid = null;
2224                    }
2225                    break;
2226                case "--force-sdk":
2227                    sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK;
2228                    break;
2229                default:
2230                    throw new IllegalArgumentException("Unknown option " + opt);
2231            }
2232            if (replaceExisting) {
2233                sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
2234            }
2235        }
2236        return params;
2237    }
2238
2239    private int runSetHomeActivity() {
2240        final PrintWriter pw = getOutPrintWriter();
2241        int userId = UserHandle.USER_SYSTEM;
2242        String opt;
2243        while ((opt = getNextOption()) != null) {
2244            switch (opt) {
2245                case "--user":
2246                    userId = UserHandle.parseUserArg(getNextArgRequired());
2247                    break;
2248                default:
2249                    pw.println("Error: Unknown option: " + opt);
2250                    return 1;
2251            }
2252        }
2253
2254        String component = getNextArg();
2255        ComponentName componentName =
2256                component != null ? ComponentName.unflattenFromString(component) : null;
2257
2258        if (componentName == null) {
2259            pw.println("Error: component name not specified or invalid");
2260            return 1;
2261        }
2262
2263        try {
2264            mInterface.setHomeActivity(componentName, userId);
2265            pw.println("Success");
2266            return 0;
2267        } catch (Exception e) {
2268            pw.println(e.toString());
2269            return 1;
2270        }
2271    }
2272
2273    private int runSetInstaller() throws RemoteException {
2274        final String targetPackage = getNextArg();
2275        final String installerPackageName = getNextArg();
2276
2277        if (targetPackage == null || installerPackageName == null) {
2278            getErrPrintWriter().println("Must provide both target and installer package names");
2279            return 1;
2280        }
2281
2282        mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2283        getOutPrintWriter().println("Success");
2284        return 0;
2285    }
2286
2287    private int runGetInstantAppResolver() {
2288        final PrintWriter pw = getOutPrintWriter();
2289        try {
2290            final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2291            if (instantAppsResolver == null) {
2292                return 1;
2293            }
2294            pw.println(instantAppsResolver.flattenToString());
2295            return 0;
2296        } catch (Exception e) {
2297            pw.println(e.toString());
2298            return 1;
2299        }
2300    }
2301
2302    private int runHasFeature() {
2303        final PrintWriter err = getErrPrintWriter();
2304        final String featureName = getNextArg();
2305        if (featureName == null) {
2306            err.println("Error: expected FEATURE name");
2307            return 1;
2308        }
2309        final String versionString = getNextArg();
2310        try {
2311            final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2312            final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2313            getOutPrintWriter().println(hasFeature);
2314            return hasFeature ? 0 : 1;
2315        } catch (NumberFormatException e) {
2316            err.println("Error: illegal version number " + versionString);
2317            return 1;
2318        } catch (RemoteException e) {
2319            err.println(e.toString());
2320            return 1;
2321        }
2322    }
2323
2324    private int runDump() {
2325        String pkg = getNextArg();
2326        if (pkg == null) {
2327            getErrPrintWriter().println("Error: no package specified");
2328            return 1;
2329        }
2330        ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2331        return 0;
2332    }
2333
2334    private int runSetHarmfulAppWarning() throws RemoteException {
2335        int userId = UserHandle.USER_CURRENT;
2336
2337        String opt;
2338        while ((opt = getNextOption()) != null) {
2339            if (opt.equals("--user")) {
2340                userId = UserHandle.parseUserArg(getNextArgRequired());
2341            } else {
2342                getErrPrintWriter().println("Error: Unknown option: " + opt);
2343                return -1;
2344            }
2345        }
2346
2347        userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning");
2348
2349        final String packageName = getNextArgRequired();
2350        final String warning = getNextArg();
2351
2352        mInterface.setHarmfulAppWarning(packageName, warning, userId);
2353
2354        return 0;
2355    }
2356
2357    private int runGetHarmfulAppWarning() throws RemoteException {
2358        int userId = UserHandle.USER_CURRENT;
2359
2360        String opt;
2361        while ((opt = getNextOption()) != null) {
2362            if (opt.equals("--user")) {
2363                userId = UserHandle.parseUserArg(getNextArgRequired());
2364            } else {
2365                getErrPrintWriter().println("Error: Unknown option: " + opt);
2366                return -1;
2367            }
2368        }
2369
2370        userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning");
2371
2372        final String packageName = getNextArgRequired();
2373        final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId);
2374        if (!TextUtils.isEmpty(warning)) {
2375            getOutPrintWriter().println(warning);
2376            return 0;
2377        } else {
2378            return 1;
2379        }
2380    }
2381
2382    private static String checkAbiArgument(String abi) {
2383        if (TextUtils.isEmpty(abi)) {
2384            throw new IllegalArgumentException("Missing ABI argument");
2385        }
2386
2387        if ("-".equals(abi)) {
2388            return abi;
2389        }
2390
2391        final String[] supportedAbis = Build.SUPPORTED_ABIS;
2392        for (String supportedAbi : supportedAbis) {
2393            if (supportedAbi.equals(abi)) {
2394                return abi;
2395            }
2396        }
2397
2398        throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2399    }
2400
2401    private int translateUserId(int userId, boolean allowAll, String logContext) {
2402        return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2403                userId, allowAll, true, logContext, "pm command");
2404    }
2405
2406    private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2407            throws RemoteException {
2408        userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
2409        if (userId == UserHandle.USER_ALL) {
2410            userId = UserHandle.USER_SYSTEM;
2411            params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2412        }
2413
2414        final int sessionId = mInterface.getPackageInstaller()
2415                .createSession(params, installerPackageName, userId);
2416        return sessionId;
2417    }
2418
2419    private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
2420            boolean logSuccess) throws RemoteException {
2421        final PrintWriter pw = getOutPrintWriter();
2422        final ParcelFileDescriptor fd;
2423        if (STDIN_PATH.equals(inPath)) {
2424            fd = new ParcelFileDescriptor(getInFileDescriptor());
2425        } else if (inPath != null) {
2426            fd = openFileForSystem(inPath, "r");
2427            if (fd == null) {
2428                return -1;
2429            }
2430            sizeBytes = fd.getStatSize();
2431            if (sizeBytes < 0) {
2432                getErrPrintWriter().println("Unable to get size of: " + inPath);
2433                return -1;
2434            }
2435        } else {
2436            fd = new ParcelFileDescriptor(getInFileDescriptor());
2437        }
2438        if (sizeBytes <= 0) {
2439            getErrPrintWriter().println("Error: must specify a APK size");
2440            return 1;
2441        }
2442
2443        PackageInstaller.Session session = null;
2444        try {
2445            session = new PackageInstaller.Session(
2446                    mInterface.getPackageInstaller().openSession(sessionId));
2447            session.write(splitName, 0, sizeBytes, fd);
2448
2449            if (logSuccess) {
2450                pw.println("Success: streamed " + sizeBytes + " bytes");
2451            }
2452            return 0;
2453        } catch (IOException e) {
2454            getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
2455            return 1;
2456        } finally {
2457            IoUtils.closeQuietly(session);
2458        }
2459    }
2460
2461    private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2462            throws RemoteException {
2463        final PrintWriter pw = getOutPrintWriter();
2464        PackageInstaller.Session session = null;
2465        try {
2466            session = new PackageInstaller.Session(
2467                    mInterface.getPackageInstaller().openSession(sessionId));
2468            session.removeSplit(splitName);
2469
2470            if (logSuccess) {
2471                pw.println("Success");
2472            }
2473            return 0;
2474        } catch (IOException e) {
2475            pw.println("Error: failed to remove split; " + e.getMessage());
2476            return 1;
2477        } finally {
2478            IoUtils.closeQuietly(session);
2479        }
2480    }
2481
2482    private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException {
2483        final PrintWriter pw = getOutPrintWriter();
2484        PackageInstaller.Session session = null;
2485        try {
2486            session = new PackageInstaller.Session(
2487                    mInterface.getPackageInstaller().openSession(sessionId));
2488
2489            // Sanity check that all .dm files match an apk.
2490            // (The installer does not support standalone .dm files and will not process them.)
2491            try {
2492                DexMetadataHelper.validateDexPaths(session.getNames());
2493            } catch (IllegalStateException | IOException e) {
2494                pw.println("Warning [Could not validate the dex paths: " + e.getMessage() + "]");
2495            }
2496
2497            final LocalIntentReceiver receiver = new LocalIntentReceiver();
2498            session.commit(receiver.getIntentSender());
2499
2500            final Intent result = receiver.getResult();
2501            final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2502                    PackageInstaller.STATUS_FAILURE);
2503            if (status == PackageInstaller.STATUS_SUCCESS) {
2504                if (logSuccess) {
2505                    pw.println("Success");
2506                }
2507            } else {
2508                pw.println("Failure ["
2509                        + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
2510            }
2511            return status;
2512        } finally {
2513            IoUtils.closeQuietly(session);
2514        }
2515    }
2516
2517    private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
2518        final PrintWriter pw = getOutPrintWriter();
2519        PackageInstaller.Session session = null;
2520        try {
2521            session = new PackageInstaller.Session(
2522                    mInterface.getPackageInstaller().openSession(sessionId));
2523            session.abandon();
2524            if (logSuccess) {
2525                pw.println("Success");
2526            }
2527            return 0;
2528        } finally {
2529            IoUtils.closeQuietly(session);
2530        }
2531    }
2532
2533    private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2534            boolean summary, int startProtectionLevel, int endProtectionLevel)
2535                    throws RemoteException {
2536        final PrintWriter pw = getOutPrintWriter();
2537        final int groupCount = groupList.size();
2538        for (int i = 0; i < groupCount; i++) {
2539            String groupName = groupList.get(i);
2540            String prefix = "";
2541            if (groups) {
2542                if (i > 0) {
2543                    pw.println("");
2544                }
2545                if (groupName != null) {
2546                    PermissionGroupInfo pgi =
2547                            mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2548                    if (summary) {
2549                        Resources res = getResources(pgi);
2550                        if (res != null) {
2551                            pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2552                        } else {
2553                            pw.print(pgi.name + ": ");
2554
2555                        }
2556                    } else {
2557                        pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2558                        if (labels) {
2559                            pw.println("  package:" + pgi.packageName);
2560                            Resources res = getResources(pgi);
2561                            if (res != null) {
2562                                pw.println("  label:"
2563                                        + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
2564                                pw.println("  description:"
2565                                        + loadText(pgi, pgi.descriptionRes,
2566                                                pgi.nonLocalizedDescription));
2567                            }
2568                        }
2569                    }
2570                } else {
2571                    pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
2572                }
2573                prefix = "  ";
2574            }
2575            List<PermissionInfo> ps =
2576                    mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
2577            final int count = ps.size();
2578            boolean first = true;
2579            for (int p = 0 ; p < count ; p++) {
2580                PermissionInfo pi = ps.get(p);
2581                if (groups && groupName == null && pi.group != null) {
2582                    continue;
2583                }
2584                final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
2585                if (base < startProtectionLevel
2586                        || base > endProtectionLevel) {
2587                    continue;
2588                }
2589                if (summary) {
2590                    if (first) {
2591                        first = false;
2592                    } else {
2593                        pw.print(", ");
2594                    }
2595                    Resources res = getResources(pi);
2596                    if (res != null) {
2597                        pw.print(loadText(pi, pi.labelRes,
2598                                pi.nonLocalizedLabel));
2599                    } else {
2600                        pw.print(pi.name);
2601                    }
2602                } else {
2603                    pw.println(prefix + (labels ? "+ " : "")
2604                            + "permission:" + pi.name);
2605                    if (labels) {
2606                        pw.println(prefix + "  package:" + pi.packageName);
2607                        Resources res = getResources(pi);
2608                        if (res != null) {
2609                            pw.println(prefix + "  label:"
2610                                    + loadText(pi, pi.labelRes,
2611                                            pi.nonLocalizedLabel));
2612                            pw.println(prefix + "  description:"
2613                                    + loadText(pi, pi.descriptionRes,
2614                                            pi.nonLocalizedDescription));
2615                        }
2616                        pw.println(prefix + "  protectionLevel:"
2617                                + PermissionInfo.protectionToString(pi.protectionLevel));
2618                    }
2619                }
2620            }
2621
2622            if (summary) {
2623                pw.println("");
2624            }
2625        }
2626    }
2627
2628    private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
2629            throws RemoteException {
2630        if (nonLocalized != null) {
2631            return nonLocalized.toString();
2632        }
2633        if (res != 0) {
2634            Resources r = getResources(pii);
2635            if (r != null) {
2636                try {
2637                    return r.getString(res);
2638                } catch (Resources.NotFoundException e) {
2639                }
2640            }
2641        }
2642        return null;
2643    }
2644
2645    private Resources getResources(PackageItemInfo pii) throws RemoteException {
2646        Resources res = mResourceCache.get(pii.packageName);
2647        if (res != null) return res;
2648
2649        ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
2650        AssetManager am = new AssetManager();
2651        am.addAssetPath(ai.publicSourceDir);
2652        res = new Resources(am, null, null);
2653        mResourceCache.put(pii.packageName, res);
2654        return res;
2655    }
2656
2657    @Override
2658    public void onHelp() {
2659        final PrintWriter pw = getOutPrintWriter();
2660        pw.println("Package manager (package) commands:");
2661        pw.println("  help");
2662        pw.println("    Print this help text.");
2663        pw.println("");
2664        pw.println("  path [--user USER_ID] PACKAGE");
2665        pw.println("    Print the path to the .apk of the given PACKAGE.");
2666        pw.println("");
2667        pw.println("  dump PACKAGE");
2668        pw.println("    Print various system state associated with the given PACKAGE.");
2669        pw.println("");
2670        pw.println("  list features");
2671        pw.println("    Prints all features of the system.");
2672        pw.println("");
2673        pw.println("  has-feature FEATURE_NAME [version]");
2674        pw.println("    Prints true and returns exit status 0 when system has a FEATURE_NAME,");
2675        pw.println("    otherwise prints false and returns exit status 1");
2676        pw.println("");
2677        pw.println("  list instrumentation [-f] [TARGET-PACKAGE]");
2678        pw.println("    Prints all test packages; optionally only those targeting TARGET-PACKAGE");
2679        pw.println("    Options:");
2680        pw.println("      -f: dump the name of the .apk file containing the test package");
2681        pw.println("");
2682        pw.println("  list libraries");
2683        pw.println("    Prints all system libraries.");
2684        pw.println("");
2685        pw.println("  list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
2686        pw.println("      [--uid UID] [--user USER_ID] [FILTER]");
2687        pw.println("    Prints all packages; optionally only those whose name contains");
2688        pw.println("    the text in FILTER.  Options are:");
2689        pw.println("      -f: see their associated file");
2690        pw.println("      -d: filter to only show disabled packages");
2691        pw.println("      -e: filter to only show enabled packages");
2692        pw.println("      -s: filter to only show system packages");
2693        pw.println("      -3: filter to only show third party packages");
2694        pw.println("      -i: see the installer for the packages");
2695        pw.println("      -l: ignored (used for compatibility with older releases)");
2696        pw.println("      -U: also show the package UID");
2697        pw.println("      -u: also include uninstalled packages");
2698        pw.println("      --uid UID: filter to only show packages with the given UID");
2699        pw.println("      --user USER_ID: only list packages belonging to the given user");
2700        pw.println("");
2701        pw.println("  list permission-groups");
2702        pw.println("    Prints all known permission groups.");
2703        pw.println("");
2704        pw.println("  list permissions [-g] [-f] [-d] [-u] [GROUP]");
2705        pw.println("    Prints all known permissions; optionally only those in GROUP.  Options are:");
2706        pw.println("      -g: organize by group");
2707        pw.println("      -f: print all information");
2708        pw.println("      -s: short summary");
2709        pw.println("      -d: only list dangerous permissions");
2710        pw.println("      -u: list only the permissions users will see");
2711        pw.println("");
2712        pw.println("  resolve-activity [--brief] [--components] [--user USER_ID] INTENT");
2713        pw.println("    Prints the activity that resolves to the given INTENT.");
2714        pw.println("");
2715        pw.println("  query-activities [--brief] [--components] [--user USER_ID] INTENT");
2716        pw.println("    Prints all activities that can handle the given INTENT.");
2717        pw.println("");
2718        pw.println("  query-services [--brief] [--components] [--user USER_ID] INTENT");
2719        pw.println("    Prints all services that can handle the given INTENT.");
2720        pw.println("");
2721        pw.println("  query-receivers [--brief] [--components] [--user USER_ID] INTENT");
2722        pw.println("    Prints all broadcast receivers that can handle the given INTENT.");
2723        pw.println("");
2724        pw.println("  install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2725        pw.println("       [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
2726        pw.println("       [--originating-uri URI] [---referrer URI]");
2727        pw.println("       [--abi ABI_NAME] [--force-sdk]");
2728        pw.println("       [--preload] [--instantapp] [--full] [--dont-kill]");
2729        pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [PATH|-]");
2730        pw.println("    Install an application.  Must provide the apk data to install, either as a");
2731        pw.println("    file path or '-' to read from stdin.  Options are:");
2732        pw.println("      -l: forward lock application");
2733        pw.println("      -R: disallow replacement of existing application");
2734        pw.println("      -t: allow test packages");
2735        pw.println("      -i: specify package name of installer owning the app");
2736        pw.println("      -s: install application on sdcard");
2737        pw.println("      -f: install application on internal flash");
2738        pw.println("      -d: allow version code downgrade (debuggable packages only)");
2739        pw.println("      -p: partial application install (new split on top of existing pkg)");
2740        pw.println("      -g: grant all runtime permissions");
2741        pw.println("      -S: size in bytes of package, required for stdin");
2742        pw.println("      --user: install under the given user.");
2743        pw.println("      --dont-kill: installing a new feature split, don't kill running app");
2744        pw.println("      --originating-uri: set URI where app was downloaded from");
2745        pw.println("      --referrer: set URI that instigated the install of the app");
2746        pw.println("      --pkg: specify expected package name of app being installed");
2747        pw.println("      --abi: override the default ABI of the platform");
2748        pw.println("      --instantapp: cause the app to be installed as an ephemeral install app");
2749        pw.println("      --full: cause the app to be installed as a non-ephemeral full app");
2750        pw.println("      --install-location: force the install location:");
2751        pw.println("          0=auto, 1=internal only, 2=prefer external");
2752        pw.println("      --force-uuid: force install on to disk volume with given UUID");
2753        pw.println("      --force-sdk: allow install even when existing app targets platform");
2754        pw.println("          codename but new one targets a final API level");
2755        pw.println("");
2756        pw.println("  install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2757        pw.println("       [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
2758        pw.println("       [--originating-uri URI] [---referrer URI]");
2759        pw.println("       [--abi ABI_NAME] [--force-sdk]");
2760        pw.println("       [--preload] [--instantapp] [--full] [--dont-kill]");
2761        pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
2762        pw.println("    Like \"install\", but starts an install session.  Use \"install-write\"");
2763        pw.println("    to push data into the session, and \"install-commit\" to finish.");
2764        pw.println("");
2765        pw.println("  install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
2766        pw.println("    Write an apk into the given install session.  If the path is '-', data");
2767        pw.println("    will be read from stdin.  Options are:");
2768        pw.println("      -S: size in bytes of package, required for stdin");
2769        pw.println("");
2770        pw.println("  install-commit SESSION_ID");
2771        pw.println("    Commit the given active install session, installing the app.");
2772        pw.println("");
2773        pw.println("  install-abandon SESSION_ID");
2774        pw.println("    Delete the given active install session.");
2775        pw.println("");
2776        pw.println("  set-install-location LOCATION");
2777        pw.println("    Changes the default install location.  NOTE this is only intended for debugging;");
2778        pw.println("    using this can cause applications to break and other undersireable behavior.");
2779        pw.println("    LOCATION is one of:");
2780        pw.println("    0 [auto]: Let system decide the best location");
2781        pw.println("    1 [internal]: Install on internal device storage");
2782        pw.println("    2 [external]: Install on external media");
2783        pw.println("");
2784        pw.println("  get-install-location");
2785        pw.println("    Returns the current install location: 0, 1 or 2 as per set-install-location.");
2786        pw.println("");
2787        pw.println("  move-package PACKAGE [internal|UUID]");
2788        pw.println("");
2789        pw.println("  move-primary-storage [internal|UUID]");
2790        pw.println("");
2791        pw.println("  pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
2792        pw.println("    Remove the given package name from the system.  May remove an entire app");
2793        pw.println("    if no SPLIT name is specified, otherwise will remove only the split of the");
2794        pw.println("    given app.  Options are:");
2795        pw.println("      -k: keep the data and cache directories around after package removal.");
2796        pw.println("      --user: remove the app from the given user.");
2797        pw.println("      --versionCode: only uninstall if the app has the given version code.");
2798        pw.println("");
2799        pw.println("  clear [--user USER_ID] PACKAGE");
2800        pw.println("    Deletes all data associated with a package.");
2801        pw.println("");
2802        pw.println("  enable [--user USER_ID] PACKAGE_OR_COMPONENT");
2803        pw.println("  disable [--user USER_ID] PACKAGE_OR_COMPONENT");
2804        pw.println("  disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
2805        pw.println("  disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
2806        pw.println("  default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
2807        pw.println("    These commands change the enabled state of a given package or");
2808        pw.println("    component (written as \"package/class\").");
2809        pw.println("");
2810        pw.println("  hide [--user USER_ID] PACKAGE_OR_COMPONENT");
2811        pw.println("  unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
2812        pw.println("");
2813        pw.println("  suspend [--user USER_ID] TARGET-PACKAGE");
2814        pw.println("    Suspends the specified package (as user).");
2815        pw.println("");
2816        pw.println("  unsuspend [--user USER_ID] TARGET-PACKAGE");
2817        pw.println("    Unsuspends the specified package (as user).");
2818        pw.println("");
2819        pw.println("  grant [--user USER_ID] PACKAGE PERMISSION");
2820        pw.println("  revoke [--user USER_ID] PACKAGE PERMISSION");
2821        pw.println("    These commands either grant or revoke permissions to apps.  The permissions");
2822        pw.println("    must be declared as used in the app's manifest, be runtime permissions");
2823        pw.println("    (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
2824        pw.println("");
2825        pw.println("  reset-permissions");
2826        pw.println("    Revert all runtime permissions to their default state.");
2827        pw.println("");
2828        pw.println("  set-permission-enforced PERMISSION [true|false]");
2829        pw.println("");
2830        pw.println("  get-privapp-permissions TARGET-PACKAGE");
2831        pw.println("    Prints all privileged permissions for a package.");
2832        pw.println("");
2833        pw.println("  get-privapp-deny-permissions TARGET-PACKAGE");
2834        pw.println("    Prints all privileged permissions that are denied for a package.");
2835        pw.println("");
2836        pw.println("  get-oem-permissions TARGET-PACKAGE");
2837        pw.println("    Prints all OEM permissions for a package.");
2838        pw.println("");
2839        pw.println("  set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
2840        pw.println("  get-app-link [--user USER_ID] PACKAGE");
2841        pw.println("");
2842        pw.println("  trim-caches DESIRED_FREE_SPACE [internal|UUID]");
2843        pw.println("    Trim cache files to reach the given free space.");
2844        pw.println("");
2845        pw.println("  create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
2846        pw.println("      [--guest] USER_NAME");
2847        pw.println("    Create a new user with the given USER_NAME, printing the new user identifier");
2848        pw.println("    of the user.");
2849        pw.println("");
2850        pw.println("  remove-user USER_ID");
2851        pw.println("    Remove the user with the given USER_IDENTIFIER, deleting all data");
2852        pw.println("    associated with that user");
2853        pw.println("");
2854        pw.println("  set-user-restriction [--user USER_ID] RESTRICTION VALUE");
2855        pw.println("");
2856        pw.println("  get-max-users");
2857        pw.println("");
2858        pw.println("  get-max-running-users");
2859        pw.println("");
2860        pw.println("  compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
2861        pw.println("          [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
2862        pw.println("    Trigger compilation of TARGET-PACKAGE or all packages if \"-a\".  Options are:");
2863        pw.println("      -a: compile all packages");
2864        pw.println("      -c: clear profile data before compiling");
2865        pw.println("      -f: force compilation even if not needed");
2866        pw.println("      -m: select compilation mode");
2867        pw.println("          MODE is one of the dex2oat compiler filters:");
2868        pw.println("            assume-verified");
2869        pw.println("            extract");
2870        pw.println("            verify");
2871        pw.println("            quicken");
2872        pw.println("            space-profile");
2873        pw.println("            space");
2874        pw.println("            speed-profile");
2875        pw.println("            speed");
2876        pw.println("            everything");
2877        pw.println("      -r: select compilation reason");
2878        pw.println("          REASON is one of:");
2879        for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
2880            pw.println("            " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
2881        }
2882        pw.println("      --reset: restore package to its post-install state");
2883        pw.println("      --check-prof (true | false): look at profiles when doing dexopt?");
2884        pw.println("      --secondary-dex: compile app secondary dex files");
2885        pw.println("      --split SPLIT: compile only the given split name");
2886        pw.println("");
2887        pw.println("  force-dex-opt PACKAGE");
2888        pw.println("    Force immediate execution of dex opt for the given PACKAGE.");
2889        pw.println("");
2890        pw.println("  bg-dexopt-job");
2891        pw.println("    Execute the background optimizations immediately.");
2892        pw.println("    Note that the command only runs the background optimizer logic. It may");
2893        pw.println("    overlap with the actual job but the job scheduler will not be able to");
2894        pw.println("    cancel it. It will also run even if the device is not in the idle");
2895        pw.println("    maintenance mode.");
2896        pw.println("");
2897        pw.println("  reconcile-secondary-dex-files TARGET-PACKAGE");
2898        pw.println("    Reconciles the package secondary dex files with the generated oat files.");
2899        pw.println("");
2900        pw.println("  dump-profiles TARGET-PACKAGE");
2901        pw.println("    Dumps method/class profile files to");
2902        pw.println("    " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt");
2903        pw.println("");
2904        pw.println("  snapshot-profile TARGET-PACKAGE [--code-path path]");
2905        pw.println("    Take a snapshot of the package profiles to");
2906        pw.println("    " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
2907                + "TARGET-PACKAGE[-code-path].prof");
2908        pw.println("    If TARGET-PACKAGE=android it will take a snapshot of the boot image");
2909        pw.println("");
2910        pw.println("  set-home-activity [--user USER_ID] TARGET-COMPONENT");
2911        pw.println("    Set the default home activity (aka launcher).");
2912        pw.println("");
2913        pw.println("  set-installer PACKAGE INSTALLER");
2914        pw.println("    Set installer package name");
2915        pw.println("");
2916        pw.println("  get-instantapp-resolver");
2917        pw.println("    Return the name of the component that is the current instant app installer.");
2918        pw.println("");
2919        pw.println("  set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
2920        pw.println("    Mark the app as harmful with the given warning message.");
2921        pw.println("");
2922        pw.println("  get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
2923        pw.println("    Return the harmful app warning message for the given app, if present");
2924        pw.println();
2925        pw.println("  uninstall-system-updates");
2926        pw.println("    Remove updates to all system applications and fall back to their /system " +
2927                "version.");
2928        pw.println();
2929        Intent.printIntentArgsHelp(pw , "");
2930    }
2931
2932    private static class LocalIntentReceiver {
2933        private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
2934
2935        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
2936            @Override
2937            public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
2938                    IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
2939                try {
2940                    mResult.offer(intent, 5, TimeUnit.SECONDS);
2941                } catch (InterruptedException e) {
2942                    throw new RuntimeException(e);
2943                }
2944            }
2945        };
2946
2947        public IntentSender getIntentSender() {
2948            return new IntentSender((IIntentSender) mLocalSender);
2949        }
2950
2951        public Intent getResult() {
2952            try {
2953                return mResult.take();
2954            } catch (InterruptedException e) {
2955                throw new RuntimeException(e);
2956            }
2957        }
2958    }
2959}
2960