Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2007 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 
     17 package com.android.commands.pm;
     18 
     19 import android.app.ActivityManager;
     20 import android.app.ActivityManagerNative;
     21 import android.app.IActivityManager;
     22 import android.app.PackageInstallObserver;
     23 import android.content.ComponentName;
     24 import android.content.IIntentReceiver;
     25 import android.content.IIntentSender;
     26 import android.content.Intent;
     27 import android.content.IntentSender;
     28 import android.content.pm.ApplicationInfo;
     29 import android.content.pm.FeatureInfo;
     30 import android.content.pm.IPackageDataObserver;
     31 import android.content.pm.IPackageInstaller;
     32 import android.content.pm.IPackageManager;
     33 import android.content.pm.InstrumentationInfo;
     34 import android.content.pm.PackageInfo;
     35 import android.content.pm.PackageInstaller;
     36 import android.content.pm.PackageInstaller.SessionInfo;
     37 import android.content.pm.PackageInstaller.SessionParams;
     38 import android.content.pm.PackageItemInfo;
     39 import android.content.pm.PackageManager;
     40 import android.content.pm.ParceledListSlice;
     41 import android.content.pm.PermissionGroupInfo;
     42 import android.content.pm.PermissionInfo;
     43 import android.content.pm.UserInfo;
     44 import android.content.pm.VerificationParams;
     45 import android.content.res.AssetManager;
     46 import android.content.res.Resources;
     47 import android.net.Uri;
     48 import android.os.Build;
     49 import android.os.Bundle;
     50 import android.os.IUserManager;
     51 import android.os.Process;
     52 import android.os.RemoteException;
     53 import android.os.ServiceManager;
     54 import android.os.UserHandle;
     55 import android.os.UserManager;
     56 import android.text.TextUtils;
     57 import android.util.Log;
     58 
     59 import com.android.internal.content.PackageHelper;
     60 import com.android.internal.util.ArrayUtils;
     61 import com.android.internal.util.SizedInputStream;
     62 
     63 import libcore.io.IoUtils;
     64 
     65 import java.io.File;
     66 import java.io.FileDescriptor;
     67 import java.io.FileInputStream;
     68 import java.io.IOException;
     69 import java.io.InputStream;
     70 import java.io.OutputStream;
     71 import java.lang.reflect.Field;
     72 import java.lang.reflect.Modifier;
     73 import java.util.ArrayList;
     74 import java.util.Collections;
     75 import java.util.Comparator;
     76 import java.util.List;
     77 import java.util.WeakHashMap;
     78 import java.util.concurrent.SynchronousQueue;
     79 import java.util.concurrent.TimeUnit;
     80 
     81 public final class Pm {
     82     private static final String TAG = "Pm";
     83 
     84     IPackageManager mPm;
     85     IPackageInstaller mInstaller;
     86     IUserManager mUm;
     87 
     88     private WeakHashMap<String, Resources> mResourceCache
     89             = new WeakHashMap<String, Resources>();
     90 
     91     private String[] mArgs;
     92     private int mNextArg;
     93     private String mCurArgData;
     94 
     95     private static final String PM_NOT_RUNNING_ERR =
     96         "Error: Could not access the Package Manager.  Is the system running?";
     97 
     98     public static void main(String[] args) {
     99         int exitCode = 1;
    100         try {
    101             exitCode = new Pm().run(args);
    102         } catch (Exception e) {
    103             Log.e(TAG, "Error", e);
    104             System.err.println("Error: " + e);
    105             if (e instanceof RemoteException) {
    106                 System.err.println(PM_NOT_RUNNING_ERR);
    107             }
    108         }
    109         System.exit(exitCode);
    110     }
    111 
    112     public int run(String[] args) throws IOException, RemoteException {
    113         boolean validCommand = false;
    114         if (args.length < 1) {
    115             return showUsage();
    116         }
    117 
    118         mUm = IUserManager.Stub.asInterface(ServiceManager.getService("user"));
    119         mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
    120         if (mPm == null) {
    121             System.err.println(PM_NOT_RUNNING_ERR);
    122             return 1;
    123         }
    124         mInstaller = mPm.getPackageInstaller();
    125 
    126         mArgs = args;
    127         String op = args[0];
    128         mNextArg = 1;
    129 
    130         if ("list".equals(op)) {
    131             return runList();
    132         }
    133 
    134         if ("path".equals(op)) {
    135             return runPath();
    136         }
    137 
    138         if ("dump".equals(op)) {
    139             return runDump();
    140         }
    141 
    142         if ("install".equals(op)) {
    143             return runInstall();
    144         }
    145 
    146         if ("install-create".equals(op)) {
    147             return runInstallCreate();
    148         }
    149 
    150         if ("install-write".equals(op)) {
    151             return runInstallWrite();
    152         }
    153 
    154         if ("install-commit".equals(op)) {
    155             return runInstallCommit();
    156         }
    157 
    158         if ("install-abandon".equals(op) || "install-destroy".equals(op)) {
    159             return runInstallAbandon();
    160         }
    161 
    162         if ("set-installer".equals(op)) {
    163             return runSetInstaller();
    164         }
    165 
    166         if ("uninstall".equals(op)) {
    167             return runUninstall();
    168         }
    169 
    170         if ("clear".equals(op)) {
    171             return runClear();
    172         }
    173 
    174         if ("enable".equals(op)) {
    175             return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
    176         }
    177 
    178         if ("disable".equals(op)) {
    179             return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
    180         }
    181 
    182         if ("disable-user".equals(op)) {
    183             return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
    184         }
    185 
    186         if ("disable-until-used".equals(op)) {
    187             return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
    188         }
    189 
    190         if ("hide".equals(op)) {
    191             return runSetHiddenSetting(true);
    192         }
    193 
    194         if ("unhide".equals(op)) {
    195             return runSetHiddenSetting(false);
    196         }
    197 
    198         if ("grant".equals(op)) {
    199             return runGrantRevokePermission(true);
    200         }
    201 
    202         if ("revoke".equals(op)) {
    203             return runGrantRevokePermission(false);
    204         }
    205 
    206         if ("set-permission-enforced".equals(op)) {
    207             return runSetPermissionEnforced();
    208         }
    209 
    210         if ("set-install-location".equals(op)) {
    211             return runSetInstallLocation();
    212         }
    213 
    214         if ("get-install-location".equals(op)) {
    215             return runGetInstallLocation();
    216         }
    217 
    218         if ("trim-caches".equals(op)) {
    219             return runTrimCaches();
    220         }
    221 
    222         if ("create-user".equals(op)) {
    223             return runCreateUser();
    224         }
    225 
    226         if ("remove-user".equals(op)) {
    227             return runRemoveUser();
    228         }
    229 
    230         if ("get-max-users".equals(op)) {
    231             return runGetMaxUsers();
    232         }
    233 
    234         if ("force-dex-opt".equals(op)) {
    235             return runForceDexOpt();
    236         }
    237 
    238         try {
    239             if (args.length == 1) {
    240                 if (args[0].equalsIgnoreCase("-l")) {
    241                     validCommand = true;
    242                     return runListPackages(false);
    243                 } else if (args[0].equalsIgnoreCase("-lf")){
    244                     validCommand = true;
    245                     return runListPackages(true);
    246                 }
    247             } else if (args.length == 2) {
    248                 if (args[0].equalsIgnoreCase("-p")) {
    249                     validCommand = true;
    250                     return displayPackageFilePath(args[1]);
    251                 }
    252             }
    253             return 1;
    254         } finally {
    255             if (validCommand == false) {
    256                 if (op != null) {
    257                     System.err.println("Error: unknown command '" + op + "'");
    258                 }
    259                 showUsage();
    260             }
    261         }
    262     }
    263 
    264     /**
    265      * Execute the list sub-command.
    266      *
    267      * pm list [package | packages]
    268      * pm list permission-groups
    269      * pm list permissions
    270      * pm list features
    271      * pm list libraries
    272      * pm list instrumentation
    273      */
    274     private int runList() {
    275         String type = nextArg();
    276         if (type == null) {
    277             System.err.println("Error: didn't specify type of data to list");
    278             return 1;
    279         }
    280         if ("package".equals(type) || "packages".equals(type)) {
    281             return runListPackages(false);
    282         } else if ("permission-groups".equals(type)) {
    283             return runListPermissionGroups();
    284         } else if ("permissions".equals(type)) {
    285             return runListPermissions();
    286         } else if ("features".equals(type)) {
    287             return runListFeatures();
    288         } else if ("libraries".equals(type)) {
    289             return runListLibraries();
    290         } else if ("instrumentation".equals(type)) {
    291             return runListInstrumentation();
    292         } else if ("users".equals(type)) {
    293             return runListUsers();
    294         } else {
    295             System.err.println("Error: unknown list type '" + type + "'");
    296             return 1;
    297         }
    298     }
    299 
    300     /**
    301      * Lists all the installed packages.
    302      */
    303     private int runListPackages(boolean showApplicationPackage) {
    304         int getFlags = 0;
    305         boolean listDisabled = false, listEnabled = false;
    306         boolean listSystem = false, listThirdParty = false;
    307         boolean listInstaller = false;
    308         int userId = UserHandle.USER_OWNER;
    309         try {
    310             String opt;
    311             while ((opt=nextOption()) != null) {
    312                 if (opt.equals("-l")) {
    313                     // old compat
    314                 } else if (opt.equals("-lf")) {
    315                     showApplicationPackage = true;
    316                 } else if (opt.equals("-f")) {
    317                     showApplicationPackage = true;
    318                 } else if (opt.equals("-d")) {
    319                     listDisabled = true;
    320                 } else if (opt.equals("-e")) {
    321                     listEnabled = true;
    322                 } else if (opt.equals("-s")) {
    323                     listSystem = true;
    324                 } else if (opt.equals("-3")) {
    325                     listThirdParty = true;
    326                 } else if (opt.equals("-i")) {
    327                     listInstaller = true;
    328                 } else if (opt.equals("--user")) {
    329                     userId = Integer.parseInt(nextArg());
    330                 } else if (opt.equals("-u")) {
    331                     getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
    332                 } else {
    333                     System.err.println("Error: Unknown option: " + opt);
    334                     return 1;
    335                 }
    336             }
    337         } catch (RuntimeException ex) {
    338             System.err.println("Error: " + ex.toString());
    339             return 1;
    340         }
    341 
    342         String filter = nextArg();
    343 
    344         try {
    345             final List<PackageInfo> packages = getInstalledPackages(mPm, getFlags, userId);
    346 
    347             int count = packages.size();
    348             for (int p = 0 ; p < count ; p++) {
    349                 PackageInfo info = packages.get(p);
    350                 if (filter != null && !info.packageName.contains(filter)) {
    351                     continue;
    352                 }
    353                 final boolean isSystem =
    354                         (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
    355                 if ((!listDisabled || !info.applicationInfo.enabled) &&
    356                         (!listEnabled || info.applicationInfo.enabled) &&
    357                         (!listSystem || isSystem) &&
    358                         (!listThirdParty || !isSystem)) {
    359                     System.out.print("package:");
    360                     if (showApplicationPackage) {
    361                         System.out.print(info.applicationInfo.sourceDir);
    362                         System.out.print("=");
    363                     }
    364                     System.out.print(info.packageName);
    365                     if (listInstaller) {
    366                         System.out.print("  installer=");
    367                         System.out.print(mPm.getInstallerPackageName(info.packageName));
    368                     }
    369                     System.out.println();
    370                 }
    371             }
    372             return 0;
    373         } catch (RemoteException e) {
    374             System.err.println(e.toString());
    375             System.err.println(PM_NOT_RUNNING_ERR);
    376             return 1;
    377         }
    378     }
    379 
    380     @SuppressWarnings("unchecked")
    381     private List<PackageInfo> getInstalledPackages(IPackageManager pm, int flags, int userId)
    382             throws RemoteException {
    383         ParceledListSlice<PackageInfo> slice = pm.getInstalledPackages(flags, userId);
    384         return slice.getList();
    385     }
    386 
    387     /**
    388      * Lists all of the features supported by the current device.
    389      *
    390      * pm list features
    391      */
    392     private int runListFeatures() {
    393         try {
    394             List<FeatureInfo> list = new ArrayList<FeatureInfo>();
    395             FeatureInfo[] rawList = mPm.getSystemAvailableFeatures();
    396             for (int i=0; i<rawList.length; i++) {
    397                 list.add(rawList[i]);
    398             }
    399 
    400 
    401             // Sort by name
    402             Collections.sort(list, new Comparator<FeatureInfo>() {
    403                 public int compare(FeatureInfo o1, FeatureInfo o2) {
    404                     if (o1.name == o2.name) return 0;
    405                     if (o1.name == null) return -1;
    406                     if (o2.name == null) return 1;
    407                     return o1.name.compareTo(o2.name);
    408                 }
    409             });
    410 
    411             int count = (list != null) ? list.size() : 0;
    412             for (int p = 0; p < count; p++) {
    413                 FeatureInfo fi = list.get(p);
    414                 System.out.print("feature:");
    415                 if (fi.name != null) System.out.println(fi.name);
    416                 else System.out.println("reqGlEsVersion=0x"
    417                         + Integer.toHexString(fi.reqGlEsVersion));
    418             }
    419             return 0;
    420         } catch (RemoteException e) {
    421             System.err.println(e.toString());
    422             System.err.println(PM_NOT_RUNNING_ERR);
    423             return 1;
    424         }
    425     }
    426 
    427     /**
    428      * Lists all of the libraries supported by the current device.
    429      *
    430      * pm list libraries
    431      */
    432     private int runListLibraries() {
    433         try {
    434             List<String> list = new ArrayList<String>();
    435             String[] rawList = mPm.getSystemSharedLibraryNames();
    436             for (int i=0; i<rawList.length; i++) {
    437                 list.add(rawList[i]);
    438             }
    439 
    440 
    441             // Sort by name
    442             Collections.sort(list, new Comparator<String>() {
    443                 public int compare(String o1, String o2) {
    444                     if (o1 == o2) return 0;
    445                     if (o1 == null) return -1;
    446                     if (o2 == null) return 1;
    447                     return o1.compareTo(o2);
    448                 }
    449             });
    450 
    451             int count = (list != null) ? list.size() : 0;
    452             for (int p = 0; p < count; p++) {
    453                 String lib = list.get(p);
    454                 System.out.print("library:");
    455                 System.out.println(lib);
    456             }
    457             return 0;
    458         } catch (RemoteException e) {
    459             System.err.println(e.toString());
    460             System.err.println(PM_NOT_RUNNING_ERR);
    461             return 1;
    462         }
    463     }
    464 
    465     /**
    466      * Lists all of the installed instrumentation, or all for a given package
    467      *
    468      * pm list instrumentation [package] [-f]
    469      */
    470     private int runListInstrumentation() {
    471         int flags = 0;      // flags != 0 is only used to request meta-data
    472         boolean showPackage = false;
    473         String targetPackage = null;
    474 
    475         try {
    476             String opt;
    477             while ((opt=nextArg()) != null) {
    478                 if (opt.equals("-f")) {
    479                     showPackage = true;
    480                 } else if (opt.charAt(0) != '-') {
    481                     targetPackage = opt;
    482                 } else {
    483                     System.err.println("Error: Unknown option: " + opt);
    484                     return 1;
    485                 }
    486             }
    487         } catch (RuntimeException ex) {
    488             System.err.println("Error: " + ex.toString());
    489             return 1;
    490         }
    491 
    492         try {
    493             List<InstrumentationInfo> list = mPm.queryInstrumentation(targetPackage, flags);
    494 
    495             // Sort by target package
    496             Collections.sort(list, new Comparator<InstrumentationInfo>() {
    497                 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
    498                     return o1.targetPackage.compareTo(o2.targetPackage);
    499                 }
    500             });
    501 
    502             int count = (list != null) ? list.size() : 0;
    503             for (int p = 0; p < count; p++) {
    504                 InstrumentationInfo ii = list.get(p);
    505                 System.out.print("instrumentation:");
    506                 if (showPackage) {
    507                     System.out.print(ii.sourceDir);
    508                     System.out.print("=");
    509                 }
    510                 ComponentName cn = new ComponentName(ii.packageName, ii.name);
    511                 System.out.print(cn.flattenToShortString());
    512                 System.out.print(" (target=");
    513                 System.out.print(ii.targetPackage);
    514                 System.out.println(")");
    515             }
    516             return 0;
    517         } catch (RemoteException e) {
    518             System.err.println(e.toString());
    519             System.err.println(PM_NOT_RUNNING_ERR);
    520             return 1;
    521         }
    522     }
    523 
    524     /**
    525      * Lists all the known permission groups.
    526      */
    527     private int runListPermissionGroups() {
    528         try {
    529             List<PermissionGroupInfo> pgs = mPm.getAllPermissionGroups(0);
    530 
    531             int count = pgs.size();
    532             for (int p = 0 ; p < count ; p++) {
    533                 PermissionGroupInfo pgi = pgs.get(p);
    534                 System.out.print("permission group:");
    535                 System.out.println(pgi.name);
    536             }
    537             return 0;
    538         } catch (RemoteException e) {
    539             System.err.println(e.toString());
    540             System.err.println(PM_NOT_RUNNING_ERR);
    541             return 1;
    542         }
    543     }
    544 
    545     private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) {
    546         if (nonLocalized != null) {
    547             return nonLocalized.toString();
    548         }
    549         if (res != 0) {
    550             Resources r = getResources(pii);
    551             if (r != null) {
    552                 return r.getString(res);
    553             }
    554         }
    555         return null;
    556     }
    557 
    558     /**
    559      * Lists all the permissions in a group.
    560      */
    561     private int runListPermissions() {
    562         try {
    563             boolean labels = false;
    564             boolean groups = false;
    565             boolean userOnly = false;
    566             boolean summary = false;
    567             boolean dangerousOnly = false;
    568             String opt;
    569             while ((opt=nextOption()) != null) {
    570                 if (opt.equals("-f")) {
    571                     labels = true;
    572                 } else if (opt.equals("-g")) {
    573                     groups = true;
    574                 } else if (opt.equals("-s")) {
    575                     groups = true;
    576                     labels = true;
    577                     summary = true;
    578                 } else if (opt.equals("-u")) {
    579                     userOnly = true;
    580                 } else if (opt.equals("-d")) {
    581                     dangerousOnly = true;
    582                 } else {
    583                     System.err.println("Error: Unknown option: " + opt);
    584                     return 1;
    585                 }
    586             }
    587 
    588             String grp = nextOption();
    589             ArrayList<String> groupList = new ArrayList<String>();
    590             if (groups) {
    591                 List<PermissionGroupInfo> infos =
    592                         mPm.getAllPermissionGroups(0);
    593                 for (int i=0; i<infos.size(); i++) {
    594                     groupList.add(infos.get(i).name);
    595                 }
    596                 groupList.add(null);
    597             } else {
    598                 groupList.add(grp);
    599             }
    600 
    601             if (dangerousOnly) {
    602                 System.out.println("Dangerous Permissions:");
    603                 System.out.println("");
    604                 doListPermissions(groupList, groups, labels, summary,
    605                         PermissionInfo.PROTECTION_DANGEROUS,
    606                         PermissionInfo.PROTECTION_DANGEROUS);
    607                 if (userOnly) {
    608                     System.out.println("Normal Permissions:");
    609                     System.out.println("");
    610                     doListPermissions(groupList, groups, labels, summary,
    611                             PermissionInfo.PROTECTION_NORMAL,
    612                             PermissionInfo.PROTECTION_NORMAL);
    613                 }
    614             } else if (userOnly) {
    615                 System.out.println("Dangerous and Normal Permissions:");
    616                 System.out.println("");
    617                 doListPermissions(groupList, groups, labels, summary,
    618                         PermissionInfo.PROTECTION_NORMAL,
    619                         PermissionInfo.PROTECTION_DANGEROUS);
    620             } else {
    621                 System.out.println("All Permissions:");
    622                 System.out.println("");
    623                 doListPermissions(groupList, groups, labels, summary,
    624                         -10000, 10000);
    625             }
    626             return 0;
    627         } catch (RemoteException e) {
    628             System.err.println(e.toString());
    629             System.err.println(PM_NOT_RUNNING_ERR);
    630             return 1;
    631         }
    632     }
    633 
    634     private void doListPermissions(ArrayList<String> groupList,
    635             boolean groups, boolean labels, boolean summary,
    636             int startProtectionLevel, int endProtectionLevel)
    637             throws RemoteException {
    638         for (int i=0; i<groupList.size(); i++) {
    639             String groupName = groupList.get(i);
    640             String prefix = "";
    641             if (groups) {
    642                 if (i > 0) System.out.println("");
    643                 if (groupName != null) {
    644                     PermissionGroupInfo pgi = mPm.getPermissionGroupInfo(
    645                             groupName, 0);
    646                     if (summary) {
    647                         Resources res = getResources(pgi);
    648                         if (res != null) {
    649                             System.out.print(loadText(pgi, pgi.labelRes,
    650                                     pgi.nonLocalizedLabel) + ": ");
    651                         } else {
    652                             System.out.print(pgi.name + ": ");
    653 
    654                         }
    655                     } else {
    656                         System.out.println((labels ? "+ " : "")
    657                                 + "group:" + pgi.name);
    658                         if (labels) {
    659                             System.out.println("  package:" + pgi.packageName);
    660                             Resources res = getResources(pgi);
    661                             if (res != null) {
    662                                 System.out.println("  label:"
    663                                         + loadText(pgi, pgi.labelRes,
    664                                                 pgi.nonLocalizedLabel));
    665                                 System.out.println("  description:"
    666                                         + loadText(pgi, pgi.descriptionRes,
    667                                                 pgi.nonLocalizedDescription));
    668                             }
    669                         }
    670                     }
    671                 } else {
    672                     System.out.println(((labels && !summary)
    673                             ? "+ " : "") + "ungrouped:");
    674                 }
    675                 prefix = "  ";
    676             }
    677             List<PermissionInfo> ps = mPm.queryPermissionsByGroup(
    678                     groupList.get(i), 0);
    679             int count = ps.size();
    680             boolean first = true;
    681             for (int p = 0 ; p < count ; p++) {
    682                 PermissionInfo pi = ps.get(p);
    683                 if (groups && groupName == null && pi.group != null) {
    684                     continue;
    685                 }
    686                 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
    687                 if (base < startProtectionLevel
    688                         || base > endProtectionLevel) {
    689                     continue;
    690                 }
    691                 if (summary) {
    692                     if (first) {
    693                         first = false;
    694                     } else {
    695                         System.out.print(", ");
    696                     }
    697                     Resources res = getResources(pi);
    698                     if (res != null) {
    699                         System.out.print(loadText(pi, pi.labelRes,
    700                                 pi.nonLocalizedLabel));
    701                     } else {
    702                         System.out.print(pi.name);
    703                     }
    704                 } else {
    705                     System.out.println(prefix + (labels ? "+ " : "")
    706                             + "permission:" + pi.name);
    707                     if (labels) {
    708                         System.out.println(prefix + "  package:" + pi.packageName);
    709                         Resources res = getResources(pi);
    710                         if (res != null) {
    711                             System.out.println(prefix + "  label:"
    712                                     + loadText(pi, pi.labelRes,
    713                                             pi.nonLocalizedLabel));
    714                             System.out.println(prefix + "  description:"
    715                                     + loadText(pi, pi.descriptionRes,
    716                                             pi.nonLocalizedDescription));
    717                         }
    718                         System.out.println(prefix + "  protectionLevel:"
    719                                 + PermissionInfo.protectionToString(pi.protectionLevel));
    720                     }
    721                 }
    722             }
    723 
    724             if (summary) {
    725                 System.out.println("");
    726             }
    727         }
    728     }
    729 
    730     private int runPath() {
    731         String pkg = nextArg();
    732         if (pkg == null) {
    733             System.err.println("Error: no package specified");
    734             return 1;
    735         }
    736         return displayPackageFilePath(pkg);
    737     }
    738 
    739     private int runDump() {
    740         String pkg = nextArg();
    741         if (pkg == null) {
    742             System.err.println("Error: no package specified");
    743             return 1;
    744         }
    745         ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg);
    746         return 0;
    747     }
    748 
    749     class LocalPackageInstallObserver extends PackageInstallObserver {
    750         boolean finished;
    751         int result;
    752         String extraPermission;
    753         String extraPackage;
    754 
    755         @Override
    756         public void onPackageInstalled(String name, int status, String msg, Bundle extras) {
    757             synchronized (this) {
    758                 finished = true;
    759                 result = status;
    760                 if (status == PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION) {
    761                     extraPermission = extras.getString(
    762                             PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION);
    763                     extraPackage = extras.getString(
    764                             PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE);
    765                 }
    766                 notifyAll();
    767             }
    768         }
    769     }
    770 
    771     /**
    772      * Converts a failure code into a string by using reflection to find a matching constant
    773      * in PackageManager.
    774      */
    775     private String installFailureToString(LocalPackageInstallObserver obs) {
    776         final int result = obs.result;
    777         Field[] fields = PackageManager.class.getFields();
    778         for (Field f: fields) {
    779             if (f.getType() == int.class) {
    780                 int modifiers = f.getModifiers();
    781                 // only look at public final static fields.
    782                 if (((modifiers & Modifier.FINAL) != 0) &&
    783                         ((modifiers & Modifier.PUBLIC) != 0) &&
    784                         ((modifiers & Modifier.STATIC) != 0)) {
    785                     String fieldName = f.getName();
    786                     if (fieldName.startsWith("INSTALL_FAILED_") ||
    787                             fieldName.startsWith("INSTALL_PARSE_FAILED_")) {
    788                         // get the int value and compare it to result.
    789                         try {
    790                             if (result == f.getInt(null)) {
    791                                 StringBuilder sb = new StringBuilder(64);
    792                                 sb.append(fieldName);
    793                                 if (obs.extraPermission != null) {
    794                                     sb.append(" perm=");
    795                                     sb.append(obs.extraPermission);
    796                                 }
    797                                 if (obs.extraPackage != null) {
    798                                     sb.append(" pkg=" + obs.extraPackage);
    799                                 }
    800                                 return sb.toString();
    801                             }
    802                         } catch (IllegalAccessException e) {
    803                             // this shouldn't happen since we only look for public static fields.
    804                         }
    805                     }
    806                 }
    807             }
    808         }
    809 
    810         // couldn't find a matching constant? return the value
    811         return Integer.toString(result);
    812     }
    813 
    814     private int runSetInstallLocation() {
    815         int loc;
    816 
    817         String arg = nextArg();
    818         if (arg == null) {
    819             System.err.println("Error: no install location specified.");
    820             return 1;
    821         }
    822         try {
    823             loc = Integer.parseInt(arg);
    824         } catch (NumberFormatException e) {
    825             System.err.println("Error: install location has to be a number.");
    826             return 1;
    827         }
    828         try {
    829             if (!mPm.setInstallLocation(loc)) {
    830                 System.err.println("Error: install location has to be a number.");
    831                 return 1;
    832             }
    833             return 0;
    834         } catch (RemoteException e) {
    835             System.err.println(e.toString());
    836             System.err.println(PM_NOT_RUNNING_ERR);
    837             return 1;
    838         }
    839     }
    840 
    841     private int runGetInstallLocation() {
    842         try {
    843             int loc = mPm.getInstallLocation();
    844             String locStr = "invalid";
    845             if (loc == PackageHelper.APP_INSTALL_AUTO) {
    846                 locStr = "auto";
    847             } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
    848                 locStr = "internal";
    849             } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
    850                 locStr = "external";
    851             }
    852             System.out.println(loc + "[" + locStr + "]");
    853             return 0;
    854         } catch (RemoteException e) {
    855             System.err.println(e.toString());
    856             System.err.println(PM_NOT_RUNNING_ERR);
    857             return 1;
    858         }
    859     }
    860 
    861     private int runInstall() {
    862         int installFlags = 0;
    863         int userId = UserHandle.USER_ALL;
    864         String installerPackageName = null;
    865 
    866         String opt;
    867 
    868         String originatingUriString = null;
    869         String referrer = null;
    870         String abi = null;
    871 
    872         while ((opt=nextOption()) != null) {
    873             if (opt.equals("-l")) {
    874                 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
    875             } else if (opt.equals("-r")) {
    876                 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
    877             } else if (opt.equals("-i")) {
    878                 installerPackageName = nextOptionData();
    879                 if (installerPackageName == null) {
    880                     System.err.println("Error: no value specified for -i");
    881                     return 1;
    882                 }
    883             } else if (opt.equals("-t")) {
    884                 installFlags |= PackageManager.INSTALL_ALLOW_TEST;
    885             } else if (opt.equals("-s")) {
    886                 // Override if -s option is specified.
    887                 installFlags |= PackageManager.INSTALL_EXTERNAL;
    888             } else if (opt.equals("-f")) {
    889                 // Override if -s option is specified.
    890                 installFlags |= PackageManager.INSTALL_INTERNAL;
    891             } else if (opt.equals("-d")) {
    892                 installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
    893             } else if (opt.equals("--originating-uri")) {
    894                 originatingUriString = nextOptionData();
    895                 if (originatingUriString == null) {
    896                     System.err.println("Error: must supply argument for --originating-uri");
    897                     return 1;
    898                 }
    899             } else if (opt.equals("--referrer")) {
    900                 referrer = nextOptionData();
    901                 if (referrer == null) {
    902                     System.err.println("Error: must supply argument for --referrer");
    903                     return 1;
    904                 }
    905             } else if (opt.equals("--abi")) {
    906                 abi = checkAbiArgument(nextOptionData());
    907             } else if (opt.equals("--user")) {
    908                 userId = Integer.parseInt(nextOptionData());
    909             } else {
    910                 System.err.println("Error: Unknown option: " + opt);
    911                 return 1;
    912             }
    913         }
    914 
    915         if (userId == UserHandle.USER_ALL) {
    916             userId = UserHandle.USER_OWNER;
    917             installFlags |= PackageManager.INSTALL_ALL_USERS;
    918         }
    919 
    920         final Uri verificationURI;
    921         final Uri originatingURI;
    922         final Uri referrerURI;
    923 
    924         if (originatingUriString != null) {
    925             originatingURI = Uri.parse(originatingUriString);
    926         } else {
    927             originatingURI = null;
    928         }
    929 
    930         if (referrer != null) {
    931             referrerURI = Uri.parse(referrer);
    932         } else {
    933             referrerURI = null;
    934         }
    935 
    936         // Populate apkURI, must be present
    937         final String apkFilePath = nextArg();
    938         System.err.println("\tpkg: " + apkFilePath);
    939         if (apkFilePath == null) {
    940             System.err.println("Error: no package specified");
    941             return 1;
    942         }
    943 
    944         // Populate verificationURI, optionally present
    945         final String verificationFilePath = nextArg();
    946         if (verificationFilePath != null) {
    947             System.err.println("\tver: " + verificationFilePath);
    948             verificationURI = Uri.fromFile(new File(verificationFilePath));
    949         } else {
    950             verificationURI = null;
    951         }
    952 
    953         LocalPackageInstallObserver obs = new LocalPackageInstallObserver();
    954         try {
    955             VerificationParams verificationParams = new VerificationParams(verificationURI,
    956                     originatingURI, referrerURI, VerificationParams.NO_UID, null);
    957 
    958             mPm.installPackageAsUser(apkFilePath, obs.getBinder(), installFlags,
    959                     installerPackageName, verificationParams, abi, userId);
    960 
    961             synchronized (obs) {
    962                 while (!obs.finished) {
    963                     try {
    964                         obs.wait();
    965                     } catch (InterruptedException e) {
    966                     }
    967                 }
    968                 if (obs.result == PackageManager.INSTALL_SUCCEEDED) {
    969                     System.out.println("Success");
    970                     return 0;
    971                 } else {
    972                     System.err.println("Failure ["
    973                             + installFailureToString(obs)
    974                             + "]");
    975                     return 1;
    976                 }
    977             }
    978         } catch (RemoteException e) {
    979             System.err.println(e.toString());
    980             System.err.println(PM_NOT_RUNNING_ERR);
    981             return 1;
    982         }
    983     }
    984 
    985     private int runInstallCreate() throws RemoteException {
    986         int userId = UserHandle.USER_ALL;
    987         String installerPackageName = null;
    988 
    989         final SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
    990 
    991         String opt;
    992         while ((opt = nextOption()) != null) {
    993             if (opt.equals("-l")) {
    994                 params.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
    995             } else if (opt.equals("-r")) {
    996                 params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
    997             } else if (opt.equals("-i")) {
    998                 installerPackageName = nextArg();
    999                 if (installerPackageName == null) {
   1000                     throw new IllegalArgumentException("Missing installer package");
   1001                 }
   1002             } else if (opt.equals("-t")) {
   1003                 params.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
   1004             } else if (opt.equals("-s")) {
   1005                 params.installFlags |= PackageManager.INSTALL_EXTERNAL;
   1006             } else if (opt.equals("-f")) {
   1007                 params.installFlags |= PackageManager.INSTALL_INTERNAL;
   1008             } else if (opt.equals("-d")) {
   1009                 params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
   1010             } else if (opt.equals("--originating-uri")) {
   1011                 params.originatingUri = Uri.parse(nextOptionData());
   1012             } else if (opt.equals("--referrer")) {
   1013                 params.referrerUri = Uri.parse(nextOptionData());
   1014             } else if (opt.equals("-p")) {
   1015                 params.mode = SessionParams.MODE_INHERIT_EXISTING;
   1016                 params.appPackageName = nextOptionData();
   1017                 if (params.appPackageName == null) {
   1018                     throw new IllegalArgumentException("Missing inherit package name");
   1019                 }
   1020             } else if (opt.equals("-S")) {
   1021                 params.setSize(Long.parseLong(nextOptionData()));
   1022             } else if (opt.equals("--abi")) {
   1023                 params.abiOverride = checkAbiArgument(nextOptionData());
   1024             } else if (opt.equals("--user")) {
   1025                 userId = Integer.parseInt(nextOptionData());
   1026             } else {
   1027                 throw new IllegalArgumentException("Unknown option " + opt);
   1028             }
   1029         }
   1030 
   1031         if (userId == UserHandle.USER_ALL) {
   1032             userId = UserHandle.USER_OWNER;
   1033             params.installFlags |= PackageManager.INSTALL_ALL_USERS;
   1034         }
   1035 
   1036         final int sessionId = mInstaller.createSession(params, installerPackageName, userId);
   1037 
   1038         // NOTE: adb depends on parsing this string
   1039         System.out.println("Success: created install session [" + sessionId + "]");
   1040         return 0;
   1041     }
   1042 
   1043     private int runInstallWrite() throws IOException, RemoteException {
   1044         long sizeBytes = -1;
   1045 
   1046         String opt;
   1047         while ((opt = nextOption()) != null) {
   1048             if (opt.equals("-S")) {
   1049                 sizeBytes = Long.parseLong(nextOptionData());
   1050             } else {
   1051                 throw new IllegalArgumentException("Unknown option: " + opt);
   1052             }
   1053         }
   1054 
   1055         final int sessionId = Integer.parseInt(nextArg());
   1056         final String splitName = nextArg();
   1057 
   1058         String path = nextArg();
   1059         if ("-".equals(path)) {
   1060             path = null;
   1061         } else if (path != null) {
   1062             final File file = new File(path);
   1063             if (file.isFile()) {
   1064                 sizeBytes = file.length();
   1065             }
   1066         }
   1067 
   1068         final SessionInfo info = mInstaller.getSessionInfo(sessionId);
   1069 
   1070         PackageInstaller.Session session = null;
   1071         InputStream in = null;
   1072         OutputStream out = null;
   1073         try {
   1074             session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
   1075 
   1076             if (path != null) {
   1077                 in = new FileInputStream(path);
   1078             } else {
   1079                 in = new SizedInputStream(System.in, sizeBytes);
   1080             }
   1081             out = session.openWrite(splitName, 0, sizeBytes);
   1082 
   1083             int total = 0;
   1084             byte[] buffer = new byte[65536];
   1085             int c;
   1086             while ((c = in.read(buffer)) != -1) {
   1087                 total += c;
   1088                 out.write(buffer, 0, c);
   1089 
   1090                 if (info.sizeBytes > 0) {
   1091                     final float fraction = ((float) c / (float) info.sizeBytes);
   1092                     session.addProgress(fraction);
   1093                 }
   1094             }
   1095             session.fsync(out);
   1096 
   1097             System.out.println("Success: streamed " + total + " bytes");
   1098             return 0;
   1099         } finally {
   1100             IoUtils.closeQuietly(out);
   1101             IoUtils.closeQuietly(in);
   1102             IoUtils.closeQuietly(session);
   1103         }
   1104     }
   1105 
   1106     private int runInstallCommit() throws RemoteException {
   1107         final int sessionId = Integer.parseInt(nextArg());
   1108 
   1109         PackageInstaller.Session session = null;
   1110         try {
   1111             session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
   1112 
   1113             final LocalIntentReceiver receiver = new LocalIntentReceiver();
   1114             session.commit(receiver.getIntentSender());
   1115 
   1116             final Intent result = receiver.getResult();
   1117             final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
   1118                     PackageInstaller.STATUS_FAILURE);
   1119             if (status == PackageInstaller.STATUS_SUCCESS) {
   1120                 System.out.println("Success");
   1121                 return 0;
   1122             } else {
   1123                 Log.e(TAG, "Failure details: " + result.getExtras());
   1124                 System.err.println("Failure ["
   1125                         + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
   1126                 return 1;
   1127             }
   1128         } finally {
   1129             IoUtils.closeQuietly(session);
   1130         }
   1131     }
   1132 
   1133     private int runInstallAbandon() throws RemoteException {
   1134         final int sessionId = Integer.parseInt(nextArg());
   1135 
   1136         PackageInstaller.Session session = null;
   1137         try {
   1138             session = new PackageInstaller.Session(mInstaller.openSession(sessionId));
   1139             session.abandon();
   1140             System.out.println("Success");
   1141             return 0;
   1142         } finally {
   1143             IoUtils.closeQuietly(session);
   1144         }
   1145     }
   1146 
   1147     private int runSetInstaller() throws RemoteException {
   1148         final String targetPackage = nextArg();
   1149         final String installerPackageName = nextArg();
   1150 
   1151         if (targetPackage == null || installerPackageName == null) {
   1152             throw new IllegalArgumentException(
   1153                     "must provide both target and installer package names");
   1154         }
   1155 
   1156         mPm.setInstallerPackageName(targetPackage, installerPackageName);
   1157         System.out.println("Success");
   1158         return 0;
   1159     }
   1160 
   1161     public int runCreateUser() {
   1162         String name;
   1163         int userId = -1;
   1164         int flags = 0;
   1165         String opt;
   1166         while ((opt = nextOption()) != null) {
   1167             if ("--profileOf".equals(opt)) {
   1168                 String optionData = nextOptionData();
   1169                 if (optionData == null || !isNumber(optionData)) {
   1170                     System.err.println("Error: no USER_ID specified");
   1171                     showUsage();
   1172                     return 1;
   1173                 } else {
   1174                     userId = Integer.parseInt(optionData);
   1175                 }
   1176             } else if ("--managed".equals(opt)) {
   1177                 flags |= UserInfo.FLAG_MANAGED_PROFILE;
   1178             } else {
   1179                 System.err.println("Error: unknown option " + opt);
   1180                 showUsage();
   1181                 return 1;
   1182             }
   1183         }
   1184         String arg = nextArg();
   1185         if (arg == null) {
   1186             System.err.println("Error: no user name specified.");
   1187             return 1;
   1188         }
   1189         name = arg;
   1190         try {
   1191             UserInfo info = null;
   1192             if (userId < 0) {
   1193                 info = mUm.createUser(name, flags);
   1194             } else {
   1195                 info = mUm.createProfileForUser(name, flags, userId);
   1196             }
   1197             if (info != null) {
   1198                 System.out.println("Success: created user id " + info.id);
   1199                 return 1;
   1200             } else {
   1201                 System.err.println("Error: couldn't create User.");
   1202                 return 1;
   1203             }
   1204         } catch (RemoteException e) {
   1205             System.err.println(e.toString());
   1206             System.err.println(PM_NOT_RUNNING_ERR);
   1207             return 1;
   1208         }
   1209     }
   1210 
   1211     public int runRemoveUser() {
   1212         int userId;
   1213         String arg = nextArg();
   1214         if (arg == null) {
   1215             System.err.println("Error: no user id specified.");
   1216             return 1;
   1217         }
   1218         try {
   1219             userId = Integer.parseInt(arg);
   1220         } catch (NumberFormatException e) {
   1221             System.err.println("Error: user id '" + arg + "' is not a number.");
   1222             return 1;
   1223         }
   1224         try {
   1225             if (mUm.removeUser(userId)) {
   1226                 System.out.println("Success: removed user");
   1227                 return 0;
   1228             } else {
   1229                 System.err.println("Error: couldn't remove user id " + userId);
   1230                 return 1;
   1231             }
   1232         } catch (RemoteException e) {
   1233             System.err.println(e.toString());
   1234             System.err.println(PM_NOT_RUNNING_ERR);
   1235             return 1;
   1236         }
   1237     }
   1238 
   1239     public int runListUsers() {
   1240         try {
   1241             IActivityManager am = ActivityManagerNative.getDefault();
   1242 
   1243             List<UserInfo> users = mUm.getUsers(false);
   1244             if (users == null) {
   1245                 System.err.println("Error: couldn't get users");
   1246                 return 1;
   1247             } else {
   1248                 System.out.println("Users:");
   1249                 for (int i = 0; i < users.size(); i++) {
   1250                     String running = am.isUserRunning(users.get(i).id, false) ? " running" : "";
   1251                     System.out.println("\t" + users.get(i).toString() + running);
   1252                 }
   1253                 return 0;
   1254             }
   1255         } catch (RemoteException e) {
   1256             System.err.println(e.toString());
   1257             System.err.println(PM_NOT_RUNNING_ERR);
   1258             return 1;
   1259         }
   1260     }
   1261 
   1262     public int runGetMaxUsers() {
   1263         System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers());
   1264         return 0;
   1265     }
   1266 
   1267     public int runForceDexOpt() {
   1268         final String packageName = nextArg();
   1269         try {
   1270             mPm.forceDexOpt(packageName);
   1271             return 0;
   1272         } catch (RemoteException e) {
   1273             throw e.rethrowAsRuntimeException();
   1274         }
   1275     }
   1276 
   1277     private int runUninstall() throws RemoteException {
   1278         int flags = 0;
   1279         int userId = UserHandle.USER_ALL;
   1280 
   1281         String opt;
   1282         while ((opt=nextOption()) != null) {
   1283             if (opt.equals("-k")) {
   1284                 flags |= PackageManager.DELETE_KEEP_DATA;
   1285             } else if (opt.equals("--user")) {
   1286                 String param = nextArg();
   1287                 if (isNumber(param)) {
   1288                     userId = Integer.parseInt(param);
   1289                 } else {
   1290                     showUsage();
   1291                     System.err.println("Error: Invalid user: " + param);
   1292                     return 1;
   1293                 }
   1294             } else {
   1295                 System.err.println("Error: Unknown option: " + opt);
   1296                 return 1;
   1297             }
   1298         }
   1299 
   1300         String pkg = nextArg();
   1301         if (pkg == null) {
   1302             System.err.println("Error: no package specified");
   1303             showUsage();
   1304             return 1;
   1305         }
   1306 
   1307         if (userId == UserHandle.USER_ALL) {
   1308             userId = UserHandle.USER_OWNER;
   1309             flags |= PackageManager.DELETE_ALL_USERS;
   1310         } else {
   1311             PackageInfo info;
   1312             try {
   1313                 info = mPm.getPackageInfo(pkg, 0, userId);
   1314             } catch (RemoteException e) {
   1315                 System.err.println(e.toString());
   1316                 System.err.println(PM_NOT_RUNNING_ERR);
   1317                 return 1;
   1318             }
   1319             if (info == null) {
   1320                 System.err.println("Failure - not installed for " + userId);
   1321                 return 1;
   1322             }
   1323             final boolean isSystem =
   1324                     (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
   1325             // If we are being asked to delete a system app for just one
   1326             // user set flag so it disables rather than reverting to system
   1327             // version of the app.
   1328             if (isSystem) {
   1329                 flags |= PackageManager.DELETE_SYSTEM_APP;
   1330             }
   1331         }
   1332 
   1333         final LocalIntentReceiver receiver = new LocalIntentReceiver();
   1334         mInstaller.uninstall(pkg, flags, receiver.getIntentSender(), userId);
   1335 
   1336         final Intent result = receiver.getResult();
   1337         final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
   1338                 PackageInstaller.STATUS_FAILURE);
   1339         if (status == PackageInstaller.STATUS_SUCCESS) {
   1340             System.out.println("Success");
   1341             return 0;
   1342         } else {
   1343             Log.e(TAG, "Failure details: " + result.getExtras());
   1344             System.err.println("Failure ["
   1345                     + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
   1346             return 1;
   1347         }
   1348     }
   1349 
   1350     static class ClearDataObserver extends IPackageDataObserver.Stub {
   1351         boolean finished;
   1352         boolean result;
   1353 
   1354         @Override
   1355         public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
   1356             synchronized (this) {
   1357                 finished = true;
   1358                 result = succeeded;
   1359                 notifyAll();
   1360             }
   1361         }
   1362     }
   1363 
   1364     private int runClear() {
   1365         int userId = 0;
   1366         String option = nextOption();
   1367         if (option != null && option.equals("--user")) {
   1368             String optionData = nextOptionData();
   1369             if (optionData == null || !isNumber(optionData)) {
   1370                 System.err.println("Error: no USER_ID specified");
   1371                 showUsage();
   1372                 return 1;
   1373             } else {
   1374                 userId = Integer.parseInt(optionData);
   1375             }
   1376         }
   1377 
   1378         String pkg = nextArg();
   1379         if (pkg == null) {
   1380             System.err.println("Error: no package specified");
   1381             showUsage();
   1382             return 1;
   1383         }
   1384 
   1385         ClearDataObserver obs = new ClearDataObserver();
   1386         try {
   1387             ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId);
   1388             synchronized (obs) {
   1389                 while (!obs.finished) {
   1390                     try {
   1391                         obs.wait();
   1392                     } catch (InterruptedException e) {
   1393                     }
   1394                 }
   1395             }
   1396 
   1397             if (obs.result) {
   1398                 System.out.println("Success");
   1399                 return 0;
   1400             } else {
   1401                 System.err.println("Failed");
   1402                 return 1;
   1403             }
   1404         } catch (RemoteException e) {
   1405             System.err.println(e.toString());
   1406             System.err.println(PM_NOT_RUNNING_ERR);
   1407             return 1;
   1408         }
   1409     }
   1410 
   1411     private static String enabledSettingToString(int state) {
   1412         switch (state) {
   1413             case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
   1414                 return "default";
   1415             case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
   1416                 return "enabled";
   1417             case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
   1418                 return "disabled";
   1419             case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
   1420                 return "disabled-user";
   1421             case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
   1422                 return "disabled-until-used";
   1423         }
   1424         return "unknown";
   1425     }
   1426 
   1427     private static boolean isNumber(String s) {
   1428         try {
   1429             Integer.parseInt(s);
   1430         } catch (NumberFormatException nfe) {
   1431             return false;
   1432         }
   1433         return true;
   1434     }
   1435 
   1436     private int runSetEnabledSetting(int state) {
   1437         int userId = 0;
   1438         String option = nextOption();
   1439         if (option != null && option.equals("--user")) {
   1440             String optionData = nextOptionData();
   1441             if (optionData == null || !isNumber(optionData)) {
   1442                 System.err.println("Error: no USER_ID specified");
   1443                 showUsage();
   1444                 return 1;
   1445             } else {
   1446                 userId = Integer.parseInt(optionData);
   1447             }
   1448         }
   1449 
   1450         String pkg = nextArg();
   1451         if (pkg == null) {
   1452             System.err.println("Error: no package or component specified");
   1453             showUsage();
   1454             return 1;
   1455         }
   1456         ComponentName cn = ComponentName.unflattenFromString(pkg);
   1457         if (cn == null) {
   1458             try {
   1459                 mPm.setApplicationEnabledSetting(pkg, state, 0, userId,
   1460                         "shell:" + android.os.Process.myUid());
   1461                 System.out.println("Package " + pkg + " new state: "
   1462                         + enabledSettingToString(
   1463                         mPm.getApplicationEnabledSetting(pkg, userId)));
   1464                 return 0;
   1465             } catch (RemoteException e) {
   1466                 System.err.println(e.toString());
   1467                 System.err.println(PM_NOT_RUNNING_ERR);
   1468                 return 1;
   1469             }
   1470         } else {
   1471             try {
   1472                 mPm.setComponentEnabledSetting(cn, state, 0, userId);
   1473                 System.out.println("Component " + cn.toShortString() + " new state: "
   1474                         + enabledSettingToString(
   1475                         mPm.getComponentEnabledSetting(cn, userId)));
   1476                 return 0;
   1477             } catch (RemoteException e) {
   1478                 System.err.println(e.toString());
   1479                 System.err.println(PM_NOT_RUNNING_ERR);
   1480                 return 1;
   1481             }
   1482         }
   1483     }
   1484 
   1485     private int runSetHiddenSetting(boolean state) {
   1486         int userId = 0;
   1487         String option = nextOption();
   1488         if (option != null && option.equals("--user")) {
   1489             String optionData = nextOptionData();
   1490             if (optionData == null || !isNumber(optionData)) {
   1491                 System.err.println("Error: no USER_ID specified");
   1492                 showUsage();
   1493                 return 1;
   1494             } else {
   1495                 userId = Integer.parseInt(optionData);
   1496             }
   1497         }
   1498 
   1499         String pkg = nextArg();
   1500         if (pkg == null) {
   1501             System.err.println("Error: no package or component specified");
   1502             showUsage();
   1503             return 1;
   1504         }
   1505         try {
   1506             mPm.setApplicationHiddenSettingAsUser(pkg, state, userId);
   1507             System.out.println("Package " + pkg + " new hidden state: "
   1508                     + mPm.getApplicationHiddenSettingAsUser(pkg, userId));
   1509             return 0;
   1510         } catch (RemoteException e) {
   1511             System.err.println(e.toString());
   1512             System.err.println(PM_NOT_RUNNING_ERR);
   1513             return 1;
   1514         }
   1515     }
   1516 
   1517     private int runGrantRevokePermission(boolean grant) {
   1518         String pkg = nextArg();
   1519         if (pkg == null) {
   1520             System.err.println("Error: no package specified");
   1521             showUsage();
   1522             return 1;
   1523         }
   1524         String perm = nextArg();
   1525         if (perm == null) {
   1526             System.err.println("Error: no permission specified");
   1527             showUsage();
   1528             return 1;
   1529         }
   1530         try {
   1531             if (grant) {
   1532                 mPm.grantPermission(pkg, perm);
   1533             } else {
   1534                 mPm.revokePermission(pkg, perm);
   1535             }
   1536             return 0;
   1537         } catch (RemoteException e) {
   1538             System.err.println(e.toString());
   1539             System.err.println(PM_NOT_RUNNING_ERR);
   1540             return 1;
   1541         } catch (IllegalArgumentException e) {
   1542             System.err.println("Bad argument: " + e.toString());
   1543             showUsage();
   1544             return 1;
   1545         } catch (SecurityException e) {
   1546             System.err.println("Operation not allowed: " + e.toString());
   1547             return 1;
   1548         }
   1549     }
   1550 
   1551     private int runSetPermissionEnforced() {
   1552         final String permission = nextArg();
   1553         if (permission == null) {
   1554             System.err.println("Error: no permission specified");
   1555             showUsage();
   1556             return 1;
   1557         }
   1558         final String enforcedRaw = nextArg();
   1559         if (enforcedRaw == null) {
   1560             System.err.println("Error: no enforcement specified");
   1561             showUsage();
   1562             return 1;
   1563         }
   1564         final boolean enforced = Boolean.parseBoolean(enforcedRaw);
   1565         try {
   1566             mPm.setPermissionEnforced(permission, enforced);
   1567             return 0;
   1568         } catch (RemoteException e) {
   1569             System.err.println(e.toString());
   1570             System.err.println(PM_NOT_RUNNING_ERR);
   1571             return 1;
   1572         } catch (IllegalArgumentException e) {
   1573             System.err.println("Bad argument: " + e.toString());
   1574             showUsage();
   1575             return 1;
   1576         } catch (SecurityException e) {
   1577             System.err.println("Operation not allowed: " + e.toString());
   1578             return 1;
   1579         }
   1580     }
   1581 
   1582     static class ClearCacheObserver extends IPackageDataObserver.Stub {
   1583         boolean finished;
   1584         boolean result;
   1585 
   1586         @Override
   1587         public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
   1588             synchronized (this) {
   1589                 finished = true;
   1590                 result = succeeded;
   1591                 notifyAll();
   1592             }
   1593         }
   1594 
   1595     }
   1596 
   1597     private int runTrimCaches() {
   1598         String size = nextArg();
   1599         if (size == null) {
   1600             System.err.println("Error: no size specified");
   1601             showUsage();
   1602             return 1;
   1603         }
   1604         int len = size.length();
   1605         long multiplier = 1;
   1606         if (len > 1) {
   1607             char c = size.charAt(len-1);
   1608             if (c == 'K' || c == 'k') {
   1609                 multiplier = 1024L;
   1610             } else if (c == 'M' || c == 'm') {
   1611                 multiplier = 1024L*1024L;
   1612             } else if (c == 'G' || c == 'g') {
   1613                 multiplier = 1024L*1024L*1024L;
   1614             } else {
   1615                 System.err.println("Invalid suffix: " + c);
   1616                 showUsage();
   1617                 return 1;
   1618             }
   1619             size = size.substring(0, len-1);
   1620         }
   1621         long sizeVal;
   1622         try {
   1623             sizeVal = Long.parseLong(size) * multiplier;
   1624         } catch (NumberFormatException e) {
   1625             System.err.println("Error: expected number at: " + size);
   1626             showUsage();
   1627             return 1;
   1628         }
   1629         ClearDataObserver obs = new ClearDataObserver();
   1630         try {
   1631             mPm.freeStorageAndNotify(sizeVal, obs);
   1632             synchronized (obs) {
   1633                 while (!obs.finished) {
   1634                     try {
   1635                         obs.wait();
   1636                     } catch (InterruptedException e) {
   1637                     }
   1638                 }
   1639             }
   1640             return 0;
   1641         } catch (RemoteException e) {
   1642             System.err.println(e.toString());
   1643             System.err.println(PM_NOT_RUNNING_ERR);
   1644             return 1;
   1645         } catch (IllegalArgumentException e) {
   1646             System.err.println("Bad argument: " + e.toString());
   1647             showUsage();
   1648             return 1;
   1649         } catch (SecurityException e) {
   1650             System.err.println("Operation not allowed: " + e.toString());
   1651             return 1;
   1652         }
   1653     }
   1654 
   1655     /**
   1656      * Displays the package file for a package.
   1657      * @param pckg
   1658      */
   1659     private int displayPackageFilePath(String pckg) {
   1660         try {
   1661             PackageInfo info = mPm.getPackageInfo(pckg, 0, 0);
   1662             if (info != null && info.applicationInfo != null) {
   1663                 System.out.print("package:");
   1664                 System.out.println(info.applicationInfo.sourceDir);
   1665                 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
   1666                     for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
   1667                         System.out.print("package:");
   1668                         System.out.println(splitSourceDir);
   1669                     }
   1670                 }
   1671                 return 0;
   1672             }
   1673         } catch (RemoteException e) {
   1674             System.err.println(e.toString());
   1675             System.err.println(PM_NOT_RUNNING_ERR);
   1676         }
   1677         return 1;
   1678     }
   1679 
   1680     private Resources getResources(PackageItemInfo pii) {
   1681         Resources res = mResourceCache.get(pii.packageName);
   1682         if (res != null) return res;
   1683 
   1684         try {
   1685             ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0, 0);
   1686             AssetManager am = new AssetManager();
   1687             am.addAssetPath(ai.publicSourceDir);
   1688             res = new Resources(am, null, null);
   1689             mResourceCache.put(pii.packageName, res);
   1690             return res;
   1691         } catch (RemoteException e) {
   1692             System.err.println(e.toString());
   1693             System.err.println(PM_NOT_RUNNING_ERR);
   1694             return null;
   1695         }
   1696     }
   1697 
   1698     private static String checkAbiArgument(String abi) {
   1699         if (TextUtils.isEmpty(abi)) {
   1700             throw new IllegalArgumentException("Missing ABI argument");
   1701         }
   1702 
   1703         if ("-".equals(abi)) {
   1704             return abi;
   1705         }
   1706 
   1707         final String[] supportedAbis = Build.SUPPORTED_ABIS;
   1708         for (String supportedAbi : supportedAbis) {
   1709             if (supportedAbi.equals(abi)) {
   1710                 return abi;
   1711             }
   1712         }
   1713 
   1714         throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
   1715     }
   1716 
   1717     private static class LocalIntentReceiver {
   1718         private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
   1719 
   1720         private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
   1721             @Override
   1722             public int send(int code, Intent intent, String resolvedType,
   1723                     IIntentReceiver finishedReceiver, String requiredPermission) {
   1724                 try {
   1725                     mResult.offer(intent, 5, TimeUnit.SECONDS);
   1726                 } catch (InterruptedException e) {
   1727                     throw new RuntimeException(e);
   1728                 }
   1729                 return 0;
   1730             }
   1731         };
   1732 
   1733         public IntentSender getIntentSender() {
   1734             return new IntentSender((IIntentSender) mLocalSender);
   1735         }
   1736 
   1737         public Intent getResult() {
   1738             try {
   1739                 return mResult.take();
   1740             } catch (InterruptedException e) {
   1741                 throw new RuntimeException(e);
   1742             }
   1743         }
   1744     }
   1745 
   1746     private String nextOption() {
   1747         if (mNextArg >= mArgs.length) {
   1748             return null;
   1749         }
   1750         String arg = mArgs[mNextArg];
   1751         if (!arg.startsWith("-")) {
   1752             return null;
   1753         }
   1754         mNextArg++;
   1755         if (arg.equals("--")) {
   1756             return null;
   1757         }
   1758         if (arg.length() > 1 && arg.charAt(1) != '-') {
   1759             if (arg.length() > 2) {
   1760                 mCurArgData = arg.substring(2);
   1761                 return arg.substring(0, 2);
   1762             } else {
   1763                 mCurArgData = null;
   1764                 return arg;
   1765             }
   1766         }
   1767         mCurArgData = null;
   1768         return arg;
   1769     }
   1770 
   1771     private String nextOptionData() {
   1772         if (mCurArgData != null) {
   1773             return mCurArgData;
   1774         }
   1775         if (mNextArg >= mArgs.length) {
   1776             return null;
   1777         }
   1778         String data = mArgs[mNextArg];
   1779         mNextArg++;
   1780         return data;
   1781     }
   1782 
   1783     private String nextArg() {
   1784         if (mNextArg >= mArgs.length) {
   1785             return null;
   1786         }
   1787         String arg = mArgs[mNextArg];
   1788         mNextArg++;
   1789         return arg;
   1790     }
   1791 
   1792     private static int showUsage() {
   1793         System.err.println("usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]");
   1794         System.err.println("       pm list permission-groups");
   1795         System.err.println("       pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
   1796         System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");
   1797         System.err.println("       pm list features");
   1798         System.err.println("       pm list libraries");
   1799         System.err.println("       pm list users");
   1800         System.err.println("       pm path PACKAGE");
   1801         System.err.println("       pm dump PACKAGE");
   1802         System.err.println("       pm install [-lrtsfd] [-i PACKAGE] [PATH]");
   1803         System.err.println("       pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]");
   1804         System.err.println("       pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]");
   1805         System.err.println("       pm install-commit SESSION_ID");
   1806         System.err.println("       pm install-abandon SESSION_ID");
   1807         System.err.println("       pm uninstall [-k] [--user USER_ID] PACKAGE");
   1808         System.err.println("       pm set-installer PACKAGE INSTALLER");
   1809         System.err.println("       pm clear [--user USER_ID] PACKAGE");
   1810         System.err.println("       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
   1811         System.err.println("       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
   1812         System.err.println("       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
   1813         System.err.println("       pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
   1814         System.err.println("       pm hide [--user USER_ID] PACKAGE_OR_COMPONENT");
   1815         System.err.println("       pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
   1816         System.err.println("       pm grant PACKAGE PERMISSION");
   1817         System.err.println("       pm revoke PACKAGE PERMISSION");
   1818         System.err.println("       pm set-install-location [0/auto] [1/internal] [2/external]");
   1819         System.err.println("       pm get-install-location");
   1820         System.err.println("       pm set-permission-enforced PERMISSION [true|false]");
   1821         System.err.println("       pm trim-caches DESIRED_FREE_SPACE");
   1822         System.err.println("       pm create-user [--profileOf USER_ID] [--managed] USER_NAME");
   1823         System.err.println("       pm remove-user USER_ID");
   1824         System.err.println("       pm get-max-users");
   1825         System.err.println("");
   1826         System.err.println("pm list packages: prints all packages, optionally only");
   1827         System.err.println("  those whose package name contains the text in FILTER.  Options:");
   1828         System.err.println("    -f: see their associated file.");
   1829         System.err.println("    -d: filter to only show disbled packages.");
   1830         System.err.println("    -e: filter to only show enabled packages.");
   1831         System.err.println("    -s: filter to only show system packages.");
   1832         System.err.println("    -3: filter to only show third party packages.");
   1833         System.err.println("    -i: see the installer for the packages.");
   1834         System.err.println("    -u: also include uninstalled packages.");
   1835         System.err.println("");
   1836         System.err.println("pm list permission-groups: prints all known permission groups.");
   1837         System.err.println("");
   1838         System.err.println("pm list permissions: prints all known permissions, optionally only");
   1839         System.err.println("  those in GROUP.  Options:");
   1840         System.err.println("    -g: organize by group.");
   1841         System.err.println("    -f: print all information.");
   1842         System.err.println("    -s: short summary.");
   1843         System.err.println("    -d: only list dangerous permissions.");
   1844         System.err.println("    -u: list only the permissions users will see.");
   1845         System.err.println("");
   1846         System.err.println("pm list instrumentation: use to list all test packages; optionally");
   1847         System.err.println("  supply <TARGET-PACKAGE> to list the test packages for a particular");
   1848         System.err.println("  application.  Options:");
   1849         System.err.println("    -f: list the .apk file for the test package.");
   1850         System.err.println("");
   1851         System.err.println("pm list features: prints all features of the system.");
   1852         System.err.println("");
   1853         System.err.println("pm list users: prints all users on the system.");
   1854         System.err.println("");
   1855         System.err.println("pm path: print the path to the .apk of the given PACKAGE.");
   1856         System.err.println("");
   1857         System.err.println("pm dump: print system state associated with the given PACKAGE.");
   1858         System.err.println("");
   1859         System.err.println("pm install: install a single legacy package");
   1860         System.err.println("pm install-create: create an install session");
   1861         System.err.println("    -l: forward lock application");
   1862         System.err.println("    -r: replace existing application");
   1863         System.err.println("    -t: allow test packages");
   1864         System.err.println("    -i: specify the installer package name");
   1865         System.err.println("    -s: install application on sdcard");
   1866         System.err.println("    -f: install application on internal flash");
   1867         System.err.println("    -d: allow version code downgrade");
   1868         System.err.println("    -p: partial application install");
   1869         System.err.println("    -S: size in bytes of entire session");
   1870         System.err.println("");
   1871         System.err.println("pm install-write: write a package into existing session; path may");
   1872         System.err.println("  be '-' to read from stdin");
   1873         System.err.println("    -S: size in bytes of package, required for stdin");
   1874         System.err.println("");
   1875         System.err.println("pm install-commit: perform install of fully staged session");
   1876         System.err.println("pm install-abandon: abandon session");
   1877         System.err.println("");
   1878         System.err.println("pm set-installer: set installer package name");
   1879         System.err.println("");
   1880         System.err.println("pm uninstall: removes a package from the system. Options:");
   1881         System.err.println("    -k: keep the data and cache directories around after package removal.");
   1882         System.err.println("");
   1883         System.err.println("pm clear: deletes all data associated with a package.");
   1884         System.err.println("");
   1885         System.err.println("pm enable, disable, disable-user, disable-until-used: these commands");
   1886         System.err.println("  change the enabled state of a given package or component (written");
   1887         System.err.println("  as \"package/class\").");
   1888         System.err.println("");
   1889         System.err.println("pm grant, revoke: these commands either grant or revoke permissions");
   1890         System.err.println("  to applications.  Only optional permissions the application has");
   1891         System.err.println("  declared can be granted or revoked.");
   1892         System.err.println("");
   1893         System.err.println("pm get-install-location: returns the current install location.");
   1894         System.err.println("    0 [auto]: Let system decide the best location");
   1895         System.err.println("    1 [internal]: Install on internal device storage");
   1896         System.err.println("    2 [external]: Install on external media");
   1897         System.err.println("");
   1898         System.err.println("pm set-install-location: changes the default install location.");
   1899         System.err.println("  NOTE: this is only intended for debugging; using this can cause");
   1900         System.err.println("  applications to break and other undersireable behavior.");
   1901         System.err.println("    0 [auto]: Let system decide the best location");
   1902         System.err.println("    1 [internal]: Install on internal device storage");
   1903         System.err.println("    2 [external]: Install on external media");
   1904         System.err.println("");
   1905         System.err.println("pm trim-caches: trim cache files to reach the given free space.");
   1906         System.err.println("");
   1907         System.err.println("pm create-user: create a new user with the given USER_NAME,");
   1908         System.err.println("  printing the new user identifier of the user.");
   1909         System.err.println("");
   1910         System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,");
   1911         System.err.println("  deleting all data associated with that user");
   1912         System.err.println("");
   1913         return 1;
   1914     }
   1915 }
   1916