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.content.ComponentName;
     22 import android.content.pm.ApplicationInfo;
     23 import android.content.pm.ContainerEncryptionParams;
     24 import android.content.pm.FeatureInfo;
     25 import android.content.pm.IPackageDataObserver;
     26 import android.content.pm.IPackageDeleteObserver;
     27 import android.content.pm.IPackageInstallObserver;
     28 import android.content.pm.IPackageManager;
     29 import android.content.pm.InstrumentationInfo;
     30 import android.content.pm.PackageInfo;
     31 import android.content.pm.PackageItemInfo;
     32 import android.content.pm.PackageManager;
     33 import android.content.pm.ParceledListSlice;
     34 import android.content.pm.PermissionGroupInfo;
     35 import android.content.pm.PermissionInfo;
     36 import android.content.pm.UserInfo;
     37 import android.content.pm.VerificationParams;
     38 import android.content.res.AssetManager;
     39 import android.content.res.Resources;
     40 import android.net.Uri;
     41 import android.os.IUserManager;
     42 import android.os.RemoteException;
     43 import android.os.ServiceManager;
     44 import android.os.UserHandle;
     45 import android.os.UserManager;
     46 
     47 import java.io.File;
     48 import java.io.FileDescriptor;
     49 import java.lang.reflect.Field;
     50 import java.lang.reflect.Modifier;
     51 import java.security.InvalidAlgorithmParameterException;
     52 import java.util.ArrayList;
     53 import java.util.Collections;
     54 import java.util.Comparator;
     55 import java.util.List;
     56 import java.util.WeakHashMap;
     57 
     58 import javax.crypto.SecretKey;
     59 import javax.crypto.spec.IvParameterSpec;
     60 import javax.crypto.spec.SecretKeySpec;
     61 
     62 import com.android.internal.content.PackageHelper;
     63 
     64 public final class Pm {
     65     IPackageManager mPm;
     66     IUserManager mUm;
     67 
     68     private WeakHashMap<String, Resources> mResourceCache
     69             = new WeakHashMap<String, Resources>();
     70 
     71     private String[] mArgs;
     72     private int mNextArg;
     73     private String mCurArgData;
     74 
     75     private static final String PM_NOT_RUNNING_ERR =
     76         "Error: Could not access the Package Manager.  Is the system running?";
     77 
     78     public static void main(String[] args) {
     79         new Pm().run(args);
     80     }
     81 
     82     public void run(String[] args) {
     83         boolean validCommand = false;
     84         if (args.length < 1) {
     85             showUsage();
     86             return;
     87         }
     88 
     89         mUm = IUserManager.Stub.asInterface(ServiceManager.getService("user"));
     90         mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
     91         if (mPm == null) {
     92             System.err.println(PM_NOT_RUNNING_ERR);
     93             return;
     94         }
     95 
     96         mArgs = args;
     97         String op = args[0];
     98         mNextArg = 1;
     99 
    100         if ("list".equals(op)) {
    101             runList();
    102             return;
    103         }
    104 
    105         if ("path".equals(op)) {
    106             runPath();
    107             return;
    108         }
    109 
    110         if ("dump".equals(op)) {
    111             runDump();
    112             return;
    113         }
    114 
    115         if ("install".equals(op)) {
    116             runInstall();
    117             return;
    118         }
    119 
    120         if ("uninstall".equals(op)) {
    121             runUninstall();
    122             return;
    123         }
    124 
    125         if ("clear".equals(op)) {
    126             runClear();
    127             return;
    128         }
    129 
    130         if ("enable".equals(op)) {
    131             runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
    132             return;
    133         }
    134 
    135         if ("disable".equals(op)) {
    136             runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
    137             return;
    138         }
    139 
    140         if ("disable-user".equals(op)) {
    141             runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
    142             return;
    143         }
    144 
    145         if ("disable-until-used".equals(op)) {
    146             runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
    147             return;
    148         }
    149 
    150         if ("block".equals(op)) {
    151             runSetBlockedSetting(true);
    152             return;
    153         }
    154 
    155         if ("unblock".equals(op)) {
    156             runSetBlockedSetting(false);
    157             return;
    158         }
    159 
    160         if ("grant".equals(op)) {
    161             runGrantRevokePermission(true);
    162             return;
    163         }
    164 
    165         if ("revoke".equals(op)) {
    166             runGrantRevokePermission(false);
    167             return;
    168         }
    169 
    170         if ("set-permission-enforced".equals(op)) {
    171             runSetPermissionEnforced();
    172             return;
    173         }
    174 
    175         if ("set-install-location".equals(op)) {
    176             runSetInstallLocation();
    177             return;
    178         }
    179 
    180         if ("get-install-location".equals(op)) {
    181             runGetInstallLocation();
    182             return;
    183         }
    184 
    185         if ("trim-caches".equals(op)) {
    186             runTrimCaches();
    187             return;
    188         }
    189 
    190         if ("create-user".equals(op)) {
    191             runCreateUser();
    192             return;
    193         }
    194 
    195         if ("remove-user".equals(op)) {
    196             runRemoveUser();
    197             return;
    198         }
    199 
    200         if ("get-max-users".equals(op)) {
    201             runGetMaxUsers();
    202             return;
    203         }
    204 
    205         try {
    206             if (args.length == 1) {
    207                 if (args[0].equalsIgnoreCase("-l")) {
    208                     validCommand = true;
    209                     runListPackages(false);
    210                 } else if (args[0].equalsIgnoreCase("-lf")){
    211                     validCommand = true;
    212                     runListPackages(true);
    213                 }
    214             } else if (args.length == 2) {
    215                 if (args[0].equalsIgnoreCase("-p")) {
    216                     validCommand = true;
    217                     displayPackageFilePath(args[1]);
    218                 }
    219             }
    220         } finally {
    221             if (validCommand == false) {
    222                 if (op != null) {
    223                     System.err.println("Error: unknown command '" + op + "'");
    224                 }
    225                 showUsage();
    226             }
    227         }
    228     }
    229 
    230     /**
    231      * Execute the list sub-command.
    232      *
    233      * pm list [package | packages]
    234      * pm list permission-groups
    235      * pm list permissions
    236      * pm list features
    237      * pm list libraries
    238      * pm list instrumentation
    239      */
    240     private void runList() {
    241         String type = nextArg();
    242         if (type == null) {
    243             System.err.println("Error: didn't specify type of data to list");
    244             return;
    245         }
    246         if ("package".equals(type) || "packages".equals(type)) {
    247             runListPackages(false);
    248         } else if ("permission-groups".equals(type)) {
    249             runListPermissionGroups();
    250         } else if ("permissions".equals(type)) {
    251             runListPermissions();
    252         } else if ("features".equals(type)) {
    253             runListFeatures();
    254         } else if ("libraries".equals(type)) {
    255             runListLibraries();
    256         } else if ("instrumentation".equals(type)) {
    257             runListInstrumentation();
    258         } else if ("users".equals(type)) {
    259             runListUsers();
    260         } else {
    261             System.err.println("Error: unknown list type '" + type + "'");
    262         }
    263     }
    264 
    265     /**
    266      * Lists all the installed packages.
    267      */
    268     private void runListPackages(boolean showApplicationPackage) {
    269         int getFlags = 0;
    270         boolean listDisabled = false, listEnabled = false;
    271         boolean listSystem = false, listThirdParty = false;
    272         boolean listInstaller = false;
    273         int userId = UserHandle.USER_OWNER;
    274         try {
    275             String opt;
    276             while ((opt=nextOption()) != null) {
    277                 if (opt.equals("-l")) {
    278                     // old compat
    279                 } else if (opt.equals("-lf")) {
    280                     showApplicationPackage = true;
    281                 } else if (opt.equals("-f")) {
    282                     showApplicationPackage = true;
    283                 } else if (opt.equals("-d")) {
    284                     listDisabled = true;
    285                 } else if (opt.equals("-e")) {
    286                     listEnabled = true;
    287                 } else if (opt.equals("-s")) {
    288                     listSystem = true;
    289                 } else if (opt.equals("-3")) {
    290                     listThirdParty = true;
    291                 } else if (opt.equals("-i")) {
    292                     listInstaller = true;
    293                 } else if (opt.equals("--user")) {
    294                     userId = Integer.parseInt(nextArg());
    295                 } else if (opt.equals("-u")) {
    296                     getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
    297                 } else {
    298                     System.err.println("Error: Unknown option: " + opt);
    299                     return;
    300                 }
    301             }
    302         } catch (RuntimeException ex) {
    303             System.err.println("Error: " + ex.toString());
    304             return;
    305         }
    306 
    307         String filter = nextArg();
    308 
    309         try {
    310             final List<PackageInfo> packages = getInstalledPackages(mPm, getFlags, userId);
    311 
    312             int count = packages.size();
    313             for (int p = 0 ; p < count ; p++) {
    314                 PackageInfo info = packages.get(p);
    315                 if (filter != null && !info.packageName.contains(filter)) {
    316                     continue;
    317                 }
    318                 final boolean isSystem =
    319                         (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
    320                 if ((!listDisabled || !info.applicationInfo.enabled) &&
    321                         (!listEnabled || info.applicationInfo.enabled) &&
    322                         (!listSystem || isSystem) &&
    323                         (!listThirdParty || !isSystem)) {
    324                     System.out.print("package:");
    325                     if (showApplicationPackage) {
    326                         System.out.print(info.applicationInfo.sourceDir);
    327                         System.out.print("=");
    328                     }
    329                     System.out.print(info.packageName);
    330                     if (listInstaller) {
    331                         System.out.print("  installer=");
    332                         System.out.print(mPm.getInstallerPackageName(info.packageName));
    333                     }
    334                     System.out.println();
    335                 }
    336             }
    337         } catch (RemoteException e) {
    338             System.err.println(e.toString());
    339             System.err.println(PM_NOT_RUNNING_ERR);
    340         }
    341     }
    342 
    343     @SuppressWarnings("unchecked")
    344     private List<PackageInfo> getInstalledPackages(IPackageManager pm, int flags, int userId)
    345             throws RemoteException {
    346         ParceledListSlice<PackageInfo> slice = pm.getInstalledPackages(flags, userId);
    347         return slice.getList();
    348     }
    349 
    350     /**
    351      * Lists all of the features supported by the current device.
    352      *
    353      * pm list features
    354      */
    355     private void runListFeatures() {
    356         try {
    357             List<FeatureInfo> list = new ArrayList<FeatureInfo>();
    358             FeatureInfo[] rawList = mPm.getSystemAvailableFeatures();
    359             for (int i=0; i<rawList.length; i++) {
    360                 list.add(rawList[i]);
    361             }
    362 
    363 
    364             // Sort by name
    365             Collections.sort(list, new Comparator<FeatureInfo>() {
    366                 public int compare(FeatureInfo o1, FeatureInfo o2) {
    367                     if (o1.name == o2.name) return 0;
    368                     if (o1.name == null) return -1;
    369                     if (o2.name == null) return 1;
    370                     return o1.name.compareTo(o2.name);
    371                 }
    372             });
    373 
    374             int count = (list != null) ? list.size() : 0;
    375             for (int p = 0; p < count; p++) {
    376                 FeatureInfo fi = list.get(p);
    377                 System.out.print("feature:");
    378                 if (fi.name != null) System.out.println(fi.name);
    379                 else System.out.println("reqGlEsVersion=0x"
    380                         + Integer.toHexString(fi.reqGlEsVersion));
    381             }
    382         } catch (RemoteException e) {
    383             System.err.println(e.toString());
    384             System.err.println(PM_NOT_RUNNING_ERR);
    385         }
    386     }
    387 
    388     /**
    389      * Lists all of the libraries supported by the current device.
    390      *
    391      * pm list libraries
    392      */
    393     private void runListLibraries() {
    394         try {
    395             List<String> list = new ArrayList<String>();
    396             String[] rawList = mPm.getSystemSharedLibraryNames();
    397             for (int i=0; i<rawList.length; i++) {
    398                 list.add(rawList[i]);
    399             }
    400 
    401 
    402             // Sort by name
    403             Collections.sort(list, new Comparator<String>() {
    404                 public int compare(String o1, String o2) {
    405                     if (o1 == o2) return 0;
    406                     if (o1 == null) return -1;
    407                     if (o2 == null) return 1;
    408                     return o1.compareTo(o2);
    409                 }
    410             });
    411 
    412             int count = (list != null) ? list.size() : 0;
    413             for (int p = 0; p < count; p++) {
    414                 String lib = list.get(p);
    415                 System.out.print("library:");
    416                 System.out.println(lib);
    417             }
    418         } catch (RemoteException e) {
    419             System.err.println(e.toString());
    420             System.err.println(PM_NOT_RUNNING_ERR);
    421         }
    422     }
    423 
    424     /**
    425      * Lists all of the installed instrumentation, or all for a given package
    426      *
    427      * pm list instrumentation [package] [-f]
    428      */
    429     private void runListInstrumentation() {
    430         int flags = 0;      // flags != 0 is only used to request meta-data
    431         boolean showPackage = false;
    432         String targetPackage = null;
    433 
    434         try {
    435             String opt;
    436             while ((opt=nextArg()) != null) {
    437                 if (opt.equals("-f")) {
    438                     showPackage = true;
    439                 } else if (opt.charAt(0) != '-') {
    440                     targetPackage = opt;
    441                 } else {
    442                     System.err.println("Error: Unknown option: " + opt);
    443                     return;
    444                 }
    445             }
    446         } catch (RuntimeException ex) {
    447             System.err.println("Error: " + ex.toString());
    448             return;
    449         }
    450 
    451         try {
    452             List<InstrumentationInfo> list = mPm.queryInstrumentation(targetPackage, flags);
    453 
    454             // Sort by target package
    455             Collections.sort(list, new Comparator<InstrumentationInfo>() {
    456                 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
    457                     return o1.targetPackage.compareTo(o2.targetPackage);
    458                 }
    459             });
    460 
    461             int count = (list != null) ? list.size() : 0;
    462             for (int p = 0; p < count; p++) {
    463                 InstrumentationInfo ii = list.get(p);
    464                 System.out.print("instrumentation:");
    465                 if (showPackage) {
    466                     System.out.print(ii.sourceDir);
    467                     System.out.print("=");
    468                 }
    469                 ComponentName cn = new ComponentName(ii.packageName, ii.name);
    470                 System.out.print(cn.flattenToShortString());
    471                 System.out.print(" (target=");
    472                 System.out.print(ii.targetPackage);
    473                 System.out.println(")");
    474             }
    475         } catch (RemoteException e) {
    476             System.err.println(e.toString());
    477             System.err.println(PM_NOT_RUNNING_ERR);
    478         }
    479     }
    480 
    481     /**
    482      * Lists all the known permission groups.
    483      */
    484     private void runListPermissionGroups() {
    485         try {
    486             List<PermissionGroupInfo> pgs = mPm.getAllPermissionGroups(0);
    487 
    488             int count = pgs.size();
    489             for (int p = 0 ; p < count ; p++) {
    490                 PermissionGroupInfo pgi = pgs.get(p);
    491                 System.out.print("permission group:");
    492                 System.out.println(pgi.name);
    493             }
    494         } catch (RemoteException e) {
    495             System.err.println(e.toString());
    496             System.err.println(PM_NOT_RUNNING_ERR);
    497         }
    498     }
    499 
    500     private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) {
    501         if (nonLocalized != null) {
    502             return nonLocalized.toString();
    503         }
    504         if (res != 0) {
    505             Resources r = getResources(pii);
    506             if (r != null) {
    507                 return r.getString(res);
    508             }
    509         }
    510         return null;
    511     }
    512 
    513     /**
    514      * Lists all the permissions in a group.
    515      */
    516     private void runListPermissions() {
    517         try {
    518             boolean labels = false;
    519             boolean groups = false;
    520             boolean userOnly = false;
    521             boolean summary = false;
    522             boolean dangerousOnly = false;
    523             String opt;
    524             while ((opt=nextOption()) != null) {
    525                 if (opt.equals("-f")) {
    526                     labels = true;
    527                 } else if (opt.equals("-g")) {
    528                     groups = true;
    529                 } else if (opt.equals("-s")) {
    530                     groups = true;
    531                     labels = true;
    532                     summary = true;
    533                 } else if (opt.equals("-u")) {
    534                     userOnly = true;
    535                 } else if (opt.equals("-d")) {
    536                     dangerousOnly = true;
    537                 } else {
    538                     System.err.println("Error: Unknown option: " + opt);
    539                     return;
    540                 }
    541             }
    542 
    543             String grp = nextOption();
    544             ArrayList<String> groupList = new ArrayList<String>();
    545             if (groups) {
    546                 List<PermissionGroupInfo> infos =
    547                         mPm.getAllPermissionGroups(0);
    548                 for (int i=0; i<infos.size(); i++) {
    549                     groupList.add(infos.get(i).name);
    550                 }
    551                 groupList.add(null);
    552             } else {
    553                 groupList.add(grp);
    554             }
    555 
    556             if (dangerousOnly) {
    557                 System.out.println("Dangerous Permissions:");
    558                 System.out.println("");
    559                 doListPermissions(groupList, groups, labels, summary,
    560                         PermissionInfo.PROTECTION_DANGEROUS,
    561                         PermissionInfo.PROTECTION_DANGEROUS);
    562                 if (userOnly) {
    563                     System.out.println("Normal Permissions:");
    564                     System.out.println("");
    565                     doListPermissions(groupList, groups, labels, summary,
    566                             PermissionInfo.PROTECTION_NORMAL,
    567                             PermissionInfo.PROTECTION_NORMAL);
    568                 }
    569             } else if (userOnly) {
    570                 System.out.println("Dangerous and Normal Permissions:");
    571                 System.out.println("");
    572                 doListPermissions(groupList, groups, labels, summary,
    573                         PermissionInfo.PROTECTION_NORMAL,
    574                         PermissionInfo.PROTECTION_DANGEROUS);
    575             } else {
    576                 System.out.println("All Permissions:");
    577                 System.out.println("");
    578                 doListPermissions(groupList, groups, labels, summary,
    579                         -10000, 10000);
    580             }
    581         } catch (RemoteException e) {
    582             System.err.println(e.toString());
    583             System.err.println(PM_NOT_RUNNING_ERR);
    584         }
    585     }
    586 
    587     private void doListPermissions(ArrayList<String> groupList,
    588             boolean groups, boolean labels, boolean summary,
    589             int startProtectionLevel, int endProtectionLevel)
    590             throws RemoteException {
    591         for (int i=0; i<groupList.size(); i++) {
    592             String groupName = groupList.get(i);
    593             String prefix = "";
    594             if (groups) {
    595                 if (i > 0) System.out.println("");
    596                 if (groupName != null) {
    597                     PermissionGroupInfo pgi = mPm.getPermissionGroupInfo(
    598                             groupName, 0);
    599                     if (summary) {
    600                         Resources res = getResources(pgi);
    601                         if (res != null) {
    602                             System.out.print(loadText(pgi, pgi.labelRes,
    603                                     pgi.nonLocalizedLabel) + ": ");
    604                         } else {
    605                             System.out.print(pgi.name + ": ");
    606 
    607                         }
    608                     } else {
    609                         System.out.println((labels ? "+ " : "")
    610                                 + "group:" + pgi.name);
    611                         if (labels) {
    612                             System.out.println("  package:" + pgi.packageName);
    613                             Resources res = getResources(pgi);
    614                             if (res != null) {
    615                                 System.out.println("  label:"
    616                                         + loadText(pgi, pgi.labelRes,
    617                                                 pgi.nonLocalizedLabel));
    618                                 System.out.println("  description:"
    619                                         + loadText(pgi, pgi.descriptionRes,
    620                                                 pgi.nonLocalizedDescription));
    621                             }
    622                         }
    623                     }
    624                 } else {
    625                     System.out.println(((labels && !summary)
    626                             ? "+ " : "") + "ungrouped:");
    627                 }
    628                 prefix = "  ";
    629             }
    630             List<PermissionInfo> ps = mPm.queryPermissionsByGroup(
    631                     groupList.get(i), 0);
    632             int count = ps.size();
    633             boolean first = true;
    634             for (int p = 0 ; p < count ; p++) {
    635                 PermissionInfo pi = ps.get(p);
    636                 if (groups && groupName == null && pi.group != null) {
    637                     continue;
    638                 }
    639                 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
    640                 if (base < startProtectionLevel
    641                         || base > endProtectionLevel) {
    642                     continue;
    643                 }
    644                 if (summary) {
    645                     if (first) {
    646                         first = false;
    647                     } else {
    648                         System.out.print(", ");
    649                     }
    650                     Resources res = getResources(pi);
    651                     if (res != null) {
    652                         System.out.print(loadText(pi, pi.labelRes,
    653                                 pi.nonLocalizedLabel));
    654                     } else {
    655                         System.out.print(pi.name);
    656                     }
    657                 } else {
    658                     System.out.println(prefix + (labels ? "+ " : "")
    659                             + "permission:" + pi.name);
    660                     if (labels) {
    661                         System.out.println(prefix + "  package:" + pi.packageName);
    662                         Resources res = getResources(pi);
    663                         if (res != null) {
    664                             System.out.println(prefix + "  label:"
    665                                     + loadText(pi, pi.labelRes,
    666                                             pi.nonLocalizedLabel));
    667                             System.out.println(prefix + "  description:"
    668                                     + loadText(pi, pi.descriptionRes,
    669                                             pi.nonLocalizedDescription));
    670                         }
    671                         System.out.println(prefix + "  protectionLevel:"
    672                                 + PermissionInfo.protectionToString(pi.protectionLevel));
    673                     }
    674                 }
    675             }
    676 
    677             if (summary) {
    678                 System.out.println("");
    679             }
    680         }
    681     }
    682 
    683     private void runPath() {
    684         String pkg = nextArg();
    685         if (pkg == null) {
    686             System.err.println("Error: no package specified");
    687             return;
    688         }
    689         displayPackageFilePath(pkg);
    690     }
    691 
    692     private void runDump() {
    693         String pkg = nextArg();
    694         if (pkg == null) {
    695             System.err.println("Error: no package specified");
    696             return;
    697         }
    698         ActivityManager.dumpPackageStateStatic(FileDescriptor.out, pkg);
    699     }
    700 
    701     class PackageInstallObserver extends IPackageInstallObserver.Stub {
    702         boolean finished;
    703         int result;
    704 
    705         public void packageInstalled(String name, int status) {
    706             synchronized( this) {
    707                 finished = true;
    708                 result = status;
    709                 notifyAll();
    710             }
    711         }
    712     }
    713 
    714     /**
    715      * Converts a failure code into a string by using reflection to find a matching constant
    716      * in PackageManager.
    717      */
    718     private String installFailureToString(int result) {
    719         Field[] fields = PackageManager.class.getFields();
    720         for (Field f: fields) {
    721             if (f.getType() == int.class) {
    722                 int modifiers = f.getModifiers();
    723                 // only look at public final static fields.
    724                 if (((modifiers & Modifier.FINAL) != 0) &&
    725                         ((modifiers & Modifier.PUBLIC) != 0) &&
    726                         ((modifiers & Modifier.STATIC) != 0)) {
    727                     String fieldName = f.getName();
    728                     if (fieldName.startsWith("INSTALL_FAILED_") ||
    729                             fieldName.startsWith("INSTALL_PARSE_FAILED_")) {
    730                         // get the int value and compare it to result.
    731                         try {
    732                             if (result == f.getInt(null)) {
    733                                 return fieldName;
    734                             }
    735                         } catch (IllegalAccessException e) {
    736                             // this shouldn't happen since we only look for public static fields.
    737                         }
    738                     }
    739                 }
    740             }
    741         }
    742 
    743         // couldn't find a matching constant? return the value
    744         return Integer.toString(result);
    745     }
    746 
    747     private void runSetInstallLocation() {
    748         int loc;
    749 
    750         String arg = nextArg();
    751         if (arg == null) {
    752             System.err.println("Error: no install location specified.");
    753             return;
    754         }
    755         try {
    756             loc = Integer.parseInt(arg);
    757         } catch (NumberFormatException e) {
    758             System.err.println("Error: install location has to be a number.");
    759             return;
    760         }
    761         try {
    762             if (!mPm.setInstallLocation(loc)) {
    763                 System.err.println("Error: install location has to be a number.");
    764             }
    765         } catch (RemoteException e) {
    766             System.err.println(e.toString());
    767             System.err.println(PM_NOT_RUNNING_ERR);
    768         }
    769     }
    770 
    771     private void runGetInstallLocation() {
    772         try {
    773             int loc = mPm.getInstallLocation();
    774             String locStr = "invalid";
    775             if (loc == PackageHelper.APP_INSTALL_AUTO) {
    776                 locStr = "auto";
    777             } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
    778                 locStr = "internal";
    779             } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
    780                 locStr = "external";
    781             }
    782             System.out.println(loc + "[" + locStr + "]");
    783         } catch (RemoteException e) {
    784             System.err.println(e.toString());
    785             System.err.println(PM_NOT_RUNNING_ERR);
    786         }
    787     }
    788 
    789     private void runInstall() {
    790         int installFlags = PackageManager.INSTALL_ALL_USERS;
    791         String installerPackageName = null;
    792 
    793         String opt;
    794 
    795         String algo = null;
    796         byte[] iv = null;
    797         byte[] key = null;
    798 
    799         String macAlgo = null;
    800         byte[] macKey = null;
    801         byte[] tag = null;
    802         String originatingUriString = null;
    803         String referrer = null;
    804 
    805         while ((opt=nextOption()) != null) {
    806             if (opt.equals("-l")) {
    807                 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
    808             } else if (opt.equals("-r")) {
    809                 installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
    810             } else if (opt.equals("-i")) {
    811                 installerPackageName = nextOptionData();
    812                 if (installerPackageName == null) {
    813                     System.err.println("Error: no value specified for -i");
    814                     return;
    815                 }
    816             } else if (opt.equals("-t")) {
    817                 installFlags |= PackageManager.INSTALL_ALLOW_TEST;
    818             } else if (opt.equals("-s")) {
    819                 // Override if -s option is specified.
    820                 installFlags |= PackageManager.INSTALL_EXTERNAL;
    821             } else if (opt.equals("-f")) {
    822                 // Override if -s option is specified.
    823                 installFlags |= PackageManager.INSTALL_INTERNAL;
    824             } else if (opt.equals("-d")) {
    825                 installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
    826             } else if (opt.equals("--algo")) {
    827                 algo = nextOptionData();
    828                 if (algo == null) {
    829                     System.err.println("Error: must supply argument for --algo");
    830                     return;
    831                 }
    832             } else if (opt.equals("--iv")) {
    833                 iv = hexToBytes(nextOptionData());
    834                 if (iv == null) {
    835                     System.err.println("Error: must supply argument for --iv");
    836                     return;
    837                 }
    838             } else if (opt.equals("--key")) {
    839                 key = hexToBytes(nextOptionData());
    840                 if (key == null) {
    841                     System.err.println("Error: must supply argument for --key");
    842                     return;
    843                 }
    844             } else if (opt.equals("--macalgo")) {
    845                 macAlgo = nextOptionData();
    846                 if (macAlgo == null) {
    847                     System.err.println("Error: must supply argument for --macalgo");
    848                     return;
    849                 }
    850             } else if (opt.equals("--mackey")) {
    851                 macKey = hexToBytes(nextOptionData());
    852                 if (macKey == null) {
    853                     System.err.println("Error: must supply argument for --mackey");
    854                     return;
    855                 }
    856             } else if (opt.equals("--tag")) {
    857                 tag = hexToBytes(nextOptionData());
    858                 if (tag == null) {
    859                     System.err.println("Error: must supply argument for --tag");
    860                     return;
    861                 }
    862             } else if (opt.equals("--originating-uri")) {
    863                 originatingUriString = nextOptionData();
    864                 if (originatingUriString == null) {
    865                     System.err.println("Error: must supply argument for --originating-uri");
    866                     return;
    867                 }
    868             } else if (opt.equals("--referrer")) {
    869                 referrer = nextOptionData();
    870                 if (referrer == null) {
    871                     System.err.println("Error: must supply argument for --referrer");
    872                     return;
    873                 }
    874             } else {
    875                 System.err.println("Error: Unknown option: " + opt);
    876                 return;
    877             }
    878         }
    879 
    880         final ContainerEncryptionParams encryptionParams;
    881         if (algo != null || iv != null || key != null || macAlgo != null || macKey != null
    882                 || tag != null) {
    883             if (algo == null || iv == null || key == null) {
    884                 System.err.println("Error: all of --algo, --iv, and --key must be specified");
    885                 return;
    886             }
    887 
    888             if (macAlgo != null || macKey != null || tag != null) {
    889                 if (macAlgo == null || macKey == null || tag == null) {
    890                     System.err.println("Error: all of --macalgo, --mackey, and --tag must "
    891                             + "be specified");
    892                     return;
    893                 }
    894             }
    895 
    896             try {
    897                 final SecretKey encKey = new SecretKeySpec(key, "RAW");
    898 
    899                 final SecretKey macSecretKey;
    900                 if (macKey == null || macKey.length == 0) {
    901                     macSecretKey = null;
    902                 } else {
    903                     macSecretKey = new SecretKeySpec(macKey, "RAW");
    904                 }
    905 
    906                 encryptionParams = new ContainerEncryptionParams(algo, new IvParameterSpec(iv),
    907                         encKey, macAlgo, null, macSecretKey, tag, -1, -1, -1);
    908             } catch (InvalidAlgorithmParameterException e) {
    909                 e.printStackTrace();
    910                 return;
    911             }
    912         } else {
    913             encryptionParams = null;
    914         }
    915 
    916         final Uri apkURI;
    917         final Uri verificationURI;
    918         final Uri originatingURI;
    919         final Uri referrerURI;
    920 
    921         if (originatingUriString != null) {
    922             originatingURI = Uri.parse(originatingUriString);
    923         } else {
    924             originatingURI = null;
    925         }
    926 
    927         if (referrer != null) {
    928             referrerURI = Uri.parse(referrer);
    929         } else {
    930             referrerURI = null;
    931         }
    932 
    933         // Populate apkURI, must be present
    934         final String apkFilePath = nextArg();
    935         System.err.println("\tpkg: " + apkFilePath);
    936         if (apkFilePath != null) {
    937             apkURI = Uri.fromFile(new File(apkFilePath));
    938         } else {
    939             System.err.println("Error: no package specified");
    940             return;
    941         }
    942 
    943         // Populate verificationURI, optionally present
    944         final String verificationFilePath = nextArg();
    945         if (verificationFilePath != null) {
    946             System.err.println("\tver: " + verificationFilePath);
    947             verificationURI = Uri.fromFile(new File(verificationFilePath));
    948         } else {
    949             verificationURI = null;
    950         }
    951 
    952         PackageInstallObserver obs = new PackageInstallObserver();
    953         try {
    954             VerificationParams verificationParams = new VerificationParams(verificationURI,
    955                     originatingURI, referrerURI, VerificationParams.NO_UID, null);
    956 
    957             mPm.installPackageWithVerificationAndEncryption(apkURI, obs, installFlags,
    958                     installerPackageName, verificationParams, encryptionParams);
    959 
    960             synchronized (obs) {
    961                 while (!obs.finished) {
    962                     try {
    963                         obs.wait();
    964                     } catch (InterruptedException e) {
    965                     }
    966                 }
    967                 if (obs.result == PackageManager.INSTALL_SUCCEEDED) {
    968                     System.out.println("Success");
    969                 } else {
    970                     System.err.println("Failure ["
    971                             + installFailureToString(obs.result)
    972                             + "]");
    973                 }
    974             }
    975         } catch (RemoteException e) {
    976             System.err.println(e.toString());
    977             System.err.println(PM_NOT_RUNNING_ERR);
    978         }
    979     }
    980 
    981     /**
    982      * Convert a string containing hex-encoded bytes to a byte array.
    983      *
    984      * @param input String containing hex-encoded bytes
    985      * @return input as an array of bytes
    986      */
    987     private byte[] hexToBytes(String input) {
    988         if (input == null) {
    989             return null;
    990         }
    991 
    992         final int inputLength = input.length();
    993         if ((inputLength % 2) != 0) {
    994             System.err.print("Invalid length; must be multiple of 2");
    995             return null;
    996         }
    997 
    998         final int byteLength = inputLength / 2;
    999         final byte[] output = new byte[byteLength];
   1000 
   1001         int inputIndex = 0;
   1002         int byteIndex = 0;
   1003         while (inputIndex < inputLength) {
   1004             output[byteIndex++] = (byte) Integer.parseInt(
   1005                     input.substring(inputIndex, inputIndex + 2), 16);
   1006             inputIndex += 2;
   1007         }
   1008 
   1009         return output;
   1010     }
   1011 
   1012     public void runCreateUser() {
   1013         String name;
   1014         String arg = nextArg();
   1015         if (arg == null) {
   1016             System.err.println("Error: no user name specified.");
   1017             return;
   1018         }
   1019         name = arg;
   1020         try {
   1021             final UserInfo info = mUm.createUser(name, 0);
   1022             if (info != null) {
   1023                 System.out.println("Success: created user id " + info.id);
   1024             } else {
   1025                 System.err.println("Error: couldn't create User.");
   1026             }
   1027         } catch (RemoteException e) {
   1028             System.err.println(e.toString());
   1029             System.err.println(PM_NOT_RUNNING_ERR);
   1030         }
   1031 
   1032     }
   1033 
   1034     public void runRemoveUser() {
   1035         int userId;
   1036         String arg = nextArg();
   1037         if (arg == null) {
   1038             System.err.println("Error: no user id specified.");
   1039             return;
   1040         }
   1041         try {
   1042             userId = Integer.parseInt(arg);
   1043         } catch (NumberFormatException e) {
   1044             System.err.println("Error: user id '" + arg + "' is not a number.");
   1045             return;
   1046         }
   1047         try {
   1048             if (mUm.removeUser(userId)) {
   1049                 System.out.println("Success: removed user");
   1050             } else {
   1051                 System.err.println("Error: couldn't remove user id " + userId);
   1052             }
   1053         } catch (RemoteException e) {
   1054             System.err.println(e.toString());
   1055             System.err.println(PM_NOT_RUNNING_ERR);
   1056         }
   1057     }
   1058 
   1059     public void runListUsers() {
   1060         try {
   1061             List<UserInfo> users = mUm.getUsers(false);
   1062             if (users == null) {
   1063                 System.err.println("Error: couldn't get users");
   1064             } else {
   1065                 System.out.println("Users:");
   1066                 for (int i = 0; i < users.size(); i++) {
   1067                     System.out.println("\t" + users.get(i).toString());
   1068                 }
   1069             }
   1070         } catch (RemoteException e) {
   1071             System.err.println(e.toString());
   1072             System.err.println(PM_NOT_RUNNING_ERR);
   1073         }
   1074     }
   1075 
   1076     public void runGetMaxUsers() {
   1077         System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers());
   1078     }
   1079 
   1080     class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
   1081         boolean finished;
   1082         boolean result;
   1083 
   1084         public void packageDeleted(String packageName, int returnCode) {
   1085             synchronized (this) {
   1086                 finished = true;
   1087                 result = returnCode == PackageManager.DELETE_SUCCEEDED;
   1088                 notifyAll();
   1089             }
   1090         }
   1091     }
   1092 
   1093     private void runUninstall() {
   1094         int unInstallFlags = PackageManager.DELETE_ALL_USERS;
   1095 
   1096         String opt;
   1097         while ((opt=nextOption()) != null) {
   1098             if (opt.equals("-k")) {
   1099                 unInstallFlags |= PackageManager.DELETE_KEEP_DATA;
   1100             } else {
   1101                 System.err.println("Error: Unknown option: " + opt);
   1102                 return;
   1103             }
   1104         }
   1105 
   1106         String pkg = nextArg();
   1107         if (pkg == null) {
   1108             System.err.println("Error: no package specified");
   1109             showUsage();
   1110             return;
   1111         }
   1112         boolean result = deletePackage(pkg, unInstallFlags);
   1113         if (result) {
   1114             System.out.println("Success");
   1115         } else {
   1116             System.out.println("Failure");
   1117         }
   1118     }
   1119 
   1120     private boolean deletePackage(String pkg, int unInstallFlags) {
   1121         PackageDeleteObserver obs = new PackageDeleteObserver();
   1122         try {
   1123             mPm.deletePackageAsUser(pkg, obs, UserHandle.USER_OWNER, unInstallFlags);
   1124 
   1125             synchronized (obs) {
   1126                 while (!obs.finished) {
   1127                     try {
   1128                         obs.wait();
   1129                     } catch (InterruptedException e) {
   1130                     }
   1131                 }
   1132             }
   1133         } catch (RemoteException e) {
   1134             System.err.println(e.toString());
   1135             System.err.println(PM_NOT_RUNNING_ERR);
   1136         }
   1137         return obs.result;
   1138     }
   1139 
   1140     static class ClearDataObserver extends IPackageDataObserver.Stub {
   1141         boolean finished;
   1142         boolean result;
   1143 
   1144         @Override
   1145         public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
   1146             synchronized (this) {
   1147                 finished = true;
   1148                 result = succeeded;
   1149                 notifyAll();
   1150             }
   1151         }
   1152 
   1153     }
   1154 
   1155     private void runClear() {
   1156         int userId = 0;
   1157         String option = nextOption();
   1158         if (option != null && option.equals("--user")) {
   1159             String optionData = nextOptionData();
   1160             if (optionData == null || !isNumber(optionData)) {
   1161                 System.err.println("Error: no USER_ID specified");
   1162                 showUsage();
   1163                 return;
   1164             } else {
   1165                 userId = Integer.parseInt(optionData);
   1166             }
   1167         }
   1168 
   1169         String pkg = nextArg();
   1170         if (pkg == null) {
   1171             System.err.println("Error: no package specified");
   1172             showUsage();
   1173             return;
   1174         }
   1175 
   1176         ClearDataObserver obs = new ClearDataObserver();
   1177         try {
   1178             ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId);
   1179             synchronized (obs) {
   1180                 while (!obs.finished) {
   1181                     try {
   1182                         obs.wait();
   1183                     } catch (InterruptedException e) {
   1184                     }
   1185                 }
   1186             }
   1187 
   1188             if (obs.result) {
   1189                 System.err.println("Success");
   1190             } else {
   1191                 System.err.println("Failed");
   1192             }
   1193         } catch (RemoteException e) {
   1194             System.err.println(e.toString());
   1195             System.err.println(PM_NOT_RUNNING_ERR);
   1196         }
   1197     }
   1198 
   1199     private static String enabledSettingToString(int state) {
   1200         switch (state) {
   1201             case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
   1202                 return "default";
   1203             case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
   1204                 return "enabled";
   1205             case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
   1206                 return "disabled";
   1207             case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
   1208                 return "disabled-user";
   1209             case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
   1210                 return "disabled-until-used";
   1211         }
   1212         return "unknown";
   1213     }
   1214 
   1215     private static boolean isNumber(String s) {
   1216         try {
   1217             Integer.parseInt(s);
   1218         } catch (NumberFormatException nfe) {
   1219             return false;
   1220         }
   1221         return true;
   1222     }
   1223 
   1224     private void runSetEnabledSetting(int state) {
   1225         int userId = 0;
   1226         String option = nextOption();
   1227         if (option != null && option.equals("--user")) {
   1228             String optionData = nextOptionData();
   1229             if (optionData == null || !isNumber(optionData)) {
   1230                 System.err.println("Error: no USER_ID specified");
   1231                 showUsage();
   1232                 return;
   1233             } else {
   1234                 userId = Integer.parseInt(optionData);
   1235             }
   1236         }
   1237 
   1238         String pkg = nextArg();
   1239         if (pkg == null) {
   1240             System.err.println("Error: no package or component specified");
   1241             showUsage();
   1242             return;
   1243         }
   1244         ComponentName cn = ComponentName.unflattenFromString(pkg);
   1245         if (cn == null) {
   1246             try {
   1247                 mPm.setApplicationEnabledSetting(pkg, state, 0, userId,
   1248                         "shell:" + android.os.Process.myUid());
   1249                 System.err.println("Package " + pkg + " new state: "
   1250                         + enabledSettingToString(
   1251                         mPm.getApplicationEnabledSetting(pkg, userId)));
   1252             } catch (RemoteException e) {
   1253                 System.err.println(e.toString());
   1254                 System.err.println(PM_NOT_RUNNING_ERR);
   1255             }
   1256         } else {
   1257             try {
   1258                 mPm.setComponentEnabledSetting(cn, state, 0, userId);
   1259                 System.err.println("Component " + cn.toShortString() + " new state: "
   1260                         + enabledSettingToString(
   1261                         mPm.getComponentEnabledSetting(cn, userId)));
   1262             } catch (RemoteException e) {
   1263                 System.err.println(e.toString());
   1264                 System.err.println(PM_NOT_RUNNING_ERR);
   1265             }
   1266         }
   1267     }
   1268 
   1269     private void runSetBlockedSetting(boolean state) {
   1270         int userId = 0;
   1271         String option = nextOption();
   1272         if (option != null && option.equals("--user")) {
   1273             String optionData = nextOptionData();
   1274             if (optionData == null || !isNumber(optionData)) {
   1275                 System.err.println("Error: no USER_ID specified");
   1276                 showUsage();
   1277                 return;
   1278             } else {
   1279                 userId = Integer.parseInt(optionData);
   1280             }
   1281         }
   1282 
   1283         String pkg = nextArg();
   1284         if (pkg == null) {
   1285             System.err.println("Error: no package or component specified");
   1286             showUsage();
   1287             return;
   1288         }
   1289         try {
   1290             mPm.setApplicationBlockedSettingAsUser(pkg, state, userId);
   1291             System.err.println("Package " + pkg + " new blocked state: "
   1292                     + mPm.getApplicationBlockedSettingAsUser(pkg, userId));
   1293         } catch (RemoteException e) {
   1294             System.err.println(e.toString());
   1295             System.err.println(PM_NOT_RUNNING_ERR);
   1296         }
   1297     }
   1298 
   1299     private void runGrantRevokePermission(boolean grant) {
   1300         String pkg = nextArg();
   1301         if (pkg == null) {
   1302             System.err.println("Error: no package specified");
   1303             showUsage();
   1304             return;
   1305         }
   1306         String perm = nextArg();
   1307         if (perm == null) {
   1308             System.err.println("Error: no permission specified");
   1309             showUsage();
   1310             return;
   1311         }
   1312         try {
   1313             if (grant) {
   1314                 mPm.grantPermission(pkg, perm);
   1315             } else {
   1316                 mPm.revokePermission(pkg, perm);
   1317             }
   1318         } catch (RemoteException e) {
   1319             System.err.println(e.toString());
   1320             System.err.println(PM_NOT_RUNNING_ERR);
   1321         } catch (IllegalArgumentException e) {
   1322             System.err.println("Bad argument: " + e.toString());
   1323             showUsage();
   1324         } catch (SecurityException e) {
   1325             System.err.println("Operation not allowed: " + e.toString());
   1326         }
   1327     }
   1328 
   1329     private void runSetPermissionEnforced() {
   1330         final String permission = nextArg();
   1331         if (permission == null) {
   1332             System.err.println("Error: no permission specified");
   1333             showUsage();
   1334             return;
   1335         }
   1336         final String enforcedRaw = nextArg();
   1337         if (enforcedRaw == null) {
   1338             System.err.println("Error: no enforcement specified");
   1339             showUsage();
   1340             return;
   1341         }
   1342         final boolean enforced = Boolean.parseBoolean(enforcedRaw);
   1343         try {
   1344             mPm.setPermissionEnforced(permission, enforced);
   1345         } catch (RemoteException e) {
   1346             System.err.println(e.toString());
   1347             System.err.println(PM_NOT_RUNNING_ERR);
   1348         } catch (IllegalArgumentException e) {
   1349             System.err.println("Bad argument: " + e.toString());
   1350             showUsage();
   1351         } catch (SecurityException e) {
   1352             System.err.println("Operation not allowed: " + e.toString());
   1353         }
   1354     }
   1355 
   1356     static class ClearCacheObserver extends IPackageDataObserver.Stub {
   1357         boolean finished;
   1358         boolean result;
   1359 
   1360         @Override
   1361         public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
   1362             synchronized (this) {
   1363                 finished = true;
   1364                 result = succeeded;
   1365                 notifyAll();
   1366             }
   1367         }
   1368 
   1369     }
   1370 
   1371     private void runTrimCaches() {
   1372         String size = nextArg();
   1373         if (size == null) {
   1374             System.err.println("Error: no size specified");
   1375             showUsage();
   1376             return;
   1377         }
   1378         int len = size.length();
   1379         long multiplier = 1;
   1380         if (len > 1) {
   1381             char c = size.charAt(len-1);
   1382             if (c == 'K' || c == 'k') {
   1383                 multiplier = 1024L;
   1384             } else if (c == 'M' || c == 'm') {
   1385                 multiplier = 1024L*1024L;
   1386             } else if (c == 'G' || c == 'g') {
   1387                 multiplier = 1024L*1024L*1024L;
   1388             } else {
   1389                 System.err.println("Invalid suffix: " + c);
   1390                 showUsage();
   1391                 return;
   1392             }
   1393             size = size.substring(0, len-1);
   1394         }
   1395         long sizeVal;
   1396         try {
   1397             sizeVal = Long.parseLong(size) * multiplier;
   1398         } catch (NumberFormatException e) {
   1399             System.err.println("Error: expected number at: " + size);
   1400             showUsage();
   1401             return;
   1402         }
   1403         ClearDataObserver obs = new ClearDataObserver();
   1404         try {
   1405             mPm.freeStorageAndNotify(sizeVal, obs);
   1406             synchronized (obs) {
   1407                 while (!obs.finished) {
   1408                     try {
   1409                         obs.wait();
   1410                     } catch (InterruptedException e) {
   1411                     }
   1412                 }
   1413             }
   1414         } catch (RemoteException e) {
   1415             System.err.println(e.toString());
   1416             System.err.println(PM_NOT_RUNNING_ERR);
   1417         } catch (IllegalArgumentException e) {
   1418             System.err.println("Bad argument: " + e.toString());
   1419             showUsage();
   1420         } catch (SecurityException e) {
   1421             System.err.println("Operation not allowed: " + e.toString());
   1422         }
   1423     }
   1424 
   1425     /**
   1426      * Displays the package file for a package.
   1427      * @param pckg
   1428      */
   1429     private void displayPackageFilePath(String pckg) {
   1430         try {
   1431             PackageInfo info = mPm.getPackageInfo(pckg, 0, 0);
   1432             if (info != null && info.applicationInfo != null) {
   1433                 System.out.print("package:");
   1434                 System.out.println(info.applicationInfo.sourceDir);
   1435             }
   1436         } catch (RemoteException e) {
   1437             System.err.println(e.toString());
   1438             System.err.println(PM_NOT_RUNNING_ERR);
   1439         }
   1440     }
   1441 
   1442     private Resources getResources(PackageItemInfo pii) {
   1443         Resources res = mResourceCache.get(pii.packageName);
   1444         if (res != null) return res;
   1445 
   1446         try {
   1447             ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0, 0);
   1448             AssetManager am = new AssetManager();
   1449             am.addAssetPath(ai.publicSourceDir);
   1450             res = new Resources(am, null, null);
   1451             mResourceCache.put(pii.packageName, res);
   1452             return res;
   1453         } catch (RemoteException e) {
   1454             System.err.println(e.toString());
   1455             System.err.println(PM_NOT_RUNNING_ERR);
   1456             return null;
   1457         }
   1458     }
   1459 
   1460     private String nextOption() {
   1461         if (mNextArg >= mArgs.length) {
   1462             return null;
   1463         }
   1464         String arg = mArgs[mNextArg];
   1465         if (!arg.startsWith("-")) {
   1466             return null;
   1467         }
   1468         mNextArg++;
   1469         if (arg.equals("--")) {
   1470             return null;
   1471         }
   1472         if (arg.length() > 1 && arg.charAt(1) != '-') {
   1473             if (arg.length() > 2) {
   1474                 mCurArgData = arg.substring(2);
   1475                 return arg.substring(0, 2);
   1476             } else {
   1477                 mCurArgData = null;
   1478                 return arg;
   1479             }
   1480         }
   1481         mCurArgData = null;
   1482         return arg;
   1483     }
   1484 
   1485     private String nextOptionData() {
   1486         if (mCurArgData != null) {
   1487             return mCurArgData;
   1488         }
   1489         if (mNextArg >= mArgs.length) {
   1490             return null;
   1491         }
   1492         String data = mArgs[mNextArg];
   1493         mNextArg++;
   1494         return data;
   1495     }
   1496 
   1497     private String nextArg() {
   1498         if (mNextArg >= mArgs.length) {
   1499             return null;
   1500         }
   1501         String arg = mArgs[mNextArg];
   1502         mNextArg++;
   1503         return arg;
   1504     }
   1505 
   1506     private static void showUsage() {
   1507         System.err.println("usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]");
   1508         System.err.println("       pm list permission-groups");
   1509         System.err.println("       pm list permissions [-g] [-f] [-d] [-u] [GROUP]");
   1510         System.err.println("       pm list instrumentation [-f] [TARGET-PACKAGE]");
   1511         System.err.println("       pm list features");
   1512         System.err.println("       pm list libraries");
   1513         System.err.println("       pm list users");
   1514         System.err.println("       pm path PACKAGE");
   1515         System.err.println("       pm dump PACKAGE");
   1516         System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
   1517         System.err.println("                  [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]");
   1518         System.err.println("                  [--originating-uri <URI>] [--referrer <URI>] PATH");
   1519         System.err.println("       pm uninstall [-k] PACKAGE");
   1520         System.err.println("       pm clear [--user USER_ID] PACKAGE");
   1521         System.err.println("       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
   1522         System.err.println("       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
   1523         System.err.println("       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
   1524         System.err.println("       pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
   1525         System.err.println("       pm block [--user USER_ID] PACKAGE_OR_COMPONENT");
   1526         System.err.println("       pm unblock [--user USER_ID] PACKAGE_OR_COMPONENT");
   1527         System.err.println("       pm grant PACKAGE PERMISSION");
   1528         System.err.println("       pm revoke PACKAGE PERMISSION");
   1529         System.err.println("       pm set-install-location [0/auto] [1/internal] [2/external]");
   1530         System.err.println("       pm get-install-location");
   1531         System.err.println("       pm set-permission-enforced PERMISSION [true|false]");
   1532         System.err.println("       pm trim-caches DESIRED_FREE_SPACE");
   1533         System.err.println("       pm create-user USER_NAME");
   1534         System.err.println("       pm remove-user USER_ID");
   1535         System.err.println("       pm get-max-users");
   1536         System.err.println("");
   1537         System.err.println("pm list packages: prints all packages, optionally only");
   1538         System.err.println("  those whose package name contains the text in FILTER.  Options:");
   1539         System.err.println("    -f: see their associated file.");
   1540         System.err.println("    -d: filter to only show disbled packages.");
   1541         System.err.println("    -e: filter to only show enabled packages.");
   1542         System.err.println("    -s: filter to only show system packages.");
   1543         System.err.println("    -3: filter to only show third party packages.");
   1544         System.err.println("    -i: see the installer for the packages.");
   1545         System.err.println("    -u: also include uninstalled packages.");
   1546         System.err.println("");
   1547         System.err.println("pm list permission-groups: prints all known permission groups.");
   1548         System.err.println("");
   1549         System.err.println("pm list permissions: prints all known permissions, optionally only");
   1550         System.err.println("  those in GROUP.  Options:");
   1551         System.err.println("    -g: organize by group.");
   1552         System.err.println("    -f: print all information.");
   1553         System.err.println("    -s: short summary.");
   1554         System.err.println("    -d: only list dangerous permissions.");
   1555         System.err.println("    -u: list only the permissions users will see.");
   1556         System.err.println("");
   1557         System.err.println("pm list instrumentation: use to list all test packages; optionally");
   1558         System.err.println("  supply <TARGET-PACKAGE> to list the test packages for a particular");
   1559         System.err.println("  application.  Options:");
   1560         System.err.println("    -f: list the .apk file for the test package.");
   1561         System.err.println("");
   1562         System.err.println("pm list features: prints all features of the system.");
   1563         System.err.println("");
   1564         System.err.println("pm list users: prints all users on the system.");
   1565         System.err.println("");
   1566         System.err.println("pm path: print the path to the .apk of the given PACKAGE.");
   1567         System.err.println("");
   1568         System.err.println("pm dump: print system state associated w ith the given PACKAGE.");
   1569         System.err.println("");
   1570         System.err.println("pm install: installs a package to the system.  Options:");
   1571         System.err.println("    -l: install the package with FORWARD_LOCK.");
   1572         System.err.println("    -r: reinstall an exisiting app, keeping its data.");
   1573         System.err.println("    -t: allow test .apks to be installed.");
   1574         System.err.println("    -i: specify the installer package name.");
   1575         System.err.println("    -s: install package on sdcard.");
   1576         System.err.println("    -f: install package on internal flash.");
   1577         System.err.println("    -d: allow version code downgrade.");
   1578         System.err.println("");
   1579         System.err.println("pm uninstall: removes a package from the system. Options:");
   1580         System.err.println("    -k: keep the data and cache directories around after package removal.");
   1581         System.err.println("");
   1582         System.err.println("pm clear: deletes all data associated with a package.");
   1583         System.err.println("");
   1584         System.err.println("pm enable, disable, disable-user, disable-until-used: these commands");
   1585         System.err.println("  change the enabled state of a given package or component (written");
   1586         System.err.println("  as \"package/class\").");
   1587         System.err.println("");
   1588         System.err.println("pm grant, revoke: these commands either grant or revoke permissions");
   1589         System.err.println("  to applications.  Only optional permissions the application has");
   1590         System.err.println("  declared can be granted or revoked.");
   1591         System.err.println("");
   1592         System.err.println("pm get-install-location: returns the current install location.");
   1593         System.err.println("    0 [auto]: Let system decide the best location");
   1594         System.err.println("    1 [internal]: Install on internal device storage");
   1595         System.err.println("    2 [external]: Install on external media");
   1596         System.err.println("");
   1597         System.err.println("pm set-install-location: changes the default install location.");
   1598         System.err.println("  NOTE: this is only intended for debugging; using this can cause");
   1599         System.err.println("  applications to break and other undersireable behavior.");
   1600         System.err.println("    0 [auto]: Let system decide the best location");
   1601         System.err.println("    1 [internal]: Install on internal device storage");
   1602         System.err.println("    2 [external]: Install on external media");
   1603         System.err.println("");
   1604         System.err.println("pm trim-caches: trim cache files to reach the given free space.");
   1605         System.err.println("");
   1606         System.err.println("pm create-user: create a new user with the given USER_NAME,");
   1607         System.err.println("  printing the new user identifier of the user.");
   1608         System.err.println("");
   1609         System.err.println("pm remove-user: remove the user with the given USER_IDENTIFIER,");
   1610         System.err.println("  deleting all data associated with that user");
   1611     }
   1612 }
   1613