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