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