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