| /* |
| * Copyright (C) 2007 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.commands.pm; |
| |
| import android.content.ComponentName; |
| import android.content.pm.ApplicationInfo; |
| import android.content.pm.IPackageDeleteObserver; |
| import android.content.pm.IPackageInstallObserver; |
| import android.content.pm.IPackageManager; |
| import android.content.pm.InstrumentationInfo; |
| import android.content.pm.PackageInfo; |
| import android.content.pm.PackageItemInfo; |
| import android.content.pm.PackageManager; |
| import android.content.pm.PermissionGroupInfo; |
| import android.content.pm.PermissionInfo; |
| import android.content.res.AssetManager; |
| import android.content.res.Resources; |
| import android.net.Uri; |
| import android.os.RemoteException; |
| import android.os.ServiceManager; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.WeakHashMap; |
| |
| public final class Pm { |
| IPackageManager mPm; |
| |
| private WeakHashMap<String, Resources> mResourceCache |
| = new WeakHashMap<String, Resources>(); |
| |
| private String[] mArgs; |
| private int mNextArg; |
| private String mCurArgData; |
| |
| private static final String PM_NOT_RUNNING_ERR = |
| "Error: Could not access the Package Manager. Is the system running?"; |
| |
| public static void main(String[] args) { |
| new Pm().run(args); |
| } |
| |
| public void run(String[] args) { |
| boolean validCommand = false; |
| if (args.length < 1) { |
| showUsage(); |
| return; |
| } |
| |
| mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); |
| if (mPm == null) { |
| System.err.println(PM_NOT_RUNNING_ERR); |
| return; |
| } |
| |
| mArgs = args; |
| String op = args[0]; |
| mNextArg = 1; |
| |
| if ("list".equals(op)) { |
| runList(); |
| return; |
| } |
| |
| if ("path".equals(op)) { |
| runPath(); |
| return; |
| } |
| |
| if ("install".equals(op)) { |
| runInstall(); |
| return; |
| } |
| |
| if ("uninstall".equals(op)) { |
| runUninstall(); |
| return; |
| } |
| |
| if ("enable".equals(op)) { |
| runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); |
| return; |
| } |
| |
| if ("disable".equals(op)) { |
| runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); |
| return; |
| } |
| |
| try { |
| if (args.length == 1) { |
| if (args[0].equalsIgnoreCase("-l")) { |
| validCommand = true; |
| runListPackages(false); |
| } else if (args[0].equalsIgnoreCase("-lf")){ |
| validCommand = true; |
| runListPackages(true); |
| } |
| } else if (args.length == 2) { |
| if (args[0].equalsIgnoreCase("-p")) { |
| validCommand = true; |
| displayPackageFilePath(args[1]); |
| } |
| } |
| } finally { |
| if (validCommand == false) { |
| if (op != null) { |
| System.err.println("Error: unknown command '" + op + "'"); |
| } |
| showUsage(); |
| } |
| } |
| } |
| |
| /** |
| * Execute the list sub-command. |
| * |
| * pm list [package | packages] |
| * pm list permission-groups |
| * pm list permissions |
| * pm list instrumentation |
| */ |
| private void runList() { |
| String type = nextArg(); |
| if (type == null) { |
| System.err.println("Error: didn't specify type of data to list"); |
| showUsage(); |
| return; |
| } |
| if ("package".equals(type) || "packages".equals(type)) { |
| runListPackages(false); |
| } else if ("permission-groups".equals(type)) { |
| runListPermissionGroups(); |
| } else if ("permissions".equals(type)) { |
| runListPermissions(); |
| } else if ("instrumentation".equals(type)) { |
| runListInstrumentation(); |
| } else { |
| System.err.println("Error: unknown list type '" + type + "'"); |
| showUsage(); |
| } |
| } |
| |
| /** |
| * Lists all the installed packages. |
| */ |
| private void runListPackages(boolean showApplicationPackage) { |
| try { |
| String opt; |
| while ((opt=nextOption()) != null) { |
| if (opt.equals("-l")) { |
| // old compat |
| } else if (opt.equals("-lf")) { |
| showApplicationPackage = true; |
| } else if (opt.equals("-f")) { |
| showApplicationPackage = true; |
| } else { |
| System.err.println("Error: Unknown option: " + opt); |
| showUsage(); |
| return; |
| } |
| } |
| } catch (RuntimeException ex) { |
| System.err.println("Error: " + ex.toString()); |
| showUsage(); |
| return; |
| } |
| |
| try { |
| List<PackageInfo> packages = mPm.getInstalledPackages(0 /* all */); |
| |
| int count = packages.size(); |
| for (int p = 0 ; p < count ; p++) { |
| PackageInfo info = packages.get(p); |
| System.out.print("package:"); |
| if (showApplicationPackage) { |
| System.out.print(info.applicationInfo.sourceDir); |
| System.out.print("="); |
| } |
| System.out.println(info.packageName); |
| } |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| } |
| |
| /** |
| * Lists all of the installed instrumentation, or all for a given package |
| * |
| * pm list instrumentation [package] [-f] |
| */ |
| private void runListInstrumentation() { |
| int flags = 0; // flags != 0 is only used to request meta-data |
| boolean showPackage = false; |
| String targetPackage = null; |
| |
| try { |
| String opt; |
| while ((opt=nextArg()) != null) { |
| if (opt.equals("-f")) { |
| showPackage = true; |
| } else if (opt.charAt(0) != '-') { |
| targetPackage = opt; |
| } else { |
| System.err.println("Error: Unknown option: " + opt); |
| showUsage(); |
| return; |
| } |
| } |
| } catch (RuntimeException ex) { |
| System.err.println("Error: " + ex.toString()); |
| showUsage(); |
| return; |
| } |
| |
| try { |
| List<InstrumentationInfo> list = mPm.queryInstrumentation(targetPackage, flags); |
| |
| // Sort by target package |
| Collections.sort(list, new Comparator<InstrumentationInfo>() { |
| public int compare(InstrumentationInfo o1, InstrumentationInfo o2) { |
| return o1.targetPackage.compareTo(o2.targetPackage); |
| } |
| }); |
| |
| int count = (list != null) ? list.size() : 0; |
| for (int p = 0; p < count; p++) { |
| InstrumentationInfo ii = list.get(p); |
| System.out.print("instrumentation:"); |
| if (showPackage) { |
| System.out.print(ii.sourceDir); |
| System.out.print("="); |
| } |
| ComponentName cn = new ComponentName(ii.packageName, ii.name); |
| System.out.print(cn.flattenToShortString()); |
| System.out.print(" (target="); |
| System.out.print(ii.targetPackage); |
| System.out.println(")"); |
| } |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| } |
| |
| /** |
| * Lists all the known permission groups. |
| */ |
| private void runListPermissionGroups() { |
| try { |
| List<PermissionGroupInfo> pgs = mPm.getAllPermissionGroups(0); |
| |
| int count = pgs.size(); |
| for (int p = 0 ; p < count ; p++) { |
| PermissionGroupInfo pgi = pgs.get(p); |
| System.out.print("permission group:"); |
| System.out.println(pgi.name); |
| } |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| } |
| |
| private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized) { |
| if (nonLocalized != null) { |
| return nonLocalized.toString(); |
| } |
| Resources r = getResources(pii); |
| if (r != null) { |
| return r.getString(res); |
| } |
| return null; |
| } |
| |
| /** |
| * Lists all the permissions in a group. |
| */ |
| private void runListPermissions() { |
| try { |
| boolean labels = false; |
| boolean groups = false; |
| boolean userOnly = false; |
| boolean summary = false; |
| boolean dangerousOnly = false; |
| String opt; |
| while ((opt=nextOption()) != null) { |
| if (opt.equals("-f")) { |
| labels = true; |
| } else if (opt.equals("-g")) { |
| groups = true; |
| } else if (opt.equals("-s")) { |
| groups = true; |
| labels = true; |
| summary = true; |
| } else if (opt.equals("-u")) { |
| userOnly = true; |
| } else if (opt.equals("-d")) { |
| dangerousOnly = true; |
| } else { |
| System.err.println("Error: Unknown option: " + opt); |
| showUsage(); |
| return; |
| } |
| } |
| |
| String grp = nextOption(); |
| ArrayList<String> groupList = new ArrayList<String>(); |
| if (groups) { |
| List<PermissionGroupInfo> infos = |
| mPm.getAllPermissionGroups(0); |
| for (int i=0; i<infos.size(); i++) { |
| groupList.add(infos.get(i).name); |
| } |
| groupList.add(null); |
| } else { |
| groupList.add(grp); |
| } |
| |
| if (dangerousOnly) { |
| System.out.println("Dangerous Permissions:"); |
| System.out.println(""); |
| doListPermissions(groupList, groups, labels, summary, |
| PermissionInfo.PROTECTION_DANGEROUS, |
| PermissionInfo.PROTECTION_DANGEROUS); |
| if (userOnly) { |
| System.out.println("Normal Permissions:"); |
| System.out.println(""); |
| doListPermissions(groupList, groups, labels, summary, |
| PermissionInfo.PROTECTION_NORMAL, |
| PermissionInfo.PROTECTION_NORMAL); |
| } |
| } else if (userOnly) { |
| System.out.println("Dangerous and Normal Permissions:"); |
| System.out.println(""); |
| doListPermissions(groupList, groups, labels, summary, |
| PermissionInfo.PROTECTION_NORMAL, |
| PermissionInfo.PROTECTION_DANGEROUS); |
| } else { |
| System.out.println("All Permissions:"); |
| System.out.println(""); |
| doListPermissions(groupList, groups, labels, summary, |
| -10000, 10000); |
| } |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| } |
| |
| private void doListPermissions(ArrayList<String> groupList, |
| boolean groups, boolean labels, boolean summary, |
| int startProtectionLevel, int endProtectionLevel) |
| throws RemoteException { |
| for (int i=0; i<groupList.size(); i++) { |
| String groupName = groupList.get(i); |
| String prefix = ""; |
| if (groups) { |
| if (i > 0) System.out.println(""); |
| if (groupName != null) { |
| PermissionGroupInfo pgi = mPm.getPermissionGroupInfo( |
| groupName, 0); |
| if (summary) { |
| Resources res = getResources(pgi); |
| if (res != null) { |
| System.out.print(loadText(pgi, pgi.labelRes, |
| pgi.nonLocalizedLabel) + ": "); |
| } else { |
| System.out.print(pgi.name + ": "); |
| |
| } |
| } else { |
| System.out.println((labels ? "+ " : "") |
| + "group:" + pgi.name); |
| if (labels) { |
| System.out.println(" package:" + pgi.packageName); |
| Resources res = getResources(pgi); |
| if (res != null) { |
| System.out.println(" label:" |
| + loadText(pgi, pgi.labelRes, |
| pgi.nonLocalizedLabel)); |
| System.out.println(" description:" |
| + loadText(pgi, pgi.descriptionRes, |
| pgi.nonLocalizedDescription)); |
| } |
| } |
| } |
| } else { |
| System.out.println(((labels && !summary) |
| ? "+ " : "") + "ungrouped:"); |
| } |
| prefix = " "; |
| } |
| List<PermissionInfo> ps = mPm.queryPermissionsByGroup( |
| groupList.get(i), 0); |
| int count = ps.size(); |
| boolean first = true; |
| for (int p = 0 ; p < count ; p++) { |
| PermissionInfo pi = ps.get(p); |
| if (groups && groupName == null && pi.group != null) { |
| continue; |
| } |
| if (pi.protectionLevel < startProtectionLevel |
| || pi.protectionLevel > endProtectionLevel) { |
| continue; |
| } |
| if (summary) { |
| if (first) { |
| first = false; |
| } else { |
| System.out.print(", "); |
| } |
| Resources res = getResources(pi); |
| if (res != null) { |
| System.out.print(loadText(pi, pi.labelRes, |
| pi.nonLocalizedLabel)); |
| } else { |
| System.out.print(pi.name); |
| } |
| } else { |
| System.out.println(prefix + (labels ? "+ " : "") |
| + "permission:" + pi.name); |
| if (labels) { |
| System.out.println(prefix + " package:" + pi.packageName); |
| Resources res = getResources(pi); |
| if (res != null) { |
| System.out.println(prefix + " label:" |
| + loadText(pi, pi.labelRes, |
| pi.nonLocalizedLabel)); |
| System.out.println(prefix + " description:" |
| + loadText(pi, pi.descriptionRes, |
| pi.nonLocalizedDescription)); |
| } |
| String protLevel = "unknown"; |
| switch(pi.protectionLevel) { |
| case PermissionInfo.PROTECTION_DANGEROUS: |
| protLevel = "dangerous"; |
| break; |
| case PermissionInfo.PROTECTION_NORMAL: |
| protLevel = "normal"; |
| break; |
| case PermissionInfo.PROTECTION_SIGNATURE: |
| protLevel = "signature"; |
| break; |
| case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM: |
| protLevel = "signatureOrSystem"; |
| break; |
| } |
| System.out.println(prefix + " protectionLevel:" + protLevel); |
| } |
| } |
| } |
| |
| if (summary) { |
| System.out.println(""); |
| } |
| } |
| } |
| |
| private void runPath() { |
| String pkg = nextArg(); |
| if (pkg == null) { |
| System.err.println("Error: no package specified"); |
| showUsage(); |
| return; |
| } |
| displayPackageFilePath(pkg); |
| } |
| |
| class PackageInstallObserver extends IPackageInstallObserver.Stub { |
| boolean finished; |
| int result; |
| |
| public void packageInstalled(String name, int status) { |
| synchronized( this) { |
| finished = true; |
| result = status; |
| notifyAll(); |
| } |
| } |
| } |
| |
| private String installFailureToString(int result) { |
| String s; |
| switch (result) { |
| case PackageManager.INSTALL_FAILED_ALREADY_EXISTS: |
| s = "INSTALL_FAILED_ALREADY_EXISTS"; |
| break; |
| case PackageManager.INSTALL_FAILED_INVALID_APK: |
| s = "INSTALL_FAILED_INVALID_APK"; |
| break; |
| case PackageManager.INSTALL_FAILED_INVALID_URI: |
| s = "INSTALL_FAILED_INVALID_URI"; |
| break; |
| case PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE: |
| s = "INSTALL_FAILED_INSUFFICIENT_STORAGE"; |
| break; |
| case PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE: |
| s = "INSTALL_FAILED_DUPLICATE_PACKAGE"; |
| break; |
| case PackageManager.INSTALL_FAILED_NO_SHARED_USER: |
| s = "INSTALL_FAILED_NO_SHARED_USER"; |
| break; |
| case PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE: |
| s = "INSTALL_FAILED_UPDATE_INCOMPATIBLE"; |
| break; |
| case PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: |
| s = "INSTALL_FAILED_SHARED_USER_INCOMPATIBLE"; |
| break; |
| case PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY: |
| s = "INSTALL_FAILED_MISSING_SHARED_LIBRARY"; |
| break; |
| case PackageManager.INSTALL_FAILED_DEXOPT: |
| s = "INSTALL_FAILED_DEXOPT"; |
| break; |
| case PackageManager.INSTALL_FAILED_OLDER_SDK: |
| s = "INSTALL_FAILED_OLDER_SDK"; |
| break; |
| case PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER: |
| s = "INSTALL_FAILED_CONFLICTING_PROVIDER"; |
| break; |
| case PackageManager.INSTALL_FAILED_NEWER_SDK: |
| s = "INSTALL_FAILED_NEWER_SDK"; |
| break; |
| case PackageManager.INSTALL_FAILED_TEST_ONLY: |
| s = "INSTALL_FAILED_TEST_ONLY"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_NOT_APK: |
| s = "INSTALL_PARSE_FAILED_NOT_APK"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST: |
| s = "INSTALL_PARSE_FAILED_BAD_MANIFEST"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: |
| s = "INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES: |
| s = "INSTALL_PARSE_FAILED_NO_CERTIFICATES"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES: |
| s = "INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING: |
| s = "INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME: |
| s = "INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID: |
| s = "INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: |
| s = "INSTALL_PARSE_FAILED_MANIFEST_MALFORMED"; |
| break; |
| case PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY: |
| s = "INSTALL_PARSE_FAILED_MANIFEST_EMPTY"; |
| break; |
| default: |
| s = Integer.toString(result); |
| break; |
| } |
| return s; |
| } |
| |
| private void runInstall() { |
| int installFlags = 0; |
| String installerPackageName = null; |
| |
| String opt; |
| while ((opt=nextOption()) != null) { |
| if (opt.equals("-l")) { |
| installFlags |= PackageManager.INSTALL_FORWARD_LOCK; |
| } else if (opt.equals("-r")) { |
| installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; |
| } else if (opt.equals("-i")) { |
| installerPackageName = nextOptionData(); |
| if (installerPackageName == null) { |
| System.err.println("Error: no value specified for -i"); |
| showUsage(); |
| return; |
| } |
| } else if (opt.equals("-t")) { |
| installFlags |= PackageManager.INSTALL_ALLOW_TEST; |
| } else { |
| System.err.println("Error: Unknown option: " + opt); |
| showUsage(); |
| return; |
| } |
| } |
| |
| String apkFilePath = nextArg(); |
| System.err.println("\tpkg: " + apkFilePath); |
| if (apkFilePath == null) { |
| System.err.println("Error: no package specified"); |
| showUsage(); |
| return; |
| } |
| |
| PackageInstallObserver obs = new PackageInstallObserver(); |
| try { |
| mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags, |
| installerPackageName); |
| |
| synchronized (obs) { |
| while (!obs.finished) { |
| try { |
| obs.wait(); |
| } catch (InterruptedException e) { |
| } |
| } |
| if (obs.result == PackageManager.INSTALL_SUCCEEDED) { |
| System.out.println("Success"); |
| } else { |
| System.err.println("Failure [" |
| + installFailureToString(obs.result) |
| + "]"); |
| } |
| } |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| } |
| |
| class PackageDeleteObserver extends IPackageDeleteObserver.Stub { |
| boolean finished; |
| boolean result; |
| |
| public void packageDeleted(boolean succeeded) { |
| synchronized (this) { |
| finished = true; |
| result = succeeded; |
| notifyAll(); |
| } |
| } |
| } |
| |
| private void runUninstall() { |
| int unInstallFlags = 0; |
| |
| String opt = nextOption(); |
| if (opt != null && opt.equals("-k")) { |
| unInstallFlags = PackageManager.DONT_DELETE_DATA; |
| } |
| |
| String pkg = nextArg(); |
| if (pkg == null) { |
| System.err.println("Error: no package specified"); |
| showUsage(); |
| return; |
| } |
| boolean result = deletePackage(pkg, unInstallFlags); |
| if (result) { |
| System.out.println("Success"); |
| } else { |
| System.out.println("Failure"); |
| } |
| } |
| |
| private boolean deletePackage(String pkg, int unInstallFlags) { |
| PackageDeleteObserver obs = new PackageDeleteObserver(); |
| try { |
| mPm.deletePackage(pkg, obs, unInstallFlags); |
| |
| synchronized (obs) { |
| while (!obs.finished) { |
| try { |
| obs.wait(); |
| } catch (InterruptedException e) { |
| } |
| } |
| } |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| return obs.result; |
| } |
| |
| private static String enabledSettingToString(int state) { |
| switch (state) { |
| case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: |
| return "default"; |
| case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: |
| return "enabled"; |
| case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: |
| return "disabled"; |
| } |
| return "unknown"; |
| } |
| |
| private void runSetEnabledSetting(int state) { |
| String pkg = nextArg(); |
| if (pkg == null) { |
| System.err.println("Error: no package or component specified"); |
| showUsage(); |
| return; |
| } |
| ComponentName cn = ComponentName.unflattenFromString(pkg); |
| if (cn == null) { |
| try { |
| mPm.setApplicationEnabledSetting(pkg, state, 0); |
| System.err.println("Package " + pkg + " new state: " |
| + enabledSettingToString( |
| mPm.getApplicationEnabledSetting(pkg))); |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| } else { |
| try { |
| mPm.setComponentEnabledSetting(cn, state, 0); |
| System.err.println("Component " + cn.toShortString() + " new state: " |
| + enabledSettingToString( |
| mPm.getComponentEnabledSetting(cn))); |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| } |
| } |
| |
| /** |
| * Displays the package file for a package. |
| * @param pckg |
| */ |
| private void displayPackageFilePath(String pckg) { |
| try { |
| PackageInfo info = mPm.getPackageInfo(pckg, 0); |
| if (info != null && info.applicationInfo != null) { |
| System.out.print("package:"); |
| System.out.println(info.applicationInfo.sourceDir); |
| } |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| } |
| } |
| |
| private Resources getResources(PackageItemInfo pii) { |
| Resources res = mResourceCache.get(pii.packageName); |
| if (res != null) return res; |
| |
| try { |
| ApplicationInfo ai = mPm.getApplicationInfo(pii.packageName, 0); |
| AssetManager am = new AssetManager(); |
| am.addAssetPath(ai.publicSourceDir); |
| res = new Resources(am, null, null); |
| mResourceCache.put(pii.packageName, res); |
| return res; |
| } catch (RemoteException e) { |
| System.err.println(e.toString()); |
| System.err.println(PM_NOT_RUNNING_ERR); |
| return null; |
| } |
| } |
| |
| private String nextOption() { |
| if (mNextArg >= mArgs.length) { |
| return null; |
| } |
| String arg = mArgs[mNextArg]; |
| if (!arg.startsWith("-")) { |
| return null; |
| } |
| mNextArg++; |
| if (arg.equals("--")) { |
| return null; |
| } |
| if (arg.length() > 1 && arg.charAt(1) != '-') { |
| if (arg.length() > 2) { |
| mCurArgData = arg.substring(2); |
| return arg.substring(0, 2); |
| } else { |
| mCurArgData = null; |
| return arg; |
| } |
| } |
| mCurArgData = null; |
| return arg; |
| } |
| |
| private String nextOptionData() { |
| if (mCurArgData != null) { |
| return mCurArgData; |
| } |
| if (mNextArg >= mArgs.length) { |
| return null; |
| } |
| String data = mArgs[mNextArg]; |
| mNextArg++; |
| return data; |
| } |
| |
| private String nextArg() { |
| if (mNextArg >= mArgs.length) { |
| return null; |
| } |
| String arg = mArgs[mNextArg]; |
| mNextArg++; |
| return arg; |
| } |
| |
| private static void showUsage() { |
| System.err.println("usage: pm [list|path|install|uninstall]"); |
| System.err.println(" pm list packages [-f]"); |
| System.err.println(" pm list permission-groups"); |
| System.err.println(" pm list permissions [-g] [-f] [-d] [-u] [GROUP]"); |
| System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]"); |
| System.err.println(" pm path PACKAGE"); |
| System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] PATH"); |
| System.err.println(" pm uninstall [-k] PACKAGE"); |
| System.err.println(" pm enable PACKAGE_OR_COMPONENT"); |
| System.err.println(" pm disable PACKAGE_OR_COMPONENT"); |
| System.err.println(""); |
| System.err.println("The list packages command prints all packages. Options:"); |
| System.err.println(" -f: see their associated file."); |
| System.err.println(""); |
| System.err.println("The list permission-groups command prints all known"); |
| System.err.println("permission groups."); |
| System.err.println(""); |
| System.err.println("The list permissions command prints all known"); |
| System.err.println("permissions, optionally only those in GROUP. Options:"); |
| System.err.println(" -g: organize by group."); |
| System.err.println(" -f: print all information."); |
| System.err.println(" -s: short summary."); |
| System.err.println(" -d: only list dangerous permissions."); |
| System.err.println(" -u: list only the permissions users will see."); |
| System.err.println(""); |
| System.err.println("The list instrumentation command prints all instrumentations,"); |
| System.err.println("or only those that target a specified package. Options:"); |
| System.err.println(" -f: see their associated file."); |
| System.err.println(""); |
| System.err.println("The path command prints the path to the .apk of a package."); |
| System.err.println(""); |
| System.err.println("The install command installs a package to the system. Options:"); |
| System.err.println(" -l: install the package with FORWARD_LOCK."); |
| System.err.println(" -r: reinstall an exisiting app, keeping its data."); |
| System.err.println(" -t: allow test .apks to be installed."); |
| System.err.println(" -i: specify the installer package name."); |
| System.err.println(""); |
| System.err.println("The uninstall command removes a package from the system. Options:"); |
| System.err.println(" -k: keep the data and cache directories around."); |
| System.err.println("after the package removal."); |
| System.err.println(""); |
| System.err.println("The enable and disable commands change the enabled state of"); |
| System.err.println("a given package or component (written as \"package/class\")."); |
| } |
| } |