blob: 2d82c469592e7b2d04e65dcd303284f4a83e4254 [file] [log] [blame]
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Todd Kennedy60459ab2015-10-30 11:32:16 -070017package com.android.server.pm;
18
Dianne Hackbornc81983a2017-10-20 16:16:32 -070019import android.accounts.IAccountManager;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080020import android.app.ActivityManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070021import android.content.ComponentName;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070022import android.content.Context;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080023import android.content.IIntentReceiver;
24import android.content.IIntentSender;
25import android.content.Intent;
26import android.content.IntentSender;
Todd Kennedy60459ab2015-10-30 11:32:16 -070027import android.content.pm.ApplicationInfo;
28import android.content.pm.FeatureInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070029import android.content.pm.IPackageDataObserver;
Todd Kennedy60459ab2015-10-30 11:32:16 -070030import android.content.pm.IPackageManager;
31import android.content.pm.InstrumentationInfo;
32import android.content.pm.PackageInfo;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080033import android.content.pm.PackageInstaller;
Todd Kennedy60459ab2015-10-30 11:32:16 -070034import android.content.pm.PackageItemInfo;
35import android.content.pm.PackageManager;
Shunta Sato4f26cb52016-06-28 09:29:19 +090036import android.content.pm.PackageParser;
37import android.content.pm.PackageParser.ApkLite;
38import android.content.pm.PackageParser.PackageLite;
39import android.content.pm.PackageParser.PackageParserException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070040import android.content.pm.ParceledListSlice;
41import android.content.pm.PermissionGroupInfo;
42import android.content.pm.PermissionInfo;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080043import android.content.pm.PackageInstaller.SessionInfo;
44import android.content.pm.PackageInstaller.SessionParams;
Todd Kennedybe0b8892017-02-15 14:13:52 -080045import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080046import android.content.pm.ResolveInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070047import android.content.pm.UserInfo;
Svet Ganov67882122016-12-11 16:36:34 -080048import android.content.pm.VersionedPackage;
Todd Kennedy60459ab2015-10-30 11:32:16 -070049import android.content.res.AssetManager;
50import android.content.res.Resources;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080051import android.net.Uri;
52import android.os.Binder;
53import android.os.Build;
54import android.os.Bundle;
Dianne Hackborn98305522017-05-05 17:53:53 -070055import android.os.IBinder;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070056import android.os.IUserManager;
Dianne Hackbornca3872c2017-10-30 14:19:32 -070057import android.os.ParcelFileDescriptor;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070058import android.os.Process;
Todd Kennedy60459ab2015-10-30 11:32:16 -070059import android.os.RemoteException;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070060import android.os.ServiceManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070061import android.os.ShellCommand;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070062import android.os.SystemClock;
Calin Juravle8bc758b2016-03-28 12:31:52 +010063import android.os.SystemProperties;
Todd Kennedy60459ab2015-10-30 11:32:16 -070064import android.os.UserHandle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070065import android.os.UserManager;
66import android.os.storage.StorageManager;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080067import android.text.TextUtils;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070068import android.text.format.DateUtils;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080069import android.util.ArraySet;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080070import android.util.PrintWriterPrinter;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070071
Shunta Sato4f26cb52016-06-28 09:29:19 +090072import com.android.internal.content.PackageHelper;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070073import com.android.internal.util.ArrayUtils;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080074import com.android.internal.util.SizedInputStream;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080075import com.android.server.SystemConfig;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080076
Andreas Gampebdd30d82016-03-20 11:32:11 -070077import dalvik.system.DexFile;
78
Todd Kennedy72cfcd02015-11-03 17:08:55 -080079import libcore.io.IoUtils;
80
81import java.io.File;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080082import java.io.IOException;
83import java.io.InputStream;
84import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -070085import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080086import java.net.URISyntaxException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070087import java.util.ArrayList;
88import java.util.Collections;
89import java.util.Comparator;
90import java.util.List;
Svet Ganov087dce22017-09-07 15:42:16 -070091import java.util.Map;
Todd Kennedy60459ab2015-10-30 11:32:16 -070092import java.util.WeakHashMap;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080093import java.util.concurrent.SynchronousQueue;
94import java.util.concurrent.TimeUnit;
Todd Kennedy60459ab2015-10-30 11:32:16 -070095
Dianne Hackbornc81983a2017-10-20 16:16:32 -070096import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
97import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
98import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
99import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
100import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
101
Todd Kennedy60459ab2015-10-30 11:32:16 -0700102class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700103 /** Path for streaming APK content */
104 private static final String STDIN_PATH = "-";
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700105
Todd Kennedy60459ab2015-10-30 11:32:16 -0700106 final IPackageManager mInterface;
107 final private WeakHashMap<String, Resources> mResourceCache =
108 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800109 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700110 boolean mBrief;
111 boolean mComponents;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700112
113 PackageManagerShellCommand(PackageManagerService service) {
114 mInterface = service;
115 }
116
117 @Override
118 public int onCommand(String cmd) {
119 if (cmd == null) {
120 return handleDefaultCommands(cmd);
121 }
122
123 final PrintWriter pw = getOutPrintWriter();
124 try {
125 switch(cmd) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700126 case "path":
127 return runPath();
128 case "dump":
129 return runDump();
130 case "list":
131 return runList();
132 case "resolve-activity":
133 return runResolveActivity();
134 case "query-activities":
135 return runQueryIntentActivities();
136 case "query-services":
137 return runQueryIntentServices();
138 case "query-receivers":
139 return runQueryIntentReceivers();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800140 case "install":
141 return runInstall();
142 case "install-abandon":
143 case "install-destroy":
144 return runInstallAbandon();
145 case "install-commit":
146 return runInstallCommit();
147 case "install-create":
148 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800149 case "install-remove":
150 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800151 case "install-write":
152 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800153 case "install-existing":
154 return runInstallExisting();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700155 case "set-install-location":
156 return runSetInstallLocation();
157 case "get-install-location":
158 return runGetInstallLocation();
159 case "move-package":
160 return runMovePackage();
161 case "move-primary-storage":
162 return runMovePrimaryStorage();
David Brazdil493411a2016-02-01 13:48:46 +0000163 case "compile":
164 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800165 case "reconcile-secondary-dex-files":
166 return runreconcileSecondaryDexFiles();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700167 case "force-dex-opt":
168 return runForceDexOpt();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800169 case "bg-dexopt-job":
170 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700171 case "dump-profiles":
172 return runDumpProfiles();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800173 case "uninstall":
174 return runUninstall();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700175 case "clear":
176 return runClear();
177 case "enable":
178 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
179 case "disable":
180 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
181 case "disable-user":
182 return runSetEnabledSetting(
183 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
184 case "disable-until-used":
185 return runSetEnabledSetting(
186 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
187 case "default-state":
188 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
189 case "hide":
190 return runSetHiddenSetting(true);
191 case "unhide":
192 return runSetHiddenSetting(false);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000193 case "suspend":
194 return runSuspend(true);
195 case "unsuspend":
196 return runSuspend(false);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700197 case "grant":
198 return runGrantRevokePermission(true);
199 case "revoke":
200 return runGrantRevokePermission(false);
201 case "reset-permissions":
202 return runResetPermissions();
203 case "set-permission-enforced":
204 return runSetPermissionEnforced();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800205 case "get-privapp-permissions":
206 return runGetPrivappPermissions();
Todd Kennedy74629e32017-08-15 14:48:07 -0700207 case "get-privapp-deny-permissions":
208 return runGetPrivappDenyPermissions();
Svet Ganov087dce22017-09-07 15:42:16 -0700209 case "get-oem-permissions":
210 return runGetOemPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700211 case "set-app-link":
212 return runSetAppLink();
213 case "get-app-link":
214 return runGetAppLink();
215 case "trim-caches":
216 return runTrimCaches();
217 case "create-user":
218 return runCreateUser();
219 case "remove-user":
220 return runRemoveUser();
221 case "set-user-restriction":
222 return runSetUserRestriction();
223 case "get-max-users":
224 return runGetMaxUsers();
225 case "set-home-activity":
226 return runSetHomeActivity();
227 case "set-installer":
228 return runSetInstaller();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700229 case "get-instantapp-resolver":
230 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900231 case "has-feature":
232 return runHasFeature();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700233 default: {
234 String nextArg = getNextArg();
235 if (nextArg == null) {
236 if (cmd.equalsIgnoreCase("-l")) {
237 return runListPackages(false);
238 } else if (cmd.equalsIgnoreCase("-lf")) {
239 return runListPackages(true);
240 }
241 } else if (getNextArg() == null) {
242 if (cmd.equalsIgnoreCase("-p")) {
243 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
244 }
245 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700246 return handleDefaultCommands(cmd);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700247 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700248 }
249 } catch (RemoteException e) {
250 pw.println("Remote exception: " + e);
251 }
252 return -1;
253 }
254
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700255 private void setParamsSize(InstallParams params, String inPath) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700256 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700257 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
258 if (fd == null) {
259 getErrPrintWriter().println("Error: Can't open file: " + inPath);
260 throw new IllegalArgumentException("Error: Can't open file: " + inPath);
261 }
262 try {
263 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
264 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
265 null, null);
266 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
Dianne Hackborn1704e3c2017-10-31 19:55:42 +0000267 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700268 } catch (PackageParserException | IOException e) {
269 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
270 throw new IllegalArgumentException(
271 "Error: Failed to parse APK file: " + inPath, e);
272 } finally {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900273 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700274 fd.close();
275 } catch (IOException e) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900276 }
277 }
278 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700279 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700280 /**
281 * Displays the package file for a package.
282 * @param pckg
283 */
284 private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
285 PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId);
286 if (info != null && info.applicationInfo != null) {
287 final PrintWriter pw = getOutPrintWriter();
288 pw.print("package:");
289 pw.println(info.applicationInfo.sourceDir);
290 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
291 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
292 pw.print("package:");
293 pw.println(splitSourceDir);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800294 }
295 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700296 return 0;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800297 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700298 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800299 }
300
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700301 private int runPath() throws RemoteException {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000302 int userId = UserHandle.USER_SYSTEM;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700303 String option = getNextOption();
304 if (option != null && option.equals("--user")) {
305 userId = UserHandle.parseUserArg(getNextArgRequired());
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000306 }
307
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700308 String pkg = getNextArgRequired();
309 if (pkg == null) {
310 getErrPrintWriter().println("Error: no package specified");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000311 return 1;
312 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700313 return displayPackageFilePath(pkg, userId);
David Sehra8777082016-05-24 15:25:23 -0700314 }
315
Todd Kennedy60459ab2015-10-30 11:32:16 -0700316 private int runList() throws RemoteException {
317 final PrintWriter pw = getOutPrintWriter();
318 final String type = getNextArg();
319 if (type == null) {
320 pw.println("Error: didn't specify type of data to list");
321 return -1;
322 }
323 switch(type) {
324 case "features":
325 return runListFeatures();
326 case "instrumentation":
327 return runListInstrumentation();
328 case "libraries":
329 return runListLibraries();
330 case "package":
331 case "packages":
332 return runListPackages(false /*showSourceDir*/);
333 case "permission-groups":
334 return runListPermissionGroups();
335 case "permissions":
336 return runListPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700337 case "users":
338 ServiceManager.getService("user").shellCommand(
339 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
340 new String[] { "list" }, getShellCallback(), adoptResultReceiver());
341 return 0;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700342 }
343 pw.println("Error: unknown list type '" + type + "'");
344 return -1;
345 }
346
347 private int runListFeatures() throws RemoteException {
348 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700349 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700350
351 // sort by name
352 Collections.sort(list, new Comparator<FeatureInfo>() {
353 public int compare(FeatureInfo o1, FeatureInfo o2) {
354 if (o1.name == o2.name) return 0;
355 if (o1.name == null) return -1;
356 if (o2.name == null) return 1;
357 return o1.name.compareTo(o2.name);
358 }
359 });
360
361 final int count = (list != null) ? list.size() : 0;
362 for (int p = 0; p < count; p++) {
363 FeatureInfo fi = list.get(p);
364 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700365 if (fi.name != null) {
366 pw.print(fi.name);
367 if (fi.version > 0) {
368 pw.print("=");
369 pw.print(fi.version);
370 }
371 pw.println();
372 } else {
373 pw.println("reqGlEsVersion=0x"
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700374 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700375 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700376 }
377 return 0;
378 }
379
380 private int runListInstrumentation() throws RemoteException {
381 final PrintWriter pw = getOutPrintWriter();
382 boolean showSourceDir = false;
383 String targetPackage = null;
384
385 try {
386 String opt;
387 while ((opt = getNextArg()) != null) {
388 switch (opt) {
389 case "-f":
390 showSourceDir = true;
391 break;
392 default:
393 if (opt.charAt(0) != '-') {
394 targetPackage = opt;
395 } else {
396 pw.println("Error: Unknown option: " + opt);
397 return -1;
398 }
399 break;
400 }
401 }
402 } catch (RuntimeException ex) {
403 pw.println("Error: " + ex.toString());
404 return -1;
405 }
406
407 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700408 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700409
410 // sort by target package
411 Collections.sort(list, new Comparator<InstrumentationInfo>() {
412 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
413 return o1.targetPackage.compareTo(o2.targetPackage);
414 }
415 });
416
417 final int count = (list != null) ? list.size() : 0;
418 for (int p = 0; p < count; p++) {
419 final InstrumentationInfo ii = list.get(p);
420 pw.print("instrumentation:");
421 if (showSourceDir) {
422 pw.print(ii.sourceDir);
423 pw.print("=");
424 }
425 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
426 pw.print(cn.flattenToShortString());
427 pw.print(" (target=");
428 pw.print(ii.targetPackage);
429 pw.println(")");
430 }
431 return 0;
432 }
433
434 private int runListLibraries() throws RemoteException {
435 final PrintWriter pw = getOutPrintWriter();
436 final List<String> list = new ArrayList<String>();
437 final String[] rawList = mInterface.getSystemSharedLibraryNames();
438 for (int i = 0; i < rawList.length; i++) {
439 list.add(rawList[i]);
440 }
441
442 // sort by name
443 Collections.sort(list, new Comparator<String>() {
444 public int compare(String o1, String o2) {
445 if (o1 == o2) return 0;
446 if (o1 == null) return -1;
447 if (o2 == null) return 1;
448 return o1.compareTo(o2);
449 }
450 });
451
452 final int count = (list != null) ? list.size() : 0;
453 for (int p = 0; p < count; p++) {
454 String lib = list.get(p);
455 pw.print("library:");
456 pw.println(lib);
457 }
458 return 0;
459 }
460
461 private int runListPackages(boolean showSourceDir) throws RemoteException {
462 final PrintWriter pw = getOutPrintWriter();
463 int getFlags = 0;
464 boolean listDisabled = false, listEnabled = false;
465 boolean listSystem = false, listThirdParty = false;
466 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700467 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800468 boolean showVersionCode = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700469 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700470 int userId = UserHandle.USER_SYSTEM;
471 try {
472 String opt;
473 while ((opt = getNextOption()) != null) {
474 switch (opt) {
475 case "-d":
476 listDisabled = true;
477 break;
478 case "-e":
479 listEnabled = true;
480 break;
481 case "-f":
482 showSourceDir = true;
483 break;
484 case "-i":
485 listInstaller = true;
486 break;
487 case "-l":
488 // old compat
489 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700490 case "-s":
491 listSystem = true;
492 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700493 case "-U":
494 showUid = true;
495 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700496 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700497 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700498 break;
499 case "-3":
500 listThirdParty = true;
501 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800502 case "--show-versioncode":
503 showVersionCode = true;
504 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700505 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800506 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700507 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700508 case "--uid":
509 showUid = true;
510 uid = Integer.parseInt(getNextArgRequired());
511 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700512 default:
513 pw.println("Error: Unknown option: " + opt);
514 return -1;
515 }
516 }
517 } catch (RuntimeException ex) {
518 pw.println("Error: " + ex.toString());
519 return -1;
520 }
521
522 final String filter = getNextArg();
523
524 @SuppressWarnings("unchecked")
525 final ParceledListSlice<PackageInfo> slice =
526 mInterface.getInstalledPackages(getFlags, userId);
527 final List<PackageInfo> packages = slice.getList();
528
529 final int count = packages.size();
530 for (int p = 0; p < count; p++) {
531 final PackageInfo info = packages.get(p);
532 if (filter != null && !info.packageName.contains(filter)) {
533 continue;
534 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700535 if (uid != -1 && info.applicationInfo.uid != uid) {
536 continue;
537 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700538 final boolean isSystem =
539 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
540 if ((!listDisabled || !info.applicationInfo.enabled) &&
541 (!listEnabled || info.applicationInfo.enabled) &&
542 (!listSystem || isSystem) &&
543 (!listThirdParty || !isSystem)) {
544 pw.print("package:");
545 if (showSourceDir) {
546 pw.print(info.applicationInfo.sourceDir);
547 pw.print("=");
548 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800549 pw.print(info.packageName);
550 if (showVersionCode) {
551 pw.print(" versionCode:");
552 pw.print(info.applicationInfo.versionCode);
553 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700554 if (listInstaller) {
555 pw.print(" installer=");
556 pw.print(mInterface.getInstallerPackageName(info.packageName));
557 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700558 if (showUid) {
559 pw.print(" uid:");
560 pw.print(info.applicationInfo.uid);
561 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700562 pw.println();
563 }
564 }
565 return 0;
566 }
567
568 private int runListPermissionGroups() throws RemoteException {
569 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700570 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700571
572 final int count = pgs.size();
573 for (int p = 0; p < count ; p++) {
574 final PermissionGroupInfo pgi = pgs.get(p);
575 pw.print("permission group:");
576 pw.println(pgi.name);
577 }
578 return 0;
579 }
580
581 private int runListPermissions() throws RemoteException {
582 final PrintWriter pw = getOutPrintWriter();
583 boolean labels = false;
584 boolean groups = false;
585 boolean userOnly = false;
586 boolean summary = false;
587 boolean dangerousOnly = false;
588 String opt;
589 while ((opt = getNextOption()) != null) {
590 switch (opt) {
591 case "-d":
592 dangerousOnly = true;
593 break;
594 case "-f":
595 labels = true;
596 break;
597 case "-g":
598 groups = true;
599 break;
600 case "-s":
601 groups = true;
602 labels = true;
603 summary = true;
604 break;
605 case "-u":
606 userOnly = true;
607 break;
608 default:
609 pw.println("Error: Unknown option: " + opt);
610 return 1;
611 }
612 }
613
614 final ArrayList<String> groupList = new ArrayList<String>();
615 if (groups) {
616 final List<PermissionGroupInfo> infos =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700617 mInterface.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700618 final int count = infos.size();
619 for (int i = 0; i < count; i++) {
620 groupList.add(infos.get(i).name);
621 }
622 groupList.add(null);
623 } else {
624 final String grp = getNextArg();
625 groupList.add(grp);
626 }
627
628 if (dangerousOnly) {
629 pw.println("Dangerous Permissions:");
630 pw.println("");
631 doListPermissions(groupList, groups, labels, summary,
632 PermissionInfo.PROTECTION_DANGEROUS,
633 PermissionInfo.PROTECTION_DANGEROUS);
634 if (userOnly) {
635 pw.println("Normal Permissions:");
636 pw.println("");
637 doListPermissions(groupList, groups, labels, summary,
638 PermissionInfo.PROTECTION_NORMAL,
639 PermissionInfo.PROTECTION_NORMAL);
640 }
641 } else if (userOnly) {
642 pw.println("Dangerous and Normal Permissions:");
643 pw.println("");
644 doListPermissions(groupList, groups, labels, summary,
645 PermissionInfo.PROTECTION_NORMAL,
646 PermissionInfo.PROTECTION_DANGEROUS);
647 } else {
648 pw.println("All Permissions:");
649 pw.println("");
650 doListPermissions(groupList, groups, labels, summary,
651 -10000, 10000);
652 }
653 return 0;
654 }
655
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800656 private Intent parseIntentAndUser() throws URISyntaxException {
657 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700658 mBrief = false;
659 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800660 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
661 @Override
662 public boolean handleOption(String opt, ShellCommand cmd) {
663 if ("--user".equals(opt)) {
664 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
665 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700666 } else if ("--brief".equals(opt)) {
667 mBrief = true;
668 return true;
669 } else if ("--components".equals(opt)) {
670 mComponents = true;
671 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800672 }
673 return false;
674 }
675 });
676 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
677 Binder.getCallingUid(), mTargetUser, false, false, null, null);
678 return intent;
679 }
680
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700681 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
682 boolean brief, boolean components) {
683 if (brief || components) {
684 final ComponentName comp;
685 if (ri.activityInfo != null) {
686 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
687 } else if (ri.serviceInfo != null) {
688 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
689 } else if (ri.providerInfo != null) {
690 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
691 } else {
692 comp = null;
693 }
694 if (comp != null) {
695 if (!components) {
696 pr.println(prefix + "priority=" + ri.priority
697 + " preferredOrder=" + ri.preferredOrder
698 + " match=0x" + Integer.toHexString(ri.match)
699 + " specificIndex=" + ri.specificIndex
700 + " isDefault=" + ri.isDefault);
701 }
702 pr.println(prefix + comp.flattenToShortString());
703 return;
704 }
705 }
706 ri.dump(pr, prefix);
707 }
708
Dianne Hackborn99878e92015-12-02 16:27:41 -0800709 private int runResolveActivity() {
710 Intent intent;
711 try {
712 intent = parseIntentAndUser();
713 } catch (URISyntaxException e) {
714 throw new RuntimeException(e.getMessage(), e);
715 }
716 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700717 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800718 PrintWriter pw = getOutPrintWriter();
719 if (ri == null) {
720 pw.println("No activity found");
721 } else {
722 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700723 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800724 }
725 } catch (RemoteException e) {
726 throw new RuntimeException("Failed calling service", e);
727 }
728 return 0;
729 }
730
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800731 private int runQueryIntentActivities() {
732 Intent intent;
733 try {
734 intent = parseIntentAndUser();
735 } catch (URISyntaxException e) {
736 throw new RuntimeException(e.getMessage(), e);
737 }
738 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700739 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700740 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800741 PrintWriter pw = getOutPrintWriter();
742 if (result == null || result.size() <= 0) {
743 pw.println("No activities found");
744 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700745 if (!mComponents) {
746 pw.print(result.size()); pw.println(" activities found:");
747 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
748 for (int i = 0; i < result.size(); i++) {
749 pw.print(" Activity #"); pw.print(i); pw.println(":");
750 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
751 }
752 } else {
753 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
754 for (int i = 0; i < result.size(); i++) {
755 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
756 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800757 }
758 }
759 } catch (RemoteException e) {
760 throw new RuntimeException("Failed calling service", e);
761 }
762 return 0;
763 }
764
765 private int runQueryIntentServices() {
766 Intent intent;
767 try {
768 intent = parseIntentAndUser();
769 } catch (URISyntaxException e) {
770 throw new RuntimeException(e.getMessage(), e);
771 }
772 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700773 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700774 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800775 PrintWriter pw = getOutPrintWriter();
776 if (result == null || result.size() <= 0) {
777 pw.println("No services found");
778 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700779 if (!mComponents) {
780 pw.print(result.size()); pw.println(" services found:");
781 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
782 for (int i = 0; i < result.size(); i++) {
783 pw.print(" Service #"); pw.print(i); pw.println(":");
784 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
785 }
786 } else {
787 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
788 for (int i = 0; i < result.size(); i++) {
789 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
790 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800791 }
792 }
793 } catch (RemoteException e) {
794 throw new RuntimeException("Failed calling service", e);
795 }
796 return 0;
797 }
798
799 private int runQueryIntentReceivers() {
800 Intent intent;
801 try {
802 intent = parseIntentAndUser();
803 } catch (URISyntaxException e) {
804 throw new RuntimeException(e.getMessage(), e);
805 }
806 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700807 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700808 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800809 PrintWriter pw = getOutPrintWriter();
810 if (result == null || result.size() <= 0) {
811 pw.println("No receivers found");
812 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700813 if (!mComponents) {
814 pw.print(result.size()); pw.println(" receivers found:");
815 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
816 for (int i = 0; i < result.size(); i++) {
817 pw.print(" Receiver #"); pw.print(i); pw.println(":");
818 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
819 }
820 } else {
821 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
822 for (int i = 0; i < result.size(); i++) {
823 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
824 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800825 }
826 }
827 } catch (RemoteException e) {
828 throw new RuntimeException("Failed calling service", e);
829 }
830 return 0;
831 }
832
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700833 private int runInstall() throws RemoteException {
834 final PrintWriter pw = getOutPrintWriter();
835 final InstallParams params = makeInstallParams();
836 final String inPath = getNextArg();
837
838 setParamsSize(params, inPath);
839 final int sessionId = doCreateSession(params.sessionParams,
840 params.installerPackageName, params.userId);
841 boolean abandonSession = true;
842 try {
843 if (inPath == null && params.sessionParams.sizeBytes == -1) {
844 pw.println("Error: must either specify a package size or an APK file");
845 return 1;
846 }
847 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk",
848 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
849 return 1;
850 }
851 if (doCommitSession(sessionId, false /*logSuccess*/)
852 != PackageInstaller.STATUS_SUCCESS) {
853 return 1;
854 }
855 abandonSession = false;
856 pw.println("Success");
857 return 0;
858 } finally {
859 if (abandonSession) {
860 try {
861 doAbandonSession(sessionId, false /*logSuccess*/);
862 } catch (Exception ignore) {
863 }
864 }
865 }
866 }
867
868 private int runInstallAbandon() throws RemoteException {
869 final int sessionId = Integer.parseInt(getNextArg());
870 return doAbandonSession(sessionId, true /*logSuccess*/);
871 }
872
873 private int runInstallCommit() throws RemoteException {
874 final int sessionId = Integer.parseInt(getNextArg());
875 return doCommitSession(sessionId, true /*logSuccess*/);
876 }
877
878 private int runInstallCreate() throws RemoteException {
879 final PrintWriter pw = getOutPrintWriter();
880 final InstallParams installParams = makeInstallParams();
881 final int sessionId = doCreateSession(installParams.sessionParams,
882 installParams.installerPackageName, installParams.userId);
883
884 // NOTE: adb depends on parsing this string
885 pw.println("Success: created install session [" + sessionId + "]");
886 return 0;
887 }
888
889 private int runInstallWrite() throws RemoteException {
890 long sizeBytes = -1;
891
892 String opt;
893 while ((opt = getNextOption()) != null) {
894 if (opt.equals("-S")) {
895 sizeBytes = Long.parseLong(getNextArg());
896 } else {
897 throw new IllegalArgumentException("Unknown option: " + opt);
898 }
899 }
900
901 final int sessionId = Integer.parseInt(getNextArg());
902 final String splitName = getNextArg();
903 final String path = getNextArg();
904 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
905 }
906
907 private int runInstallRemove() throws RemoteException {
908 final PrintWriter pw = getOutPrintWriter();
909
910 final int sessionId = Integer.parseInt(getNextArg());
911
912 final String splitName = getNextArg();
913 if (splitName == null) {
914 pw.println("Error: split name not specified");
915 return 1;
916 }
917 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
918 }
919
920 private int runInstallExisting() throws RemoteException {
921 final PrintWriter pw = getOutPrintWriter();
922 int userId = UserHandle.USER_SYSTEM;
923 int installFlags = 0;
924 String opt;
925 while ((opt = getNextOption()) != null) {
926 switch (opt) {
927 case "--user":
928 userId = UserHandle.parseUserArg(getNextArgRequired());
929 break;
930 case "--ephemeral":
931 case "--instant":
932 installFlags |= PackageManager.INSTALL_INSTANT_APP;
933 installFlags &= ~PackageManager.INSTALL_FULL_APP;
934 break;
935 case "--full":
936 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
937 installFlags |= PackageManager.INSTALL_FULL_APP;
938 break;
939 default:
940 pw.println("Error: Unknown option: " + opt);
941 return 1;
942 }
943 }
944
945 final String packageName = getNextArg();
946 if (packageName == null) {
947 pw.println("Error: package name not specified");
948 return 1;
949 }
950
951 try {
952 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
953 installFlags, PackageManager.INSTALL_REASON_UNKNOWN);
954 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
955 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
956 }
957 pw.println("Package " + packageName + " installed for user: " + userId);
958 return 0;
959 } catch (RemoteException | NameNotFoundException e) {
960 pw.println(e.toString());
961 return 1;
962 }
963 }
964
965 private int runSetInstallLocation() throws RemoteException {
966 int loc;
967
968 String arg = getNextArg();
969 if (arg == null) {
970 getErrPrintWriter().println("Error: no install location specified.");
971 return 1;
972 }
973 try {
974 loc = Integer.parseInt(arg);
975 } catch (NumberFormatException e) {
976 getErrPrintWriter().println("Error: install location has to be a number.");
977 return 1;
978 }
979 if (!mInterface.setInstallLocation(loc)) {
980 getErrPrintWriter().println("Error: install location has to be a number.");
981 return 1;
982 }
983 return 0;
984 }
985
986 private int runGetInstallLocation() throws RemoteException {
987 int loc = mInterface.getInstallLocation();
988 String locStr = "invalid";
989 if (loc == PackageHelper.APP_INSTALL_AUTO) {
990 locStr = "auto";
991 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
992 locStr = "internal";
993 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
994 locStr = "external";
995 }
996 getOutPrintWriter().println(loc + "[" + locStr + "]");
997 return 0;
998 }
999
1000 public int runMovePackage() throws RemoteException {
1001 final String packageName = getNextArg();
1002 if (packageName == null) {
1003 getErrPrintWriter().println("Error: package name not specified");
1004 return 1;
1005 }
1006 String volumeUuid = getNextArg();
1007 if ("internal".equals(volumeUuid)) {
1008 volumeUuid = null;
1009 }
1010
1011 final int moveId = mInterface.movePackage(packageName, volumeUuid);
1012
1013 int status = mInterface.getMoveStatus(moveId);
1014 while (!PackageManager.isMoveStatusFinished(status)) {
1015 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1016 status = mInterface.getMoveStatus(moveId);
1017 }
1018
1019 if (status == PackageManager.MOVE_SUCCEEDED) {
1020 getOutPrintWriter().println("Success");
1021 return 0;
1022 } else {
1023 getErrPrintWriter().println("Failure [" + status + "]");
1024 return 1;
1025 }
1026 }
1027
1028 public int runMovePrimaryStorage() throws RemoteException {
1029 String volumeUuid = getNextArg();
1030 if ("internal".equals(volumeUuid)) {
1031 volumeUuid = null;
1032 }
1033
1034 final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1035
1036 int status = mInterface.getMoveStatus(moveId);
1037 while (!PackageManager.isMoveStatusFinished(status)) {
1038 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1039 status = mInterface.getMoveStatus(moveId);
1040 }
1041
1042 if (status == PackageManager.MOVE_SUCCEEDED) {
1043 getOutPrintWriter().println("Success");
1044 return 0;
1045 } else {
1046 getErrPrintWriter().println("Failure [" + status + "]");
1047 return 1;
1048 }
1049 }
1050
1051 private int runCompile() throws RemoteException {
1052 final PrintWriter pw = getOutPrintWriter();
1053 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1054 boolean forceCompilation = false;
1055 boolean allPackages = false;
1056 boolean clearProfileData = false;
1057 String compilerFilter = null;
1058 String compilationReason = null;
1059 String checkProfilesRaw = null;
1060 boolean secondaryDex = false;
1061 String split = null;
1062
1063 String opt;
1064 while ((opt = getNextOption()) != null) {
1065 switch (opt) {
1066 case "-a":
1067 allPackages = true;
1068 break;
1069 case "-c":
1070 clearProfileData = true;
1071 break;
1072 case "-f":
1073 forceCompilation = true;
1074 break;
1075 case "-m":
1076 compilerFilter = getNextArgRequired();
1077 break;
1078 case "-r":
1079 compilationReason = getNextArgRequired();
1080 break;
1081 case "--check-prof":
1082 checkProfilesRaw = getNextArgRequired();
1083 break;
1084 case "--reset":
1085 forceCompilation = true;
1086 clearProfileData = true;
1087 compilationReason = "install";
1088 break;
1089 case "--secondary-dex":
1090 secondaryDex = true;
1091 break;
1092 case "--split":
1093 split = getNextArgRequired();
1094 break;
1095 default:
1096 pw.println("Error: Unknown option: " + opt);
1097 return 1;
1098 }
1099 }
1100
1101 if (checkProfilesRaw != null) {
1102 if ("true".equals(checkProfilesRaw)) {
1103 checkProfiles = true;
1104 } else if ("false".equals(checkProfilesRaw)) {
1105 checkProfiles = false;
1106 } else {
1107 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1108 return 1;
1109 }
1110 }
1111
1112 if (compilerFilter != null && compilationReason != null) {
1113 pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
1114 "at the same time");
1115 return 1;
1116 }
1117 if (compilerFilter == null && compilationReason == null) {
1118 pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " +
1119 "reason (\"-r\") at the same time");
1120 return 1;
1121 }
1122
1123 if (allPackages && split != null) {
1124 pw.println("-a cannot be specified together with --split");
1125 return 1;
1126 }
1127
1128 if (secondaryDex && split != null) {
1129 pw.println("--secondary-dex cannot be specified together with --split");
1130 return 1;
1131 }
1132
1133 String targetCompilerFilter;
1134 if (compilerFilter != null) {
1135 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1136 pw.println("Error: \"" + compilerFilter +
1137 "\" is not a valid compilation filter.");
1138 return 1;
1139 }
1140 targetCompilerFilter = compilerFilter;
1141 } else {
1142 int reason = -1;
1143 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1144 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1145 compilationReason)) {
1146 reason = i;
1147 break;
1148 }
1149 }
1150 if (reason == -1) {
1151 pw.println("Error: Unknown compilation reason: " + compilationReason);
1152 return 1;
1153 }
1154 targetCompilerFilter =
1155 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1156 }
1157
1158
1159 List<String> packageNames = null;
1160 if (allPackages) {
1161 packageNames = mInterface.getAllPackages();
1162 } else {
1163 String packageName = getNextArg();
1164 if (packageName == null) {
1165 pw.println("Error: package name not specified");
1166 return 1;
1167 }
1168 packageNames = Collections.singletonList(packageName);
1169 }
1170
1171 List<String> failedPackages = new ArrayList<>();
Andreas Gampecbd08d42017-11-20 17:03:17 -08001172 int index = 0;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001173 for (String packageName : packageNames) {
1174 if (clearProfileData) {
1175 mInterface.clearApplicationProfileData(packageName);
1176 }
1177
Andreas Gampecbd08d42017-11-20 17:03:17 -08001178 if (allPackages) {
1179 pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1180 pw.flush();
1181 }
1182
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001183 boolean result = secondaryDex
1184 ? mInterface.performDexOptSecondary(packageName,
1185 targetCompilerFilter, forceCompilation)
1186 : mInterface.performDexOptMode(packageName,
1187 checkProfiles, targetCompilerFilter, forceCompilation,
1188 true /* bootComplete */, split);
1189 if (!result) {
1190 failedPackages.add(packageName);
1191 }
1192 }
1193
1194 if (failedPackages.isEmpty()) {
1195 pw.println("Success");
1196 return 0;
1197 } else if (failedPackages.size() == 1) {
1198 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1199 return 1;
1200 } else {
1201 pw.print("Failure: the following packages could not be compiled: ");
1202 boolean is_first = true;
1203 for (String packageName : failedPackages) {
1204 if (is_first) {
1205 is_first = false;
1206 } else {
1207 pw.print(", ");
1208 }
1209 pw.print(packageName);
1210 }
1211 pw.println();
1212 return 1;
1213 }
1214 }
1215
1216 private int runreconcileSecondaryDexFiles() throws RemoteException {
1217 String packageName = getNextArg();
1218 mInterface.reconcileSecondaryDexFiles(packageName);
1219 return 0;
1220 }
1221
1222 public int runForceDexOpt() throws RemoteException {
1223 mInterface.forceDexOpt(getNextArgRequired());
1224 return 0;
1225 }
1226
1227 private int runDexoptJob() throws RemoteException {
Arthur Eubanks09dd1ec2017-09-15 09:28:51 -07001228 String arg;
1229 List<String> packageNames = new ArrayList<>();
1230 while ((arg = getNextArg()) != null) {
1231 packageNames.add(arg);
1232 }
1233 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1234 packageNames);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001235 return result ? 0 : -1;
1236 }
1237
1238 private int runDumpProfiles() throws RemoteException {
1239 String packageName = getNextArg();
1240 mInterface.dumpProfiles(packageName);
1241 return 0;
1242 }
1243
1244 private int runUninstall() throws RemoteException {
1245 final PrintWriter pw = getOutPrintWriter();
1246 int flags = 0;
1247 int userId = UserHandle.USER_ALL;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001248 long versionCode = PackageManager.VERSION_CODE_HIGHEST;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001249
1250 String opt;
1251 while ((opt = getNextOption()) != null) {
1252 switch (opt) {
1253 case "-k":
1254 flags |= PackageManager.DELETE_KEEP_DATA;
1255 break;
1256 case "--user":
1257 userId = UserHandle.parseUserArg(getNextArgRequired());
1258 break;
1259 case "--versionCode":
Dianne Hackborn3accca02013-09-20 09:32:11 -07001260 versionCode = Long.parseLong(getNextArgRequired());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001261 break;
1262 default:
1263 pw.println("Error: Unknown option: " + opt);
1264 return 1;
1265 }
1266 }
1267
1268 final String packageName = getNextArg();
1269 if (packageName == null) {
1270 pw.println("Error: package name not specified");
1271 return 1;
1272 }
1273
1274 // if a split is specified, just remove it and not the whole package
1275 final String splitName = getNextArg();
1276 if (splitName != null) {
1277 return runRemoveSplit(packageName, splitName);
1278 }
1279
1280 userId = translateUserId(userId, "runUninstall");
1281 if (userId == UserHandle.USER_ALL) {
1282 userId = UserHandle.USER_SYSTEM;
1283 flags |= PackageManager.DELETE_ALL_USERS;
1284 } else {
1285 final PackageInfo info = mInterface.getPackageInfo(packageName,
1286 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1287 if (info == null) {
1288 pw.println("Failure [not installed for " + userId + "]");
1289 return 1;
1290 }
1291 final boolean isSystem =
1292 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1293 // If we are being asked to delete a system app for just one
1294 // user set flag so it disables rather than reverting to system
1295 // version of the app.
1296 if (isSystem) {
1297 flags |= PackageManager.DELETE_SYSTEM_APP;
1298 }
1299 }
1300
1301 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1302 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1303 versionCode), null /*callerPackageName*/, flags,
1304 receiver.getIntentSender(), userId);
1305
1306 final Intent result = receiver.getResult();
1307 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1308 PackageInstaller.STATUS_FAILURE);
1309 if (status == PackageInstaller.STATUS_SUCCESS) {
1310 pw.println("Success");
1311 return 0;
1312 } else {
1313 pw.println("Failure ["
1314 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1315 return 1;
1316 }
1317 }
1318
1319 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1320 final PrintWriter pw = getOutPrintWriter();
1321 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1322 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1323 sessionParams.appPackageName = packageName;
1324 final int sessionId =
1325 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1326 boolean abandonSession = true;
1327 try {
1328 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1329 != PackageInstaller.STATUS_SUCCESS) {
1330 return 1;
1331 }
1332 if (doCommitSession(sessionId, false /*logSuccess*/)
1333 != PackageInstaller.STATUS_SUCCESS) {
1334 return 1;
1335 }
1336 abandonSession = false;
1337 pw.println("Success");
1338 return 0;
1339 } finally {
1340 if (abandonSession) {
1341 try {
1342 doAbandonSession(sessionId, false /*logSuccess*/);
1343 } catch (Exception ignore) {
1344 }
1345 }
1346 }
1347 }
1348
1349 static class ClearDataObserver extends IPackageDataObserver.Stub {
1350 boolean finished;
1351 boolean result;
1352
1353 @Override
1354 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1355 synchronized (this) {
1356 finished = true;
1357 result = succeeded;
1358 notifyAll();
1359 }
1360 }
1361 }
1362
1363 private int runClear() throws RemoteException {
1364 int userId = UserHandle.USER_SYSTEM;
1365 String option = getNextOption();
1366 if (option != null && option.equals("--user")) {
1367 userId = UserHandle.parseUserArg(getNextArgRequired());
1368 }
1369
1370 String pkg = getNextArg();
1371 if (pkg == null) {
1372 getErrPrintWriter().println("Error: no package specified");
1373 return 1;
1374 }
1375
1376 ClearDataObserver obs = new ClearDataObserver();
Christopher Tate1d99c392017-12-07 16:54:04 -08001377 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001378 synchronized (obs) {
1379 while (!obs.finished) {
1380 try {
1381 obs.wait();
1382 } catch (InterruptedException e) {
1383 }
1384 }
1385 }
1386
1387 if (obs.result) {
1388 getOutPrintWriter().println("Success");
1389 return 0;
1390 } else {
1391 getErrPrintWriter().println("Failed");
1392 return 1;
1393 }
1394 }
1395
1396 private static String enabledSettingToString(int state) {
1397 switch (state) {
1398 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1399 return "default";
1400 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1401 return "enabled";
1402 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1403 return "disabled";
1404 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1405 return "disabled-user";
1406 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1407 return "disabled-until-used";
1408 }
1409 return "unknown";
1410 }
1411
1412 private int runSetEnabledSetting(int state) throws RemoteException {
1413 int userId = UserHandle.USER_SYSTEM;
1414 String option = getNextOption();
1415 if (option != null && option.equals("--user")) {
1416 userId = UserHandle.parseUserArg(getNextArgRequired());
1417 }
1418
1419 String pkg = getNextArg();
1420 if (pkg == null) {
1421 getErrPrintWriter().println("Error: no package or component specified");
1422 return 1;
1423 }
1424 ComponentName cn = ComponentName.unflattenFromString(pkg);
1425 if (cn == null) {
1426 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1427 "shell:" + android.os.Process.myUid());
1428 getOutPrintWriter().println("Package " + pkg + " new state: "
1429 + enabledSettingToString(
1430 mInterface.getApplicationEnabledSetting(pkg, userId)));
1431 return 0;
1432 } else {
1433 mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1434 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1435 + enabledSettingToString(
1436 mInterface.getComponentEnabledSetting(cn, userId)));
1437 return 0;
1438 }
1439 }
1440
1441 private int runSetHiddenSetting(boolean state) throws RemoteException {
1442 int userId = UserHandle.USER_SYSTEM;
1443 String option = getNextOption();
1444 if (option != null && option.equals("--user")) {
1445 userId = UserHandle.parseUserArg(getNextArgRequired());
1446 }
1447
1448 String pkg = getNextArg();
1449 if (pkg == null) {
1450 getErrPrintWriter().println("Error: no package or component specified");
1451 return 1;
1452 }
1453 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1454 getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1455 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1456 return 0;
1457 }
1458
1459 private int runSuspend(boolean suspendedState) {
1460 final PrintWriter pw = getOutPrintWriter();
1461 int userId = UserHandle.USER_SYSTEM;
1462 String opt;
1463 while ((opt = getNextOption()) != null) {
1464 switch (opt) {
1465 case "--user":
1466 userId = UserHandle.parseUserArg(getNextArgRequired());
1467 break;
1468 default:
1469 pw.println("Error: Unknown option: " + opt);
1470 return 1;
1471 }
1472 }
1473
1474 String packageName = getNextArg();
1475 if (packageName == null) {
1476 pw.println("Error: package name not specified");
1477 return 1;
1478 }
1479
1480 try {
1481 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
1482 userId);
1483 pw.println("Package " + packageName + " new suspended state: "
1484 + mInterface.isPackageSuspendedForUser(packageName, userId));
1485 return 0;
1486 } catch (RemoteException | IllegalArgumentException e) {
1487 pw.println(e.toString());
1488 return 1;
1489 }
1490 }
1491
1492 private int runGrantRevokePermission(boolean grant) throws RemoteException {
1493 int userId = UserHandle.USER_SYSTEM;
1494
1495 String opt = null;
1496 while ((opt = getNextOption()) != null) {
1497 if (opt.equals("--user")) {
1498 userId = UserHandle.parseUserArg(getNextArgRequired());
1499 }
1500 }
1501
1502 String pkg = getNextArg();
1503 if (pkg == null) {
1504 getErrPrintWriter().println("Error: no package specified");
1505 return 1;
1506 }
1507 String perm = getNextArg();
1508 if (perm == null) {
1509 getErrPrintWriter().println("Error: no permission specified");
1510 return 1;
1511 }
1512
1513 if (grant) {
1514 mInterface.grantRuntimePermission(pkg, perm, userId);
1515 } else {
1516 mInterface.revokeRuntimePermission(pkg, perm, userId);
1517 }
1518 return 0;
1519 }
1520
1521 private int runResetPermissions() throws RemoteException {
1522 mInterface.resetRuntimePermissions();
1523 return 0;
1524 }
1525
1526 private int runSetPermissionEnforced() throws RemoteException {
1527 final String permission = getNextArg();
1528 if (permission == null) {
1529 getErrPrintWriter().println("Error: no permission specified");
1530 return 1;
1531 }
1532 final String enforcedRaw = getNextArg();
1533 if (enforcedRaw == null) {
1534 getErrPrintWriter().println("Error: no enforcement specified");
1535 return 1;
1536 }
1537 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
1538 return 0;
1539 }
1540
Jiyong Park002fdbd2017-02-13 20:50:31 +09001541 private boolean isVendorApp(String pkg) {
1542 try {
1543 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1544 return info != null && info.applicationInfo.isVendor();
1545 } catch (RemoteException e) {
1546 return false;
1547 }
1548 }
1549
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001550 private int runGetPrivappPermissions() {
1551 final String pkg = getNextArg();
1552 if (pkg == null) {
1553 getErrPrintWriter().println("Error: no package specified.");
1554 return 1;
1555 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001556
1557 ArraySet<String> privAppPermissions = isVendorApp(pkg) ?
1558 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg)
1559 : SystemConfig.getInstance().getPrivAppPermissions(pkg);
1560
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001561 getOutPrintWriter().println(privAppPermissions == null
1562 ? "{}" : privAppPermissions.toString());
1563 return 0;
1564 }
1565
1566 private int runGetPrivappDenyPermissions() {
1567 final String pkg = getNextArg();
1568 if (pkg == null) {
1569 getErrPrintWriter().println("Error: no package specified.");
1570 return 1;
1571 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001572
1573 ArraySet<String> privAppPermissions = isVendorApp(pkg) ?
1574 SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg)
1575 : SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
1576
1577 getOutPrintWriter().println(privAppPermissions == null
1578 ? "{}" : privAppPermissions.toString());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001579 return 0;
1580 }
1581
1582 private int runGetOemPermissions() {
1583 final String pkg = getNextArg();
1584 if (pkg == null) {
1585 getErrPrintWriter().println("Error: no package specified.");
1586 return 1;
1587 }
1588 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
1589 .getOemPermissions(pkg);
1590 if (oemPermissions == null || oemPermissions.isEmpty()) {
1591 getOutPrintWriter().println("{}");
1592 } else {
1593 oemPermissions.forEach((permission, granted) ->
1594 getOutPrintWriter().println(permission + " granted:" + granted)
1595 );
1596 }
1597 return 0;
1598 }
1599
1600 private String linkStateToString(int state) {
1601 switch (state) {
1602 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
1603 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
1604 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
1605 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
1606 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
1607 }
1608 return "Unknown link state: " + state;
1609 }
1610
1611 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
1612 private int runSetAppLink() throws RemoteException {
1613 int userId = UserHandle.USER_SYSTEM;
1614
1615 String opt;
1616 while ((opt = getNextOption()) != null) {
1617 if (opt.equals("--user")) {
1618 userId = UserHandle.parseUserArg(getNextArgRequired());
1619 } else {
1620 getErrPrintWriter().println("Error: unknown option: " + opt);
1621 return 1;
1622 }
1623 }
1624
1625 // Package name to act on; required
1626 final String pkg = getNextArg();
1627 if (pkg == null) {
1628 getErrPrintWriter().println("Error: no package specified.");
1629 return 1;
1630 }
1631
1632 // State to apply; {always|ask|never|undefined}, required
1633 final String modeString = getNextArg();
1634 if (modeString == null) {
1635 getErrPrintWriter().println("Error: no app link state specified.");
1636 return 1;
1637 }
1638
1639 final int newMode;
1640 switch (modeString.toLowerCase()) {
1641 case "undefined":
1642 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1643 break;
1644
1645 case "always":
1646 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1647 break;
1648
1649 case "ask":
1650 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1651 break;
1652
1653 case "always-ask":
1654 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
1655 break;
1656
1657 case "never":
1658 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
1659 break;
1660
1661 default:
1662 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
1663 return 1;
1664 }
1665
1666 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1667 if (info == null) {
1668 getErrPrintWriter().println("Error: package " + pkg + " not found.");
1669 return 1;
1670 }
1671
1672 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1673 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1674 return 1;
1675 }
1676
1677 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
1678 getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
1679 return 1;
1680 }
1681
1682 return 0;
1683 }
1684
1685 // pm get-app-link [--user USER_ID] PACKAGE
1686 private int runGetAppLink() throws RemoteException {
1687 int userId = UserHandle.USER_SYSTEM;
1688
1689 String opt;
1690 while ((opt = getNextOption()) != null) {
1691 if (opt.equals("--user")) {
1692 userId = UserHandle.parseUserArg(getNextArgRequired());
1693 } else {
1694 getErrPrintWriter().println("Error: unknown option: " + opt);
1695 return 1;
1696 }
1697 }
1698
1699 // Package name to act on; required
1700 final String pkg = getNextArg();
1701 if (pkg == null) {
1702 getErrPrintWriter().println("Error: no package specified.");
1703 return 1;
1704 }
1705
1706 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1707 if (info == null) {
1708 getErrPrintWriter().println("Error: package " + pkg + " not found.");
1709 return 1;
1710 }
1711
1712 if ((info.applicationInfo.privateFlags
1713 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1714 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1715 return 1;
1716 }
1717
1718 getOutPrintWriter().println(linkStateToString(
1719 mInterface.getIntentVerificationStatus(pkg, userId)));
1720
1721 return 0;
1722 }
1723
1724 private int runTrimCaches() throws RemoteException {
1725 String size = getNextArg();
1726 if (size == null) {
1727 getErrPrintWriter().println("Error: no size specified");
1728 return 1;
1729 }
1730 long multiplier = 1;
1731 int len = size.length();
1732 char c = size.charAt(len - 1);
1733 if (c < '0' || c > '9') {
1734 if (c == 'K' || c == 'k') {
1735 multiplier = 1024L;
1736 } else if (c == 'M' || c == 'm') {
1737 multiplier = 1024L*1024L;
1738 } else if (c == 'G' || c == 'g') {
1739 multiplier = 1024L*1024L*1024L;
1740 } else {
1741 getErrPrintWriter().println("Invalid suffix: " + c);
1742 return 1;
1743 }
1744 size = size.substring(0, len-1);
1745 }
1746 long sizeVal;
1747 try {
1748 sizeVal = Long.parseLong(size) * multiplier;
1749 } catch (NumberFormatException e) {
1750 getErrPrintWriter().println("Error: expected number at: " + size);
1751 return 1;
1752 }
1753 String volumeUuid = getNextArg();
1754 if ("internal".equals(volumeUuid)) {
1755 volumeUuid = null;
1756 }
1757 ClearDataObserver obs = new ClearDataObserver();
1758 mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
1759 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
1760 synchronized (obs) {
1761 while (!obs.finished) {
1762 try {
1763 obs.wait();
1764 } catch (InterruptedException e) {
1765 }
1766 }
1767 }
1768 return 0;
1769 }
1770
1771 private static boolean isNumber(String s) {
1772 try {
1773 Integer.parseInt(s);
1774 } catch (NumberFormatException nfe) {
1775 return false;
1776 }
1777 return true;
1778 }
1779
1780 public int runCreateUser() throws RemoteException {
1781 String name;
1782 int userId = -1;
1783 int flags = 0;
1784 String opt;
1785 while ((opt = getNextOption()) != null) {
1786 if ("--profileOf".equals(opt)) {
1787 userId = UserHandle.parseUserArg(getNextArgRequired());
1788 } else if ("--managed".equals(opt)) {
1789 flags |= UserInfo.FLAG_MANAGED_PROFILE;
1790 } else if ("--restricted".equals(opt)) {
1791 flags |= UserInfo.FLAG_RESTRICTED;
1792 } else if ("--ephemeral".equals(opt)) {
1793 flags |= UserInfo.FLAG_EPHEMERAL;
1794 } else if ("--guest".equals(opt)) {
1795 flags |= UserInfo.FLAG_GUEST;
1796 } else if ("--demo".equals(opt)) {
1797 flags |= UserInfo.FLAG_DEMO;
1798 } else {
1799 getErrPrintWriter().println("Error: unknown option " + opt);
1800 return 1;
1801 }
1802 }
1803 String arg = getNextArg();
1804 if (arg == null) {
1805 getErrPrintWriter().println("Error: no user name specified.");
1806 return 1;
1807 }
1808 name = arg;
1809 UserInfo info;
1810 IUserManager um = IUserManager.Stub.asInterface(
1811 ServiceManager.getService(Context.USER_SERVICE));
1812 IAccountManager accm = IAccountManager.Stub.asInterface(
1813 ServiceManager.getService(Context.ACCOUNT_SERVICE));
1814 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
1815 // In non-split user mode, userId can only be SYSTEM
1816 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
1817 info = um.createRestrictedProfile(name, parentUserId);
1818 accm.addSharedAccountsFromParentUser(parentUserId, userId,
1819 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
1820 } else if (userId < 0) {
1821 info = um.createUser(name, flags);
1822 } else {
1823 info = um.createProfileForUser(name, flags, userId, null);
1824 }
1825
1826 if (info != null) {
1827 getOutPrintWriter().println("Success: created user id " + info.id);
1828 return 0;
1829 } else {
1830 getErrPrintWriter().println("Error: couldn't create User.");
1831 return 1;
1832 }
1833 }
1834
1835 public int runRemoveUser() throws RemoteException {
1836 int userId;
1837 String arg = getNextArg();
1838 if (arg == null) {
1839 getErrPrintWriter().println("Error: no user id specified.");
1840 return 1;
1841 }
1842 userId = UserHandle.parseUserArg(arg);
1843 IUserManager um = IUserManager.Stub.asInterface(
1844 ServiceManager.getService(Context.USER_SERVICE));
1845 if (um.removeUser(userId)) {
1846 getOutPrintWriter().println("Success: removed user");
1847 return 0;
1848 } else {
1849 getErrPrintWriter().println("Error: couldn't remove user id " + userId);
1850 return 1;
1851 }
1852 }
1853
1854 public int runSetUserRestriction() throws RemoteException {
1855 int userId = UserHandle.USER_SYSTEM;
1856 String opt = getNextOption();
1857 if (opt != null && "--user".equals(opt)) {
1858 userId = UserHandle.parseUserArg(getNextArgRequired());
1859 }
1860
1861 String restriction = getNextArg();
1862 String arg = getNextArg();
1863 boolean value;
1864 if ("1".equals(arg)) {
1865 value = true;
1866 } else if ("0".equals(arg)) {
1867 value = false;
1868 } else {
1869 getErrPrintWriter().println("Error: valid value not specified");
1870 return 1;
1871 }
1872 IUserManager um = IUserManager.Stub.asInterface(
1873 ServiceManager.getService(Context.USER_SERVICE));
1874 um.setUserRestriction(restriction, value, userId);
1875 return 0;
1876 }
1877
1878 public int runGetMaxUsers() {
1879 getOutPrintWriter().println("Maximum supported users: "
1880 + UserManager.getMaxSupportedUsers());
1881 return 0;
1882 }
1883
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001884 private static class InstallParams {
1885 SessionParams sessionParams;
1886 String installerPackageName;
1887 int userId = UserHandle.USER_ALL;
1888 }
1889
1890 private InstallParams makeInstallParams() {
1891 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
1892 final InstallParams params = new InstallParams();
1893 params.sessionParams = sessionParams;
1894 String opt;
Patrick Baumanna9333492017-11-28 15:23:49 -08001895 boolean replaceExisting = true;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001896 while ((opt = getNextOption()) != null) {
1897 switch (opt) {
1898 case "-l":
1899 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
1900 break;
Patrick Baumanna9333492017-11-28 15:23:49 -08001901 case "-r": // ignore
1902 break;
1903 case "-R":
1904 replaceExisting = false;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001905 break;
1906 case "-i":
1907 params.installerPackageName = getNextArg();
1908 if (params.installerPackageName == null) {
1909 throw new IllegalArgumentException("Missing installer package");
1910 }
1911 break;
1912 case "-t":
1913 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
1914 break;
1915 case "-s":
1916 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL;
1917 break;
1918 case "-f":
1919 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
1920 break;
1921 case "-d":
1922 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
1923 break;
1924 case "-g":
1925 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
1926 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07001927 case "--dont-kill":
1928 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
1929 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001930 case "--originating-uri":
1931 sessionParams.originatingUri = Uri.parse(getNextArg());
1932 break;
1933 case "--referrer":
1934 sessionParams.referrerUri = Uri.parse(getNextArg());
1935 break;
1936 case "-p":
1937 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
1938 sessionParams.appPackageName = getNextArg();
1939 if (sessionParams.appPackageName == null) {
1940 throw new IllegalArgumentException("Missing inherit package name");
1941 }
1942 break;
Dianne Hackbornca3872c2017-10-30 14:19:32 -07001943 case "--pkg":
1944 sessionParams.appPackageName = getNextArg();
1945 if (sessionParams.appPackageName == null) {
1946 throw new IllegalArgumentException("Missing package name");
1947 }
1948 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001949 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07001950 final long sizeBytes = Long.parseLong(getNextArg());
1951 if (sizeBytes <= 0) {
1952 throw new IllegalArgumentException("Size must be positive");
1953 }
1954 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001955 break;
1956 case "--abi":
1957 sessionParams.abiOverride = checkAbiArgument(getNextArg());
1958 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08001959 case "--ephemeral":
Dianne Hackbornca3872c2017-10-30 14:19:32 -07001960 case "--instant":
Todd Kennedybe0b8892017-02-15 14:13:52 -08001961 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08001962 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08001963 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08001964 case "--full":
1965 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
1966 break;
Todd Kennedy78a72502017-07-19 12:49:30 -07001967 case "--preload":
1968 sessionParams.setInstallAsVirtualPreload();
1969 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001970 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001971 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001972 break;
1973 case "--install-location":
1974 sessionParams.installLocation = Integer.parseInt(getNextArg());
1975 break;
1976 case "--force-uuid":
1977 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
1978 sessionParams.volumeUuid = getNextArg();
1979 if ("internal".equals(sessionParams.volumeUuid)) {
1980 sessionParams.volumeUuid = null;
1981 }
1982 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07001983 case "--force-sdk":
1984 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK;
1985 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001986 default:
1987 throw new IllegalArgumentException("Unknown option " + opt);
1988 }
Patrick Baumanna9333492017-11-28 15:23:49 -08001989 if (replaceExisting) {
1990 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1991 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001992 }
1993 return params;
1994 }
1995
Makoto Onuki4828a592016-03-15 18:06:57 -07001996 private int runSetHomeActivity() {
1997 final PrintWriter pw = getOutPrintWriter();
1998 int userId = UserHandle.USER_SYSTEM;
1999 String opt;
2000 while ((opt = getNextOption()) != null) {
2001 switch (opt) {
2002 case "--user":
2003 userId = UserHandle.parseUserArg(getNextArgRequired());
2004 break;
2005 default:
2006 pw.println("Error: Unknown option: " + opt);
2007 return 1;
2008 }
2009 }
2010
2011 String component = getNextArg();
2012 ComponentName componentName =
2013 component != null ? ComponentName.unflattenFromString(component) : null;
2014
2015 if (componentName == null) {
2016 pw.println("Error: component name not specified or invalid");
2017 return 1;
2018 }
2019
2020 try {
2021 mInterface.setHomeActivity(componentName, userId);
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002022 pw.println("Success");
Makoto Onuki4828a592016-03-15 18:06:57 -07002023 return 0;
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002024 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07002025 pw.println(e.toString());
2026 return 1;
2027 }
2028 }
2029
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002030 private int runSetInstaller() throws RemoteException {
2031 final String targetPackage = getNextArg();
2032 final String installerPackageName = getNextArg();
Fyodor Kupolov51245c72016-12-01 11:34:10 -08002033
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002034 if (targetPackage == null || installerPackageName == null) {
2035 getErrPrintWriter().println("Must provide both target and installer package names");
Todd Kennedy74629e32017-08-15 14:48:07 -07002036 return 1;
2037 }
Todd Kennedy74629e32017-08-15 14:48:07 -07002038
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002039 mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2040 getOutPrintWriter().println("Success");
Svet Ganov087dce22017-09-07 15:42:16 -07002041 return 0;
2042 }
2043
Todd Kennedy0a3f0812017-05-08 14:43:15 -07002044 private int runGetInstantAppResolver() {
2045 final PrintWriter pw = getOutPrintWriter();
2046 try {
2047 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2048 if (instantAppsResolver == null) {
2049 return 1;
2050 }
2051 pw.println(instantAppsResolver.flattenToString());
2052 return 0;
2053 } catch (Exception e) {
2054 pw.println(e.toString());
2055 return 1;
2056 }
2057 }
2058
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09002059 private int runHasFeature() {
2060 final PrintWriter err = getErrPrintWriter();
2061 final String featureName = getNextArg();
2062 if (featureName == null) {
2063 err.println("Error: expected FEATURE name");
2064 return 1;
2065 }
2066 final String versionString = getNextArg();
2067 try {
2068 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2069 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2070 getOutPrintWriter().println(hasFeature);
2071 return hasFeature ? 0 : 1;
2072 } catch (NumberFormatException e) {
2073 err.println("Error: illegal version number " + versionString);
2074 return 1;
2075 } catch (RemoteException e) {
2076 err.println(e.toString());
2077 return 1;
2078 }
2079 }
2080
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002081 private int runDump() {
2082 String pkg = getNextArg();
2083 if (pkg == null) {
2084 getErrPrintWriter().println("Error: no package specified");
2085 return 1;
2086 }
2087 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2088 return 0;
2089 }
2090
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002091 private static String checkAbiArgument(String abi) {
2092 if (TextUtils.isEmpty(abi)) {
2093 throw new IllegalArgumentException("Missing ABI argument");
2094 }
2095
2096 if ("-".equals(abi)) {
2097 return abi;
2098 }
2099
2100 final String[] supportedAbis = Build.SUPPORTED_ABIS;
2101 for (String supportedAbi : supportedAbis) {
2102 if (supportedAbi.equals(abi)) {
2103 return abi;
2104 }
2105 }
2106
2107 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2108 }
2109
2110 private int translateUserId(int userId, String logContext) {
2111 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
2112 userId, true, true, logContext, "pm command");
2113 }
2114
2115 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2116 throws RemoteException {
2117 userId = translateUserId(userId, "runInstallCreate");
2118 if (userId == UserHandle.USER_ALL) {
2119 userId = UserHandle.USER_SYSTEM;
2120 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2121 }
2122
2123 final int sessionId = mInterface.getPackageInstaller()
2124 .createSession(params, installerPackageName, userId);
2125 return sessionId;
2126 }
2127
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002128 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002129 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002130 final PrintWriter pw = getOutPrintWriter();
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002131 final ParcelFileDescriptor fd;
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002132 if (STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002133 fd = null;
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002134 } else if (inPath != null) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002135 fd = openFileForSystem(inPath, "r");
2136 if (fd == null) {
2137 return -1;
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002138 }
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002139 sizeBytes = fd.getStatSize();
2140 if (sizeBytes < 0) {
2141 getErrPrintWriter().println("Unable to get size of: " + inPath);
2142 return -1;
2143 }
2144 } else {
2145 fd = null;
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002146 }
Todd Kennedy63cc8b02016-09-22 13:25:46 -07002147 if (sizeBytes <= 0) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002148 getErrPrintWriter().println("Error: must specify a APK size");
Todd Kennedy63cc8b02016-09-22 13:25:46 -07002149 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002150 }
2151
2152 final SessionInfo info = mInterface.getPackageInstaller().getSessionInfo(sessionId);
2153
2154 PackageInstaller.Session session = null;
2155 InputStream in = null;
2156 OutputStream out = null;
2157 try {
2158 session = new PackageInstaller.Session(
2159 mInterface.getPackageInstaller().openSession(sessionId));
2160
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002161 if (fd != null) {
2162 in = new ParcelFileDescriptor.AutoCloseInputStream(fd);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002163 } else {
Dianne Hackborn2e931f52016-01-28 12:21:17 -08002164 in = new SizedInputStream(getRawInputStream(), sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002165 }
2166 out = session.openWrite(splitName, 0, sizeBytes);
2167
2168 int total = 0;
Philip P. Moltmann80e8e392017-09-18 09:07:04 -07002169 byte[] buffer = new byte[1024 * 1024];
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002170 int c;
2171 while ((c = in.read(buffer)) != -1) {
2172 total += c;
2173 out.write(buffer, 0, c);
2174
2175 if (info.sizeBytes > 0) {
2176 final float fraction = ((float) c / (float) info.sizeBytes);
2177 session.addProgress(fraction);
2178 }
2179 }
2180 session.fsync(out);
2181
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002182 if (logSuccess) {
2183 pw.println("Success: streamed " + total + " bytes");
2184 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002185 return 0;
2186 } catch (IOException e) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002187 getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002188 return 1;
2189 } finally {
2190 IoUtils.closeQuietly(out);
2191 IoUtils.closeQuietly(in);
2192 IoUtils.closeQuietly(session);
2193 }
2194 }
2195
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002196 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2197 throws RemoteException {
2198 final PrintWriter pw = getOutPrintWriter();
2199 PackageInstaller.Session session = null;
2200 try {
2201 session = new PackageInstaller.Session(
2202 mInterface.getPackageInstaller().openSession(sessionId));
2203 session.removeSplit(splitName);
2204
2205 if (logSuccess) {
2206 pw.println("Success");
2207 }
2208 return 0;
2209 } catch (IOException e) {
2210 pw.println("Error: failed to remove split; " + e.getMessage());
2211 return 1;
2212 } finally {
2213 IoUtils.closeQuietly(session);
2214 }
2215 }
2216
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002217 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002218 final PrintWriter pw = getOutPrintWriter();
2219 PackageInstaller.Session session = null;
2220 try {
2221 session = new PackageInstaller.Session(
2222 mInterface.getPackageInstaller().openSession(sessionId));
2223
2224 final LocalIntentReceiver receiver = new LocalIntentReceiver();
2225 session.commit(receiver.getIntentSender());
2226
2227 final Intent result = receiver.getResult();
2228 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2229 PackageInstaller.STATUS_FAILURE);
2230 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002231 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07002232 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002233 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002234 } else {
2235 pw.println("Failure ["
2236 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002237 }
2238 return status;
2239 } finally {
2240 IoUtils.closeQuietly(session);
2241 }
2242 }
2243
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002244 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002245 final PrintWriter pw = getOutPrintWriter();
2246 PackageInstaller.Session session = null;
2247 try {
2248 session = new PackageInstaller.Session(
2249 mInterface.getPackageInstaller().openSession(sessionId));
2250 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002251 if (logSuccess) {
2252 pw.println("Success");
2253 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002254 return 0;
2255 } finally {
2256 IoUtils.closeQuietly(session);
2257 }
2258 }
2259
Todd Kennedy60459ab2015-10-30 11:32:16 -07002260 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2261 boolean summary, int startProtectionLevel, int endProtectionLevel)
2262 throws RemoteException {
2263 final PrintWriter pw = getOutPrintWriter();
2264 final int groupCount = groupList.size();
2265 for (int i = 0; i < groupCount; i++) {
2266 String groupName = groupList.get(i);
2267 String prefix = "";
2268 if (groups) {
2269 if (i > 0) {
2270 pw.println("");
2271 }
2272 if (groupName != null) {
2273 PermissionGroupInfo pgi =
2274 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2275 if (summary) {
2276 Resources res = getResources(pgi);
2277 if (res != null) {
2278 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2279 } else {
2280 pw.print(pgi.name + ": ");
2281
2282 }
2283 } else {
2284 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2285 if (labels) {
2286 pw.println(" package:" + pgi.packageName);
2287 Resources res = getResources(pgi);
2288 if (res != null) {
2289 pw.println(" label:"
2290 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
2291 pw.println(" description:"
2292 + loadText(pgi, pgi.descriptionRes,
2293 pgi.nonLocalizedDescription));
2294 }
2295 }
2296 }
2297 } else {
2298 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
2299 }
2300 prefix = " ";
2301 }
2302 List<PermissionInfo> ps =
Jeff Sharkeyd5896632016-03-04 16:16:00 -07002303 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07002304 final int count = ps.size();
2305 boolean first = true;
2306 for (int p = 0 ; p < count ; p++) {
2307 PermissionInfo pi = ps.get(p);
2308 if (groups && groupName == null && pi.group != null) {
2309 continue;
2310 }
2311 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
2312 if (base < startProtectionLevel
2313 || base > endProtectionLevel) {
2314 continue;
2315 }
2316 if (summary) {
2317 if (first) {
2318 first = false;
2319 } else {
2320 pw.print(", ");
2321 }
2322 Resources res = getResources(pi);
2323 if (res != null) {
2324 pw.print(loadText(pi, pi.labelRes,
2325 pi.nonLocalizedLabel));
2326 } else {
2327 pw.print(pi.name);
2328 }
2329 } else {
2330 pw.println(prefix + (labels ? "+ " : "")
2331 + "permission:" + pi.name);
2332 if (labels) {
2333 pw.println(prefix + " package:" + pi.packageName);
2334 Resources res = getResources(pi);
2335 if (res != null) {
2336 pw.println(prefix + " label:"
2337 + loadText(pi, pi.labelRes,
2338 pi.nonLocalizedLabel));
2339 pw.println(prefix + " description:"
2340 + loadText(pi, pi.descriptionRes,
2341 pi.nonLocalizedDescription));
2342 }
2343 pw.println(prefix + " protectionLevel:"
2344 + PermissionInfo.protectionToString(pi.protectionLevel));
2345 }
2346 }
2347 }
2348
2349 if (summary) {
2350 pw.println("");
2351 }
2352 }
2353 }
2354
2355 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
2356 throws RemoteException {
2357 if (nonLocalized != null) {
2358 return nonLocalized.toString();
2359 }
2360 if (res != 0) {
2361 Resources r = getResources(pii);
2362 if (r != null) {
2363 try {
2364 return r.getString(res);
2365 } catch (Resources.NotFoundException e) {
2366 }
2367 }
2368 }
2369 return null;
2370 }
2371
2372 private Resources getResources(PackageItemInfo pii) throws RemoteException {
2373 Resources res = mResourceCache.get(pii.packageName);
2374 if (res != null) return res;
2375
2376 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
2377 AssetManager am = new AssetManager();
2378 am.addAssetPath(ai.publicSourceDir);
2379 res = new Resources(am, null, null);
2380 mResourceCache.put(pii.packageName, res);
2381 return res;
2382 }
2383
2384 @Override
2385 public void onHelp() {
2386 final PrintWriter pw = getOutPrintWriter();
2387 pw.println("Package manager (package) commands:");
2388 pw.println(" help");
2389 pw.println(" Print this help text.");
2390 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002391 pw.println(" path [--user USER_ID] PACKAGE");
2392 pw.println(" Print the path to the .apk of the given PACKAGE.");
2393 pw.println("");
2394 pw.println(" dump PACKAGE");
2395 pw.println(" Print various system state associated with the given PACKAGE.");
2396 pw.println("");
2397 pw.println(" list features");
2398 pw.println(" Prints all features of the system.");
2399 pw.println("");
2400 pw.println(" has-feature FEATURE_NAME [version]");
2401 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,");
2402 pw.println(" otherwise prints false and returns exit status 1");
2403 pw.println("");
2404 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
2405 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
2406 pw.println(" Options:");
2407 pw.println(" -f: dump the name of the .apk file containing the test package");
2408 pw.println("");
2409 pw.println(" list libraries");
2410 pw.println(" Prints all system libraries.");
2411 pw.println("");
2412 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
2413 pw.println(" [--uid UID] [--user USER_ID] [FILTER]");
2414 pw.println(" Prints all packages; optionally only those whose name contains");
2415 pw.println(" the text in FILTER. Options are:");
2416 pw.println(" -f: see their associated file");
2417 pw.println(" -d: filter to only show disabled packages");
2418 pw.println(" -e: filter to only show enabled packages");
2419 pw.println(" -s: filter to only show system packages");
2420 pw.println(" -3: filter to only show third party packages");
2421 pw.println(" -i: see the installer for the packages");
2422 pw.println(" -l: ignored (used for compatibility with older releases)");
2423 pw.println(" -U: also show the package UID");
2424 pw.println(" -u: also include uninstalled packages");
2425 pw.println(" --uid UID: filter to only show packages with the given UID");
2426 pw.println(" --user USER_ID: only list packages belonging to the given user");
2427 pw.println("");
2428 pw.println(" list permission-groups");
2429 pw.println(" Prints all known permission groups.");
2430 pw.println("");
2431 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
2432 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:");
2433 pw.println(" -g: organize by group");
2434 pw.println(" -f: print all information");
2435 pw.println(" -s: short summary");
2436 pw.println(" -d: only list dangerous permissions");
2437 pw.println(" -u: list only the permissions users will see");
2438 pw.println("");
2439 pw.println(" resolve-activity [--brief] [--components] [--user USER_ID] INTENT");
2440 pw.println(" Prints the activity that resolves to the given INTENT.");
2441 pw.println("");
2442 pw.println(" query-activities [--brief] [--components] [--user USER_ID] INTENT");
2443 pw.println(" Prints all activities that can handle the given INTENT.");
2444 pw.println("");
2445 pw.println(" query-services [--brief] [--components] [--user USER_ID] INTENT");
2446 pw.println(" Prints all services that can handle the given INTENT.");
2447 pw.println("");
2448 pw.println(" query-receivers [--brief] [--components] [--user USER_ID] INTENT");
2449 pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
2450 pw.println("");
2451 pw.println(" install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2452 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
2453 pw.println(" [--originating-uri URI] [---referrer URI]");
2454 pw.println(" [--abi ABI_NAME] [--force-sdk]");
2455 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
2456 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [PATH|-]");
2457 pw.println(" Install an application. Must provide the apk data to install, either as a");
2458 pw.println(" file path or '-' to read from stdin. Options are:");
2459 pw.println(" -l: forward lock application");
Patrick Baumanna9333492017-11-28 15:23:49 -08002460 pw.println(" -R: disallow replacement of existing application");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002461 pw.println(" -t: allow test packages");
2462 pw.println(" -i: specify package name of installer owning the app");
2463 pw.println(" -s: install application on sdcard");
2464 pw.println(" -f: install application on internal flash");
2465 pw.println(" -d: allow version code downgrade (debuggable packages only)");
2466 pw.println(" -p: partial application install (new split on top of existing pkg)");
2467 pw.println(" -g: grant all runtime permissions");
2468 pw.println(" -S: size in bytes of package, required for stdin");
2469 pw.println(" --user: install under the given user.");
2470 pw.println(" --dont-kill: installing a new feature split, don't kill running app");
2471 pw.println(" --originating-uri: set URI where app was downloaded from");
2472 pw.println(" --referrer: set URI that instigated the install of the app");
2473 pw.println(" --pkg: specify expected package name of app being installed");
2474 pw.println(" --abi: override the default ABI of the platform");
2475 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app");
2476 pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
2477 pw.println(" --install-location: force the install location:");
2478 pw.println(" 0=auto, 1=internal only, 2=prefer external");
2479 pw.println(" --force-uuid: force install on to disk volume with given UUID");
2480 pw.println(" --force-sdk: allow install even when existing app targets platform");
2481 pw.println(" codename but new one targets a final API level");
2482 pw.println("");
2483 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2484 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
2485 pw.println(" [--originating-uri URI] [---referrer URI]");
2486 pw.println(" [--abi ABI_NAME] [--force-sdk]");
2487 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
2488 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
2489 pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
2490 pw.println(" to push data into the session, and \"install-commit\" to finish.");
2491 pw.println("");
2492 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
2493 pw.println(" Write an apk into the given install session. If the path is '-', data");
2494 pw.println(" will be read from stdin. Options are:");
2495 pw.println(" -S: size in bytes of package, required for stdin");
2496 pw.println("");
2497 pw.println(" install-commit SESSION_ID");
2498 pw.println(" Commit the given active install session, installing the app.");
2499 pw.println("");
2500 pw.println(" install-abandon SESSION_ID");
2501 pw.println(" Delete the given active install session.");
2502 pw.println("");
2503 pw.println(" set-install-location LOCATION");
2504 pw.println(" Changes the default install location. NOTE this is only intended for debugging;");
2505 pw.println(" using this can cause applications to break and other undersireable behavior.");
2506 pw.println(" LOCATION is one of:");
2507 pw.println(" 0 [auto]: Let system decide the best location");
2508 pw.println(" 1 [internal]: Install on internal device storage");
2509 pw.println(" 2 [external]: Install on external media");
2510 pw.println("");
2511 pw.println(" get-install-location");
2512 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location.");
2513 pw.println("");
2514 pw.println(" move-package PACKAGE [internal|UUID]");
2515 pw.println("");
2516 pw.println(" move-primary-storage [internal|UUID]");
2517 pw.println("");
2518 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
2519 pw.println(" Remove the given package name from the system. May remove an entire app");
2520 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
2521 pw.println(" given app. Options are:");
2522 pw.println(" -k: keep the data and cache directories around after package removal.");
2523 pw.println(" --user: remove the app from the given user.");
2524 pw.println(" --versionCode: only uninstall if the app has the given version code.");
2525 pw.println("");
2526 pw.println(" clear [--user USER_ID] PACKAGE");
2527 pw.println(" Deletes all data associated with a package.");
2528 pw.println("");
2529 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT");
2530 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT");
2531 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
2532 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
2533 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
2534 pw.println(" These commands change the enabled state of a given package or");
2535 pw.println(" component (written as \"package/class\").");
2536 pw.println("");
2537 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT");
2538 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
2539 pw.println("");
2540 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
2541 pw.println(" Suspends the specified package (as user).");
2542 pw.println("");
2543 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
2544 pw.println(" Unsuspends the specified package (as user).");
2545 pw.println("");
2546 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
2547 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
2548 pw.println(" These commands either grant or revoke permissions to apps. The permissions");
2549 pw.println(" must be declared as used in the app's manifest, be runtime permissions");
2550 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
2551 pw.println("");
2552 pw.println(" reset-permissions");
2553 pw.println(" Revert all runtime permissions to their default state.");
2554 pw.println("");
2555 pw.println(" set-permission-enforced PERMISSION [true|false]");
2556 pw.println("");
2557 pw.println(" get-privapp-permissions TARGET-PACKAGE");
2558 pw.println(" Prints all privileged permissions for a package.");
2559 pw.println("");
2560 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE");
2561 pw.println(" Prints all privileged permissions that are denied for a package.");
2562 pw.println("");
2563 pw.println(" get-oem-permissions TARGET-PACKAGE");
2564 pw.println(" Prints all OEM permissions for a package.");
2565 pw.println("");
2566 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
2567 pw.println(" get-app-link [--user USER_ID] PACKAGE");
2568 pw.println("");
2569 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
2570 pw.println(" Trim cache files to reach the given free space.");
2571 pw.println("");
2572 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
2573 pw.println(" [--guest] USER_NAME");
2574 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
2575 pw.println(" of the user.");
2576 pw.println("");
2577 pw.println(" remove-user USER_ID");
2578 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data");
2579 pw.println(" associated with that user");
2580 pw.println("");
2581 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE");
2582 pw.println("");
2583 pw.println(" get-max-users");
2584 pw.println("");
Calin Juravleb6f844d2017-07-17 15:23:21 -07002585 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
Richard Uhler568a9692016-05-03 16:02:52 -07002586 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002587 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
David Brazdil990fb6b2016-03-01 10:02:27 +00002588 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00002589 pw.println(" -c: clear profile data before compiling");
2590 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00002591 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07002592 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01002593 pw.println(" assume-verified");
2594 pw.println(" extract");
2595 pw.println(" verify");
2596 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07002597 pw.println(" space-profile");
2598 pw.println(" space");
2599 pw.println(" speed-profile");
2600 pw.println(" speed");
2601 pw.println(" everything");
2602 pw.println(" -r: select compilation reason");
2603 pw.println(" REASON is one of:");
2604 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
2605 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
2606 }
David Brazdilcf046952016-03-08 16:40:20 +00002607 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07002608 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08002609 pw.println(" --secondary-dex: compile app secondary dex files");
Calin Juravleb6f844d2017-07-17 15:23:21 -07002610 pw.println(" --split SPLIT: compile only the given split name");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002611 pw.println("");
2612 pw.println(" force-dex-opt PACKAGE");
2613 pw.println(" Force immediate execution of dex opt for the given PACKAGE.");
2614 pw.println("");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08002615 pw.println(" bg-dexopt-job");
2616 pw.println(" Execute the background optimizations immediately.");
2617 pw.println(" Note that the command only runs the background optimizer logic. It may");
2618 pw.println(" overlap with the actual job but the job scheduler will not be able to");
2619 pw.println(" cancel it. It will also run even if the device is not in the idle");
2620 pw.println(" maintenance mode.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002621 pw.println("");
Calin Juravle1aa5f882017-01-25 01:05:50 -08002622 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
2623 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002624 pw.println("");
David Sehrcae13b02016-06-07 09:11:27 -07002625 pw.println(" dump-profiles TARGET-PACKAGE");
2626 pw.println(" Dumps method/class profile files to");
2627 pw.println(" /data/misc/profman/TARGET-PACKAGE.txt");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002628 pw.println("");
Makoto Onuki4828a592016-03-15 18:06:57 -07002629 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002630 pw.println(" Set the default home activity (aka launcher).");
2631 pw.println("");
2632 pw.println(" set-installer PACKAGE INSTALLER");
2633 pw.println(" Set installer package name");
2634 pw.println("");
2635 pw.println(" get-instantapp-resolver");
2636 pw.println(" Return the name of the component that is the current instant app installer.");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002637 pw.println();
2638 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07002639 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002640
2641 private static class LocalIntentReceiver {
2642 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
2643
2644 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
2645 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07002646 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002647 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
2648 try {
2649 mResult.offer(intent, 5, TimeUnit.SECONDS);
2650 } catch (InterruptedException e) {
2651 throw new RuntimeException(e);
2652 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002653 }
2654 };
2655
2656 public IntentSender getIntentSender() {
2657 return new IntentSender((IIntentSender) mLocalSender);
2658 }
2659
2660 public Intent getResult() {
2661 try {
2662 return mResult.take();
2663 } catch (InterruptedException e) {
2664 throw new RuntimeException(e);
2665 }
2666 }
2667 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07002668}