blob: 20d7b28c55e154664b46903119976e0f5151932f [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
Todd Kennedy72cfcd02015-11-03 17:08:55 -080019import android.app.ActivityManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070020import android.content.ComponentName;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080021import android.content.IIntentReceiver;
22import android.content.IIntentSender;
23import android.content.Intent;
24import android.content.IntentSender;
Todd Kennedy60459ab2015-10-30 11:32:16 -070025import android.content.pm.ApplicationInfo;
26import android.content.pm.FeatureInfo;
27import android.content.pm.IPackageManager;
28import android.content.pm.InstrumentationInfo;
29import android.content.pm.PackageInfo;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080030import android.content.pm.PackageInstaller;
Todd Kennedy60459ab2015-10-30 11:32:16 -070031import android.content.pm.PackageItemInfo;
32import android.content.pm.PackageManager;
Shunta Sato4f26cb52016-06-28 09:29:19 +090033import android.content.pm.PackageParser;
34import android.content.pm.PackageParser.ApkLite;
35import android.content.pm.PackageParser.PackageLite;
36import android.content.pm.PackageParser.PackageParserException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070037import android.content.pm.ParceledListSlice;
38import android.content.pm.PermissionGroupInfo;
39import android.content.pm.PermissionInfo;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080040import android.content.pm.PackageInstaller.SessionInfo;
41import android.content.pm.PackageInstaller.SessionParams;
Todd Kennedybe0b8892017-02-15 14:13:52 -080042import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080043import android.content.pm.ResolveInfo;
Svet Ganov67882122016-12-11 16:36:34 -080044import android.content.pm.VersionedPackage;
Todd Kennedy60459ab2015-10-30 11:32:16 -070045import android.content.res.AssetManager;
46import android.content.res.Resources;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080047import android.net.Uri;
48import android.os.Binder;
49import android.os.Build;
50import android.os.Bundle;
Dianne Hackborn98305522017-05-05 17:53:53 -070051import android.os.IBinder;
Todd Kennedy60459ab2015-10-30 11:32:16 -070052import android.os.RemoteException;
53import android.os.ShellCommand;
Calin Juravle8bc758b2016-03-28 12:31:52 +010054import android.os.SystemProperties;
Todd Kennedy60459ab2015-10-30 11:32:16 -070055import android.os.UserHandle;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080056import android.text.TextUtils;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080057import android.util.ArraySet;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080058import android.util.PrintWriterPrinter;
Shunta Sato4f26cb52016-06-28 09:29:19 +090059import com.android.internal.content.PackageHelper;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080060import com.android.internal.util.SizedInputStream;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080061import com.android.server.SystemConfig;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080062
Andreas Gampebdd30d82016-03-20 11:32:11 -070063import dalvik.system.DexFile;
64
Todd Kennedy72cfcd02015-11-03 17:08:55 -080065import libcore.io.IoUtils;
66
67import java.io.File;
68import java.io.FileInputStream;
69import java.io.IOException;
70import java.io.InputStream;
71import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -070072import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080073import java.net.URISyntaxException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070074import java.util.ArrayList;
75import java.util.Collections;
76import java.util.Comparator;
77import java.util.List;
78import java.util.WeakHashMap;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080079import java.util.concurrent.SynchronousQueue;
80import java.util.concurrent.TimeUnit;
Todd Kennedy60459ab2015-10-30 11:32:16 -070081
82class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -070083 /** Path for streaming APK content */
84 private static final String STDIN_PATH = "-";
85 /** Whether or not APK content must be streamed from stdin */
86 private static final boolean FORCE_STREAM_INSTALL = true;
87
Todd Kennedy60459ab2015-10-30 11:32:16 -070088 final IPackageManager mInterface;
89 final private WeakHashMap<String, Resources> mResourceCache =
90 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080091 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -070092 boolean mBrief;
93 boolean mComponents;
Todd Kennedy60459ab2015-10-30 11:32:16 -070094
95 PackageManagerShellCommand(PackageManagerService service) {
96 mInterface = service;
97 }
98
99 @Override
100 public int onCommand(String cmd) {
101 if (cmd == null) {
102 return handleDefaultCommands(cmd);
103 }
104
105 final PrintWriter pw = getOutPrintWriter();
106 try {
107 switch(cmd) {
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800108 case "install":
109 return runInstall();
110 case "install-abandon":
111 case "install-destroy":
112 return runInstallAbandon();
113 case "install-commit":
114 return runInstallCommit();
115 case "install-create":
116 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800117 case "install-remove":
118 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800119 case "install-write":
120 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800121 case "install-existing":
122 return runInstallExisting();
David Brazdil493411a2016-02-01 13:48:46 +0000123 case "compile":
124 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800125 case "reconcile-secondary-dex-files":
126 return runreconcileSecondaryDexFiles();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800127 case "bg-dexopt-job":
128 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700129 case "dump-profiles":
130 return runDumpProfiles();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700131 case "list":
132 return runList();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800133 case "uninstall":
134 return runUninstall();
Dianne Hackborn99878e92015-12-02 16:27:41 -0800135 case "resolve-activity":
136 return runResolveActivity();
Dianne Hackborn6ac42ae2015-12-08 17:22:10 -0800137 case "query-activities":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800138 return runQueryIntentActivities();
Dianne Hackborn6ac42ae2015-12-08 17:22:10 -0800139 case "query-services":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800140 return runQueryIntentServices();
Dianne Hackborn6ac42ae2015-12-08 17:22:10 -0800141 case "query-receivers":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800142 return runQueryIntentReceivers();
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000143 case "suspend":
144 return runSuspend(true);
145 case "unsuspend":
146 return runSuspend(false);
Makoto Onuki4828a592016-03-15 18:06:57 -0700147 case "set-home-activity":
148 return runSetHomeActivity();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800149 case "get-privapp-permissions":
150 return runGetPrivappPermissions();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700151 case "get-instantapp-resolver":
152 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900153 case "has-feature":
154 return runHasFeature();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700155 default:
156 return handleDefaultCommands(cmd);
157 }
158 } catch (RemoteException e) {
159 pw.println("Remote exception: " + e);
160 }
161 return -1;
162 }
163
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700164 private void setParamsSize(InstallParams params, String inPath) {
165 // If we're forced to stream the package, the params size
166 // must be set via command-line argument. There's nothing
167 // to do here.
168 if (FORCE_STREAM_INSTALL) {
169 return;
170 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800171 final PrintWriter pw = getOutPrintWriter();
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700172 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900173 File file = new File(inPath);
174 if (file.isFile()) {
175 try {
176 ApkLite baseApk = PackageParser.parseApkLite(file, 0);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800177 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
178 null, null);
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700179 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
180 pkgLite, false, params.sessionParams.abiOverride));
Shunta Sato4f26cb52016-06-28 09:29:19 +0900181 } catch (PackageParserException | IOException e) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700182 pw.println("Error: Failed to parse APK file: " + file);
183 throw new IllegalArgumentException(
184 "Error: Failed to parse APK file: " + file, e);
Shunta Sato4f26cb52016-06-28 09:29:19 +0900185 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700186 } else {
187 pw.println("Error: Can't open non-file: " + inPath);
188 throw new IllegalArgumentException("Error: Can't open non-file: " + inPath);
Shunta Sato4f26cb52016-06-28 09:29:19 +0900189 }
190 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700191 }
Shunta Sato4f26cb52016-06-28 09:29:19 +0900192
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700193 private int runInstall() throws RemoteException {
194 final PrintWriter pw = getOutPrintWriter();
195 final InstallParams params = makeInstallParams();
196 final String inPath = getNextArg();
197
198 setParamsSize(params, inPath);
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800199 final int sessionId = doCreateSession(params.sessionParams,
200 params.installerPackageName, params.userId);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800201 boolean abandonSession = true;
202 try {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700203 if (inPath == null && params.sessionParams.sizeBytes == -1) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800204 pw.println("Error: must either specify a package size or an APK file");
205 return 1;
206 }
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800207 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk",
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800208 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
209 return 1;
210 }
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800211 if (doCommitSession(sessionId, false /*logSuccess*/)
212 != PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800213 return 1;
214 }
215 abandonSession = false;
Todd Kennedy50ea35f2015-12-17 14:46:39 -0800216 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800217 return 0;
218 } finally {
219 if (abandonSession) {
220 try {
221 doAbandonSession(sessionId, false /*logSuccess*/);
222 } catch (Exception ignore) {
223 }
224 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800225 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800226 }
227
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000228 private int runSuspend(boolean suspendedState) {
229 final PrintWriter pw = getOutPrintWriter();
230 int userId = UserHandle.USER_SYSTEM;
231 String opt;
232 while ((opt = getNextOption()) != null) {
233 switch (opt) {
234 case "--user":
235 userId = UserHandle.parseUserArg(getNextArgRequired());
236 break;
237 default:
238 pw.println("Error: Unknown option: " + opt);
239 return 1;
240 }
241 }
242
243 String packageName = getNextArg();
244 if (packageName == null) {
245 pw.println("Error: package name not specified");
246 return 1;
247 }
248
249 try {
Andrei Stingaceanueb84b182016-01-26 18:39:55 +0000250 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
251 userId);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000252 pw.println("Package " + packageName + " new suspended state: "
Andrei Stingaceanu355b2322016-02-12 16:43:51 +0000253 + mInterface.isPackageSuspendedForUser(packageName, userId));
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000254 return 0;
Andrei Stingaceanuefc4a342016-03-22 14:43:01 +0000255 } catch (RemoteException | IllegalArgumentException e) {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000256 pw.println(e.toString());
257 return 1;
258 }
259 }
260
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800261 private int runInstallAbandon() throws RemoteException {
262 final int sessionId = Integer.parseInt(getNextArg());
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800263 return doAbandonSession(sessionId, true /*logSuccess*/);
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800264 }
265
266 private int runInstallCommit() throws RemoteException {
267 final int sessionId = Integer.parseInt(getNextArg());
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800268 return doCommitSession(sessionId, true /*logSuccess*/);
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800269 }
270
271 private int runInstallCreate() throws RemoteException {
272 final PrintWriter pw = getOutPrintWriter();
273 final InstallParams installParams = makeInstallParams();
274 final int sessionId = doCreateSession(installParams.sessionParams,
275 installParams.installerPackageName, installParams.userId);
276
277 // NOTE: adb depends on parsing this string
278 pw.println("Success: created install session [" + sessionId + "]");
279 return 0;
280 }
281
282 private int runInstallWrite() throws RemoteException {
283 long sizeBytes = -1;
284
285 String opt;
286 while ((opt = getNextOption()) != null) {
287 if (opt.equals("-S")) {
288 sizeBytes = Long.parseLong(getNextArg());
289 } else {
290 throw new IllegalArgumentException("Unknown option: " + opt);
291 }
292 }
293
294 final int sessionId = Integer.parseInt(getNextArg());
295 final String splitName = getNextArg();
296 final String path = getNextArg();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800297 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
298 }
299
300 private int runInstallRemove() throws RemoteException {
301 final PrintWriter pw = getOutPrintWriter();
302
303 final int sessionId = Integer.parseInt(getNextArg());
304
305 final String splitName = getNextArg();
306 if (splitName == null) {
307 pw.println("Error: split name not specified");
308 return 1;
309 }
310 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800311 }
312
Todd Kennedybe0b8892017-02-15 14:13:52 -0800313 private int runInstallExisting() throws RemoteException {
314 final PrintWriter pw = getOutPrintWriter();
315 int userId = UserHandle.USER_SYSTEM;
316 int installFlags = 0;
317 String opt;
318 while ((opt = getNextOption()) != null) {
319 switch (opt) {
320 case "--user":
321 userId = UserHandle.parseUserArg(getNextArgRequired());
322 break;
323 case "--ephemeral":
324 case "--instant":
325 installFlags |= PackageManager.INSTALL_INSTANT_APP;
326 installFlags &= ~PackageManager.INSTALL_FULL_APP;
327 break;
328 case "--full":
329 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
330 installFlags |= PackageManager.INSTALL_FULL_APP;
331 break;
332 default:
333 pw.println("Error: Unknown option: " + opt);
334 return 1;
335 }
336 }
337
338 final String packageName = getNextArg();
339 if (packageName == null) {
340 pw.println("Error: package name not specified");
341 return 1;
342 }
343
344 try {
345 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
346 installFlags, PackageManager.INSTALL_REASON_UNKNOWN);
347 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
348 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
349 }
350 pw.println("Package " + packageName + " installed for user: " + userId);
351 return 0;
352 } catch (RemoteException | NameNotFoundException e) {
353 pw.println(e.toString());
354 return 1;
355 }
356 }
357
David Brazdil493411a2016-02-01 13:48:46 +0000358 private int runCompile() throws RemoteException {
359 final PrintWriter pw = getOutPrintWriter();
Calin Juravle8bc758b2016-03-28 12:31:52 +0100360 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
David Brazdil493411a2016-02-01 13:48:46 +0000361 boolean forceCompilation = false;
David Brazdil990fb6b2016-03-01 10:02:27 +0000362 boolean allPackages = false;
David Brazdil9aa6db02016-03-08 12:57:12 +0000363 boolean clearProfileData = false;
Andreas Gampebdd30d82016-03-20 11:32:11 -0700364 String compilerFilter = null;
365 String compilationReason = null;
Calin Juravle8bc758b2016-03-28 12:31:52 +0100366 String checkProfilesRaw = null;
Calin Juravlec22c30e2017-01-16 19:18:48 -0800367 boolean secondaryDex = false;
Andreas Gampebdd30d82016-03-20 11:32:11 -0700368
David Brazdil493411a2016-02-01 13:48:46 +0000369 String opt;
370 while ((opt = getNextOption()) != null) {
371 switch (opt) {
David Brazdil990fb6b2016-03-01 10:02:27 +0000372 case "-a":
373 allPackages = true;
374 break;
David Brazdil9aa6db02016-03-08 12:57:12 +0000375 case "-c":
376 clearProfileData = true;
David Brazdil493411a2016-02-01 13:48:46 +0000377 break;
378 case "-f":
379 forceCompilation = true;
380 break;
David Brazdil9aa6db02016-03-08 12:57:12 +0000381 case "-m":
Andreas Gampebdd30d82016-03-20 11:32:11 -0700382 compilerFilter = getNextArgRequired();
383 break;
384 case "-r":
385 compilationReason = getNextArgRequired();
David Brazdil9aa6db02016-03-08 12:57:12 +0000386 break;
Richard Uhler568a9692016-05-03 16:02:52 -0700387 case "--check-prof":
Calin Juravle8bc758b2016-03-28 12:31:52 +0100388 checkProfilesRaw = getNextArgRequired();
389 break;
David Brazdil9aa6db02016-03-08 12:57:12 +0000390 case "--reset":
391 forceCompilation = true;
392 clearProfileData = true;
Richard Uhler5f201e62016-05-11 13:38:27 -0700393 compilationReason = "install";
David Brazdil9aa6db02016-03-08 12:57:12 +0000394 break;
Calin Juravlec22c30e2017-01-16 19:18:48 -0800395 case "--secondary-dex":
396 secondaryDex = true;
397 break;
David Brazdil493411a2016-02-01 13:48:46 +0000398 default:
399 pw.println("Error: Unknown option: " + opt);
400 return 1;
401 }
402 }
403
Calin Juravle8bc758b2016-03-28 12:31:52 +0100404 if (checkProfilesRaw != null) {
405 if ("true".equals(checkProfilesRaw)) {
406 checkProfiles = true;
407 } else if ("false".equals(checkProfilesRaw)) {
408 checkProfiles = false;
409 } else {
410 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
411 return 1;
412 }
413 }
414
Andreas Gampebdd30d82016-03-20 11:32:11 -0700415 if (compilerFilter != null && compilationReason != null) {
416 pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
417 "at the same time");
418 return 1;
David Brazdil493411a2016-02-01 13:48:46 +0000419 }
Andreas Gampebdd30d82016-03-20 11:32:11 -0700420 if (compilerFilter == null && compilationReason == null) {
421 pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " +
422 "reason (\"-r\") at the same time");
423 return 1;
424 }
425
426 String targetCompilerFilter;
427 if (compilerFilter != null) {
Richard Uhler568a9692016-05-03 16:02:52 -0700428 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
429 pw.println("Error: \"" + compilerFilter +
430 "\" is not a valid compilation filter.");
431 return 1;
Andreas Gampebdd30d82016-03-20 11:32:11 -0700432 }
Richard Uhler568a9692016-05-03 16:02:52 -0700433 targetCompilerFilter = compilerFilter;
Andreas Gampebdd30d82016-03-20 11:32:11 -0700434 } else {
435 int reason = -1;
436 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
437 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
438 compilationReason)) {
439 reason = i;
440 break;
441 }
442 }
443 if (reason == -1) {
444 pw.println("Error: Unknown compilation reason: " + compilationReason);
445 return 1;
446 }
447 targetCompilerFilter =
448 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
449 }
450
David Brazdil493411a2016-02-01 13:48:46 +0000451
David Brazdil990fb6b2016-03-01 10:02:27 +0000452 List<String> packageNames = null;
453 if (allPackages) {
454 packageNames = mInterface.getAllPackages();
455 } else {
456 String packageName = getNextArg();
457 if (packageName == null) {
458 pw.println("Error: package name not specified");
459 return 1;
460 }
461 packageNames = Collections.singletonList(packageName);
David Brazdil493411a2016-02-01 13:48:46 +0000462 }
463
David Brazdil990fb6b2016-03-01 10:02:27 +0000464 List<String> failedPackages = new ArrayList<>();
465 for (String packageName : packageNames) {
David Brazdil9aa6db02016-03-08 12:57:12 +0000466 if (clearProfileData) {
467 mInterface.clearApplicationProfileData(packageName);
468 }
469
Calin Juravlec22c30e2017-01-16 19:18:48 -0800470 boolean result = secondaryDex
471 ? mInterface.performDexOptSecondary(packageName,
472 targetCompilerFilter, forceCompilation)
473 : mInterface.performDexOptMode(packageName,
Nicolas Geoffray3b4359a2017-05-25 13:53:22 +0100474 checkProfiles, targetCompilerFilter, forceCompilation,
475 true /* bootComplete */);
David Brazdil990fb6b2016-03-01 10:02:27 +0000476 if (!result) {
477 failedPackages.add(packageName);
478 }
479 }
480
481 if (failedPackages.isEmpty()) {
David Brazdil493411a2016-02-01 13:48:46 +0000482 pw.println("Success");
483 return 0;
David Brazdil990fb6b2016-03-01 10:02:27 +0000484 } else if (failedPackages.size() == 1) {
485 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
486 return 1;
David Brazdil493411a2016-02-01 13:48:46 +0000487 } else {
David Brazdil990fb6b2016-03-01 10:02:27 +0000488 pw.print("Failure: the following packages could not be compiled: ");
489 boolean is_first = true;
490 for (String packageName : failedPackages) {
491 if (is_first) {
492 is_first = false;
493 } else {
494 pw.print(", ");
495 }
496 pw.print(packageName);
497 }
498 pw.println();
David Brazdil493411a2016-02-01 13:48:46 +0000499 return 1;
500 }
501 }
502
Calin Juravle1aa5f882017-01-25 01:05:50 -0800503 private int runreconcileSecondaryDexFiles() throws RemoteException {
504 String packageName = getNextArg();
505 mInterface.reconcileSecondaryDexFiles(packageName);
506 return 0;
507 }
508
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800509 private int runDexoptJob() throws RemoteException {
510 boolean result = mInterface.runBackgroundDexoptJob();
511 return result ? 0 : -1;
512 }
513
David Sehra8777082016-05-24 15:25:23 -0700514 private int runDumpProfiles() throws RemoteException {
515 String packageName = getNextArg();
516 mInterface.dumpProfiles(packageName);
517 return 0;
518 }
519
Todd Kennedy60459ab2015-10-30 11:32:16 -0700520 private int runList() throws RemoteException {
521 final PrintWriter pw = getOutPrintWriter();
522 final String type = getNextArg();
523 if (type == null) {
524 pw.println("Error: didn't specify type of data to list");
525 return -1;
526 }
527 switch(type) {
528 case "features":
529 return runListFeatures();
530 case "instrumentation":
531 return runListInstrumentation();
532 case "libraries":
533 return runListLibraries();
534 case "package":
535 case "packages":
536 return runListPackages(false /*showSourceDir*/);
537 case "permission-groups":
538 return runListPermissionGroups();
539 case "permissions":
540 return runListPermissions();
541 }
542 pw.println("Error: unknown list type '" + type + "'");
543 return -1;
544 }
545
546 private int runListFeatures() throws RemoteException {
547 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700548 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700549
550 // sort by name
551 Collections.sort(list, new Comparator<FeatureInfo>() {
552 public int compare(FeatureInfo o1, FeatureInfo o2) {
553 if (o1.name == o2.name) return 0;
554 if (o1.name == null) return -1;
555 if (o2.name == null) return 1;
556 return o1.name.compareTo(o2.name);
557 }
558 });
559
560 final int count = (list != null) ? list.size() : 0;
561 for (int p = 0; p < count; p++) {
562 FeatureInfo fi = list.get(p);
563 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700564 if (fi.name != null) {
565 pw.print(fi.name);
566 if (fi.version > 0) {
567 pw.print("=");
568 pw.print(fi.version);
569 }
570 pw.println();
571 } else {
572 pw.println("reqGlEsVersion=0x"
Todd Kennedy60459ab2015-10-30 11:32:16 -0700573 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700574 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700575 }
576 return 0;
577 }
578
579 private int runListInstrumentation() throws RemoteException {
580 final PrintWriter pw = getOutPrintWriter();
581 boolean showSourceDir = false;
582 String targetPackage = null;
583
584 try {
585 String opt;
586 while ((opt = getNextArg()) != null) {
587 switch (opt) {
588 case "-f":
589 showSourceDir = true;
590 break;
591 default:
592 if (opt.charAt(0) != '-') {
593 targetPackage = opt;
594 } else {
595 pw.println("Error: Unknown option: " + opt);
596 return -1;
597 }
598 break;
599 }
600 }
601 } catch (RuntimeException ex) {
602 pw.println("Error: " + ex.toString());
603 return -1;
604 }
605
606 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700607 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700608
609 // sort by target package
610 Collections.sort(list, new Comparator<InstrumentationInfo>() {
611 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
612 return o1.targetPackage.compareTo(o2.targetPackage);
613 }
614 });
615
616 final int count = (list != null) ? list.size() : 0;
617 for (int p = 0; p < count; p++) {
618 final InstrumentationInfo ii = list.get(p);
619 pw.print("instrumentation:");
620 if (showSourceDir) {
621 pw.print(ii.sourceDir);
622 pw.print("=");
623 }
624 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
625 pw.print(cn.flattenToShortString());
626 pw.print(" (target=");
627 pw.print(ii.targetPackage);
628 pw.println(")");
629 }
630 return 0;
631 }
632
633 private int runListLibraries() throws RemoteException {
634 final PrintWriter pw = getOutPrintWriter();
635 final List<String> list = new ArrayList<String>();
636 final String[] rawList = mInterface.getSystemSharedLibraryNames();
637 for (int i = 0; i < rawList.length; i++) {
638 list.add(rawList[i]);
639 }
640
641 // sort by name
642 Collections.sort(list, new Comparator<String>() {
643 public int compare(String o1, String o2) {
644 if (o1 == o2) return 0;
645 if (o1 == null) return -1;
646 if (o2 == null) return 1;
647 return o1.compareTo(o2);
648 }
649 });
650
651 final int count = (list != null) ? list.size() : 0;
652 for (int p = 0; p < count; p++) {
653 String lib = list.get(p);
654 pw.print("library:");
655 pw.println(lib);
656 }
657 return 0;
658 }
659
660 private int runListPackages(boolean showSourceDir) throws RemoteException {
661 final PrintWriter pw = getOutPrintWriter();
662 int getFlags = 0;
663 boolean listDisabled = false, listEnabled = false;
664 boolean listSystem = false, listThirdParty = false;
665 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700666 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800667 boolean showVersionCode = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700668 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700669 int userId = UserHandle.USER_SYSTEM;
670 try {
671 String opt;
672 while ((opt = getNextOption()) != null) {
673 switch (opt) {
674 case "-d":
675 listDisabled = true;
676 break;
677 case "-e":
678 listEnabled = true;
679 break;
680 case "-f":
681 showSourceDir = true;
682 break;
683 case "-i":
684 listInstaller = true;
685 break;
686 case "-l":
687 // old compat
688 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700689 case "-s":
690 listSystem = true;
691 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700692 case "-U":
693 showUid = true;
694 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700695 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700696 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700697 break;
698 case "-3":
699 listThirdParty = true;
700 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800701 case "--show-versioncode":
702 showVersionCode = true;
703 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700704 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800705 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700706 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700707 case "--uid":
708 showUid = true;
709 uid = Integer.parseInt(getNextArgRequired());
710 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700711 default:
712 pw.println("Error: Unknown option: " + opt);
713 return -1;
714 }
715 }
716 } catch (RuntimeException ex) {
717 pw.println("Error: " + ex.toString());
718 return -1;
719 }
720
721 final String filter = getNextArg();
722
723 @SuppressWarnings("unchecked")
724 final ParceledListSlice<PackageInfo> slice =
725 mInterface.getInstalledPackages(getFlags, userId);
726 final List<PackageInfo> packages = slice.getList();
727
728 final int count = packages.size();
729 for (int p = 0; p < count; p++) {
730 final PackageInfo info = packages.get(p);
731 if (filter != null && !info.packageName.contains(filter)) {
732 continue;
733 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700734 if (uid != -1 && info.applicationInfo.uid != uid) {
735 continue;
736 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700737 final boolean isSystem =
738 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
739 if ((!listDisabled || !info.applicationInfo.enabled) &&
740 (!listEnabled || info.applicationInfo.enabled) &&
741 (!listSystem || isSystem) &&
742 (!listThirdParty || !isSystem)) {
743 pw.print("package:");
744 if (showSourceDir) {
745 pw.print(info.applicationInfo.sourceDir);
746 pw.print("=");
747 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800748 pw.print(info.packageName);
749 if (showVersionCode) {
750 pw.print(" versionCode:");
751 pw.print(info.applicationInfo.versionCode);
752 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700753 if (listInstaller) {
754 pw.print(" installer=");
755 pw.print(mInterface.getInstallerPackageName(info.packageName));
756 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700757 if (showUid) {
758 pw.print(" uid:");
759 pw.print(info.applicationInfo.uid);
760 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700761 pw.println();
762 }
763 }
764 return 0;
765 }
766
767 private int runListPermissionGroups() throws RemoteException {
768 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700769 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700770
771 final int count = pgs.size();
772 for (int p = 0; p < count ; p++) {
773 final PermissionGroupInfo pgi = pgs.get(p);
774 pw.print("permission group:");
775 pw.println(pgi.name);
776 }
777 return 0;
778 }
779
780 private int runListPermissions() throws RemoteException {
781 final PrintWriter pw = getOutPrintWriter();
782 boolean labels = false;
783 boolean groups = false;
784 boolean userOnly = false;
785 boolean summary = false;
786 boolean dangerousOnly = false;
787 String opt;
788 while ((opt = getNextOption()) != null) {
789 switch (opt) {
790 case "-d":
791 dangerousOnly = true;
792 break;
793 case "-f":
794 labels = true;
795 break;
796 case "-g":
797 groups = true;
798 break;
799 case "-s":
800 groups = true;
801 labels = true;
802 summary = true;
803 break;
804 case "-u":
805 userOnly = true;
806 break;
807 default:
808 pw.println("Error: Unknown option: " + opt);
809 return 1;
810 }
811 }
812
813 final ArrayList<String> groupList = new ArrayList<String>();
814 if (groups) {
815 final List<PermissionGroupInfo> infos =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700816 mInterface.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700817 final int count = infos.size();
818 for (int i = 0; i < count; i++) {
819 groupList.add(infos.get(i).name);
820 }
821 groupList.add(null);
822 } else {
823 final String grp = getNextArg();
824 groupList.add(grp);
825 }
826
827 if (dangerousOnly) {
828 pw.println("Dangerous Permissions:");
829 pw.println("");
830 doListPermissions(groupList, groups, labels, summary,
831 PermissionInfo.PROTECTION_DANGEROUS,
832 PermissionInfo.PROTECTION_DANGEROUS);
833 if (userOnly) {
834 pw.println("Normal Permissions:");
835 pw.println("");
836 doListPermissions(groupList, groups, labels, summary,
837 PermissionInfo.PROTECTION_NORMAL,
838 PermissionInfo.PROTECTION_NORMAL);
839 }
840 } else if (userOnly) {
841 pw.println("Dangerous and Normal Permissions:");
842 pw.println("");
843 doListPermissions(groupList, groups, labels, summary,
844 PermissionInfo.PROTECTION_NORMAL,
845 PermissionInfo.PROTECTION_DANGEROUS);
846 } else {
847 pw.println("All Permissions:");
848 pw.println("");
849 doListPermissions(groupList, groups, labels, summary,
850 -10000, 10000);
851 }
852 return 0;
853 }
854
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800855 private int runUninstall() throws RemoteException {
856 final PrintWriter pw = getOutPrintWriter();
857 int flags = 0;
858 int userId = UserHandle.USER_ALL;
Svet Ganov67882122016-12-11 16:36:34 -0800859 int versionCode = PackageManager.VERSION_CODE_HIGHEST;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800860
861 String opt;
862 while ((opt = getNextOption()) != null) {
863 switch (opt) {
864 case "-k":
865 flags |= PackageManager.DELETE_KEEP_DATA;
866 break;
867 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800868 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800869 break;
Svet Ganov67882122016-12-11 16:36:34 -0800870 case "--versionCode":
871 versionCode = Integer.parseInt(getNextArgRequired());
872 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800873 default:
874 pw.println("Error: Unknown option: " + opt);
875 return 1;
876 }
877 }
878
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800879 final String packageName = getNextArg();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800880 if (packageName == null) {
881 pw.println("Error: package name not specified");
882 return 1;
883 }
884
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800885 // if a split is specified, just remove it and not the whole package
886 final String splitName = getNextArg();
887 if (splitName != null) {
888 return runRemoveSplit(packageName, splitName);
889 }
890
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800891 userId = translateUserId(userId, "runUninstall");
892 if (userId == UserHandle.USER_ALL) {
893 userId = UserHandle.USER_SYSTEM;
894 flags |= PackageManager.DELETE_ALL_USERS;
895 } else {
Svet Ganova5c867c2017-05-15 01:17:05 -0700896 final PackageInfo info = mInterface.getPackageInfo(packageName,
897 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800898 if (info == null) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800899 pw.println("Failure [not installed for " + userId + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800900 return 1;
901 }
902 final boolean isSystem =
903 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
904 // If we are being asked to delete a system app for just one
905 // user set flag so it disables rather than reverting to system
906 // version of the app.
907 if (isSystem) {
908 flags |= PackageManager.DELETE_SYSTEM_APP;
909 }
910 }
911
912 final LocalIntentReceiver receiver = new LocalIntentReceiver();
Svet Ganov67882122016-12-11 16:36:34 -0800913 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
914 versionCode), null /*callerPackageName*/, flags,
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800915 receiver.getIntentSender(), userId);
916
917 final Intent result = receiver.getResult();
918 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
919 PackageInstaller.STATUS_FAILURE);
920 if (status == PackageInstaller.STATUS_SUCCESS) {
921 pw.println("Success");
922 return 0;
923 } else {
924 pw.println("Failure ["
925 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
926 return 1;
927 }
928 }
929
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800930 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
931 final PrintWriter pw = getOutPrintWriter();
932 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
933 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
934 sessionParams.appPackageName = packageName;
935 final int sessionId =
936 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
937 boolean abandonSession = true;
938 try {
939 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
940 != PackageInstaller.STATUS_SUCCESS) {
941 return 1;
942 }
943 if (doCommitSession(sessionId, false /*logSuccess*/)
944 != PackageInstaller.STATUS_SUCCESS) {
945 return 1;
946 }
947 abandonSession = false;
948 pw.println("Success");
949 return 0;
950 } finally {
951 if (abandonSession) {
952 try {
953 doAbandonSession(sessionId, false /*logSuccess*/);
954 } catch (Exception ignore) {
955 }
956 }
957 }
958 }
959
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800960 private Intent parseIntentAndUser() throws URISyntaxException {
961 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700962 mBrief = false;
963 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800964 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
965 @Override
966 public boolean handleOption(String opt, ShellCommand cmd) {
967 if ("--user".equals(opt)) {
968 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
969 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700970 } else if ("--brief".equals(opt)) {
971 mBrief = true;
972 return true;
973 } else if ("--components".equals(opt)) {
974 mComponents = true;
975 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800976 }
977 return false;
978 }
979 });
980 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
981 Binder.getCallingUid(), mTargetUser, false, false, null, null);
982 return intent;
983 }
984
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700985 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
986 boolean brief, boolean components) {
987 if (brief || components) {
988 final ComponentName comp;
989 if (ri.activityInfo != null) {
990 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
991 } else if (ri.serviceInfo != null) {
992 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
993 } else if (ri.providerInfo != null) {
994 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
995 } else {
996 comp = null;
997 }
998 if (comp != null) {
999 if (!components) {
1000 pr.println(prefix + "priority=" + ri.priority
1001 + " preferredOrder=" + ri.preferredOrder
1002 + " match=0x" + Integer.toHexString(ri.match)
1003 + " specificIndex=" + ri.specificIndex
1004 + " isDefault=" + ri.isDefault);
1005 }
1006 pr.println(prefix + comp.flattenToShortString());
1007 return;
1008 }
1009 }
1010 ri.dump(pr, prefix);
1011 }
1012
Dianne Hackborn99878e92015-12-02 16:27:41 -08001013 private int runResolveActivity() {
1014 Intent intent;
1015 try {
1016 intent = parseIntentAndUser();
1017 } catch (URISyntaxException e) {
1018 throw new RuntimeException(e.getMessage(), e);
1019 }
1020 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -07001021 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -08001022 PrintWriter pw = getOutPrintWriter();
1023 if (ri == null) {
1024 pw.println("No activity found");
1025 } else {
1026 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001027 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -08001028 }
1029 } catch (RemoteException e) {
1030 throw new RuntimeException("Failed calling service", e);
1031 }
1032 return 0;
1033 }
1034
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001035 private int runQueryIntentActivities() {
1036 Intent intent;
1037 try {
1038 intent = parseIntentAndUser();
1039 } catch (URISyntaxException e) {
1040 throw new RuntimeException(e.getMessage(), e);
1041 }
1042 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -07001043 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -07001044 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001045 PrintWriter pw = getOutPrintWriter();
1046 if (result == null || result.size() <= 0) {
1047 pw.println("No activities found");
1048 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001049 if (!mComponents) {
1050 pw.print(result.size()); pw.println(" activities found:");
1051 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1052 for (int i = 0; i < result.size(); i++) {
1053 pw.print(" Activity #"); pw.print(i); pw.println(":");
1054 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1055 }
1056 } else {
1057 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1058 for (int i = 0; i < result.size(); i++) {
1059 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1060 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001061 }
1062 }
1063 } catch (RemoteException e) {
1064 throw new RuntimeException("Failed calling service", e);
1065 }
1066 return 0;
1067 }
1068
1069 private int runQueryIntentServices() {
1070 Intent intent;
1071 try {
1072 intent = parseIntentAndUser();
1073 } catch (URISyntaxException e) {
1074 throw new RuntimeException(e.getMessage(), e);
1075 }
1076 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -07001077 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -07001078 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001079 PrintWriter pw = getOutPrintWriter();
1080 if (result == null || result.size() <= 0) {
1081 pw.println("No services found");
1082 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001083 if (!mComponents) {
1084 pw.print(result.size()); pw.println(" services found:");
1085 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1086 for (int i = 0; i < result.size(); i++) {
1087 pw.print(" Service #"); pw.print(i); pw.println(":");
1088 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1089 }
1090 } else {
1091 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1092 for (int i = 0; i < result.size(); i++) {
1093 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1094 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001095 }
1096 }
1097 } catch (RemoteException e) {
1098 throw new RuntimeException("Failed calling service", e);
1099 }
1100 return 0;
1101 }
1102
1103 private int runQueryIntentReceivers() {
1104 Intent intent;
1105 try {
1106 intent = parseIntentAndUser();
1107 } catch (URISyntaxException e) {
1108 throw new RuntimeException(e.getMessage(), e);
1109 }
1110 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -07001111 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -07001112 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001113 PrintWriter pw = getOutPrintWriter();
1114 if (result == null || result.size() <= 0) {
1115 pw.println("No receivers found");
1116 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001117 if (!mComponents) {
1118 pw.print(result.size()); pw.println(" receivers found:");
1119 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1120 for (int i = 0; i < result.size(); i++) {
1121 pw.print(" Receiver #"); pw.print(i); pw.println(":");
1122 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1123 }
1124 } else {
1125 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1126 for (int i = 0; i < result.size(); i++) {
1127 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1128 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001129 }
1130 }
1131 } catch (RemoteException e) {
1132 throw new RuntimeException("Failed calling service", e);
1133 }
1134 return 0;
1135 }
1136
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001137 private static class InstallParams {
1138 SessionParams sessionParams;
1139 String installerPackageName;
1140 int userId = UserHandle.USER_ALL;
1141 }
1142
1143 private InstallParams makeInstallParams() {
1144 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
1145 final InstallParams params = new InstallParams();
1146 params.sessionParams = sessionParams;
1147 String opt;
1148 while ((opt = getNextOption()) != null) {
1149 switch (opt) {
1150 case "-l":
1151 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
1152 break;
1153 case "-r":
1154 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1155 break;
1156 case "-i":
1157 params.installerPackageName = getNextArg();
1158 if (params.installerPackageName == null) {
1159 throw new IllegalArgumentException("Missing installer package");
1160 }
1161 break;
1162 case "-t":
1163 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
1164 break;
1165 case "-s":
1166 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL;
1167 break;
1168 case "-f":
1169 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
1170 break;
1171 case "-d":
1172 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
1173 break;
1174 case "-g":
1175 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
1176 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07001177 case "--dont-kill":
1178 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
1179 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001180 case "--originating-uri":
1181 sessionParams.originatingUri = Uri.parse(getNextArg());
1182 break;
1183 case "--referrer":
1184 sessionParams.referrerUri = Uri.parse(getNextArg());
1185 break;
1186 case "-p":
1187 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
1188 sessionParams.appPackageName = getNextArg();
1189 if (sessionParams.appPackageName == null) {
1190 throw new IllegalArgumentException("Missing inherit package name");
1191 }
1192 break;
1193 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07001194 final long sizeBytes = Long.parseLong(getNextArg());
1195 if (sizeBytes <= 0) {
1196 throw new IllegalArgumentException("Size must be positive");
1197 }
1198 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001199 break;
1200 case "--abi":
1201 sessionParams.abiOverride = checkAbiArgument(getNextArg());
1202 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08001203 case "--ephemeral":
Todd Kennedybe0b8892017-02-15 14:13:52 -08001204 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08001205 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08001206 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08001207 case "--full":
1208 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
1209 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001210 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001211 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001212 break;
1213 case "--install-location":
1214 sessionParams.installLocation = Integer.parseInt(getNextArg());
1215 break;
1216 case "--force-uuid":
1217 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
1218 sessionParams.volumeUuid = getNextArg();
1219 if ("internal".equals(sessionParams.volumeUuid)) {
1220 sessionParams.volumeUuid = null;
1221 }
1222 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07001223 case "--force-sdk":
1224 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK;
1225 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001226 default:
1227 throw new IllegalArgumentException("Unknown option " + opt);
1228 }
1229 }
1230 return params;
1231 }
1232
Makoto Onuki4828a592016-03-15 18:06:57 -07001233 private int runSetHomeActivity() {
1234 final PrintWriter pw = getOutPrintWriter();
1235 int userId = UserHandle.USER_SYSTEM;
1236 String opt;
1237 while ((opt = getNextOption()) != null) {
1238 switch (opt) {
1239 case "--user":
1240 userId = UserHandle.parseUserArg(getNextArgRequired());
1241 break;
1242 default:
1243 pw.println("Error: Unknown option: " + opt);
1244 return 1;
1245 }
1246 }
1247
1248 String component = getNextArg();
1249 ComponentName componentName =
1250 component != null ? ComponentName.unflattenFromString(component) : null;
1251
1252 if (componentName == null) {
1253 pw.println("Error: component name not specified or invalid");
1254 return 1;
1255 }
1256
1257 try {
1258 mInterface.setHomeActivity(componentName, userId);
Makoto Onuki3bdbf982016-06-23 16:56:35 -07001259 pw.println("Success");
Makoto Onuki4828a592016-03-15 18:06:57 -07001260 return 0;
Makoto Onuki3bdbf982016-06-23 16:56:35 -07001261 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07001262 pw.println(e.toString());
1263 return 1;
1264 }
1265 }
1266
Fyodor Kupolov51245c72016-12-01 11:34:10 -08001267 private int runGetPrivappPermissions() {
1268 final String pkg = getNextArg();
1269 if (pkg == null) {
1270 System.err.println("Error: no package specified.");
1271 return 1;
1272 }
1273 ArraySet<String> privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
1274 getOutPrintWriter().println(privAppPermissions == null
1275 ? "{}" : privAppPermissions.toString());
1276 return 0;
1277 }
1278
Todd Kennedy0a3f0812017-05-08 14:43:15 -07001279 private int runGetInstantAppResolver() {
1280 final PrintWriter pw = getOutPrintWriter();
1281 try {
1282 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
1283 if (instantAppsResolver == null) {
1284 return 1;
1285 }
1286 pw.println(instantAppsResolver.flattenToString());
1287 return 0;
1288 } catch (Exception e) {
1289 pw.println(e.toString());
1290 return 1;
1291 }
1292 }
1293
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09001294 private int runHasFeature() {
1295 final PrintWriter err = getErrPrintWriter();
1296 final String featureName = getNextArg();
1297 if (featureName == null) {
1298 err.println("Error: expected FEATURE name");
1299 return 1;
1300 }
1301 final String versionString = getNextArg();
1302 try {
1303 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
1304 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
1305 getOutPrintWriter().println(hasFeature);
1306 return hasFeature ? 0 : 1;
1307 } catch (NumberFormatException e) {
1308 err.println("Error: illegal version number " + versionString);
1309 return 1;
1310 } catch (RemoteException e) {
1311 err.println(e.toString());
1312 return 1;
1313 }
1314 }
1315
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001316 private static String checkAbiArgument(String abi) {
1317 if (TextUtils.isEmpty(abi)) {
1318 throw new IllegalArgumentException("Missing ABI argument");
1319 }
1320
1321 if ("-".equals(abi)) {
1322 return abi;
1323 }
1324
1325 final String[] supportedAbis = Build.SUPPORTED_ABIS;
1326 for (String supportedAbi : supportedAbis) {
1327 if (supportedAbi.equals(abi)) {
1328 return abi;
1329 }
1330 }
1331
1332 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
1333 }
1334
1335 private int translateUserId(int userId, String logContext) {
1336 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
1337 userId, true, true, logContext, "pm command");
1338 }
1339
1340 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
1341 throws RemoteException {
1342 userId = translateUserId(userId, "runInstallCreate");
1343 if (userId == UserHandle.USER_ALL) {
1344 userId = UserHandle.USER_SYSTEM;
1345 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
1346 }
1347
1348 final int sessionId = mInterface.getPackageInstaller()
1349 .createSession(params, installerPackageName, userId);
1350 return sessionId;
1351 }
1352
Todd Kennedyeb9b0532016-03-08 10:10:54 -08001353 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08001354 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001355 final PrintWriter pw = getOutPrintWriter();
Todd Kennedy9caf94e2016-10-12 15:26:08 -07001356 if (FORCE_STREAM_INSTALL && inPath != null && !STDIN_PATH.equals(inPath)) {
1357 pw.println("Error: APK content must be streamed");
1358 return 1;
1359 }
1360 if (STDIN_PATH.equals(inPath)) {
1361 inPath = null;
1362 } else if (inPath != null) {
1363 final File file = new File(inPath);
1364 if (file.isFile()) {
1365 sizeBytes = file.length();
1366 }
1367 }
Todd Kennedy63cc8b02016-09-22 13:25:46 -07001368 if (sizeBytes <= 0) {
1369 pw.println("Error: must specify a APK size");
1370 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001371 }
1372
1373 final SessionInfo info = mInterface.getPackageInstaller().getSessionInfo(sessionId);
1374
1375 PackageInstaller.Session session = null;
1376 InputStream in = null;
1377 OutputStream out = null;
1378 try {
1379 session = new PackageInstaller.Session(
1380 mInterface.getPackageInstaller().openSession(sessionId));
1381
1382 if (inPath != null) {
1383 in = new FileInputStream(inPath);
1384 } else {
Dianne Hackborn2e931f52016-01-28 12:21:17 -08001385 in = new SizedInputStream(getRawInputStream(), sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001386 }
1387 out = session.openWrite(splitName, 0, sizeBytes);
1388
1389 int total = 0;
1390 byte[] buffer = new byte[65536];
1391 int c;
1392 while ((c = in.read(buffer)) != -1) {
1393 total += c;
1394 out.write(buffer, 0, c);
1395
1396 if (info.sizeBytes > 0) {
1397 final float fraction = ((float) c / (float) info.sizeBytes);
1398 session.addProgress(fraction);
1399 }
1400 }
1401 session.fsync(out);
1402
Todd Kennedy8d9366c2015-12-16 13:47:14 -08001403 if (logSuccess) {
1404 pw.println("Success: streamed " + total + " bytes");
1405 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001406 return 0;
1407 } catch (IOException e) {
1408 pw.println("Error: failed to write; " + e.getMessage());
1409 return 1;
1410 } finally {
1411 IoUtils.closeQuietly(out);
1412 IoUtils.closeQuietly(in);
1413 IoUtils.closeQuietly(session);
1414 }
1415 }
1416
Todd Kennedyeb9b0532016-03-08 10:10:54 -08001417 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
1418 throws RemoteException {
1419 final PrintWriter pw = getOutPrintWriter();
1420 PackageInstaller.Session session = null;
1421 try {
1422 session = new PackageInstaller.Session(
1423 mInterface.getPackageInstaller().openSession(sessionId));
1424 session.removeSplit(splitName);
1425
1426 if (logSuccess) {
1427 pw.println("Success");
1428 }
1429 return 0;
1430 } catch (IOException e) {
1431 pw.println("Error: failed to remove split; " + e.getMessage());
1432 return 1;
1433 } finally {
1434 IoUtils.closeQuietly(session);
1435 }
1436 }
1437
Todd Kennedy8d9366c2015-12-16 13:47:14 -08001438 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001439 final PrintWriter pw = getOutPrintWriter();
1440 PackageInstaller.Session session = null;
1441 try {
1442 session = new PackageInstaller.Session(
1443 mInterface.getPackageInstaller().openSession(sessionId));
1444
1445 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1446 session.commit(receiver.getIntentSender());
1447
1448 final Intent result = receiver.getResult();
1449 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1450 PackageInstaller.STATUS_FAILURE);
1451 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08001452 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07001453 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08001454 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001455 } else {
1456 pw.println("Failure ["
1457 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001458 }
1459 return status;
1460 } finally {
1461 IoUtils.closeQuietly(session);
1462 }
1463 }
1464
Todd Kennedy8d9366c2015-12-16 13:47:14 -08001465 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001466 final PrintWriter pw = getOutPrintWriter();
1467 PackageInstaller.Session session = null;
1468 try {
1469 session = new PackageInstaller.Session(
1470 mInterface.getPackageInstaller().openSession(sessionId));
1471 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08001472 if (logSuccess) {
1473 pw.println("Success");
1474 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001475 return 0;
1476 } finally {
1477 IoUtils.closeQuietly(session);
1478 }
1479 }
1480
Todd Kennedy60459ab2015-10-30 11:32:16 -07001481 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
1482 boolean summary, int startProtectionLevel, int endProtectionLevel)
1483 throws RemoteException {
1484 final PrintWriter pw = getOutPrintWriter();
1485 final int groupCount = groupList.size();
1486 for (int i = 0; i < groupCount; i++) {
1487 String groupName = groupList.get(i);
1488 String prefix = "";
1489 if (groups) {
1490 if (i > 0) {
1491 pw.println("");
1492 }
1493 if (groupName != null) {
1494 PermissionGroupInfo pgi =
1495 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
1496 if (summary) {
1497 Resources res = getResources(pgi);
1498 if (res != null) {
1499 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
1500 } else {
1501 pw.print(pgi.name + ": ");
1502
1503 }
1504 } else {
1505 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
1506 if (labels) {
1507 pw.println(" package:" + pgi.packageName);
1508 Resources res = getResources(pgi);
1509 if (res != null) {
1510 pw.println(" label:"
1511 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
1512 pw.println(" description:"
1513 + loadText(pgi, pgi.descriptionRes,
1514 pgi.nonLocalizedDescription));
1515 }
1516 }
1517 }
1518 } else {
1519 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
1520 }
1521 prefix = " ";
1522 }
1523 List<PermissionInfo> ps =
Jeff Sharkeyd5896632016-03-04 16:16:00 -07001524 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07001525 final int count = ps.size();
1526 boolean first = true;
1527 for (int p = 0 ; p < count ; p++) {
1528 PermissionInfo pi = ps.get(p);
1529 if (groups && groupName == null && pi.group != null) {
1530 continue;
1531 }
1532 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
1533 if (base < startProtectionLevel
1534 || base > endProtectionLevel) {
1535 continue;
1536 }
1537 if (summary) {
1538 if (first) {
1539 first = false;
1540 } else {
1541 pw.print(", ");
1542 }
1543 Resources res = getResources(pi);
1544 if (res != null) {
1545 pw.print(loadText(pi, pi.labelRes,
1546 pi.nonLocalizedLabel));
1547 } else {
1548 pw.print(pi.name);
1549 }
1550 } else {
1551 pw.println(prefix + (labels ? "+ " : "")
1552 + "permission:" + pi.name);
1553 if (labels) {
1554 pw.println(prefix + " package:" + pi.packageName);
1555 Resources res = getResources(pi);
1556 if (res != null) {
1557 pw.println(prefix + " label:"
1558 + loadText(pi, pi.labelRes,
1559 pi.nonLocalizedLabel));
1560 pw.println(prefix + " description:"
1561 + loadText(pi, pi.descriptionRes,
1562 pi.nonLocalizedDescription));
1563 }
1564 pw.println(prefix + " protectionLevel:"
1565 + PermissionInfo.protectionToString(pi.protectionLevel));
1566 }
1567 }
1568 }
1569
1570 if (summary) {
1571 pw.println("");
1572 }
1573 }
1574 }
1575
1576 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
1577 throws RemoteException {
1578 if (nonLocalized != null) {
1579 return nonLocalized.toString();
1580 }
1581 if (res != 0) {
1582 Resources r = getResources(pii);
1583 if (r != null) {
1584 try {
1585 return r.getString(res);
1586 } catch (Resources.NotFoundException e) {
1587 }
1588 }
1589 }
1590 return null;
1591 }
1592
1593 private Resources getResources(PackageItemInfo pii) throws RemoteException {
1594 Resources res = mResourceCache.get(pii.packageName);
1595 if (res != null) return res;
1596
1597 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
1598 AssetManager am = new AssetManager();
1599 am.addAssetPath(ai.publicSourceDir);
1600 res = new Resources(am, null, null);
1601 mResourceCache.put(pii.packageName, res);
1602 return res;
1603 }
1604
1605 @Override
1606 public void onHelp() {
1607 final PrintWriter pw = getOutPrintWriter();
1608 pw.println("Package manager (package) commands:");
1609 pw.println(" help");
1610 pw.println(" Print this help text.");
1611 pw.println("");
Richard Uhler568a9692016-05-03 16:02:52 -07001612 pw.println(" compile [-m MODE | -r REASON] [-f] [-c]");
1613 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
David Brazdil990fb6b2016-03-01 10:02:27 +00001614 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\".");
David Brazdil493411a2016-02-01 13:48:46 +00001615 pw.println(" Options:");
David Brazdil990fb6b2016-03-01 10:02:27 +00001616 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00001617 pw.println(" -c: clear profile data before compiling");
1618 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00001619 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07001620 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01001621 pw.println(" assume-verified");
1622 pw.println(" extract");
1623 pw.println(" verify");
1624 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07001625 pw.println(" space-profile");
1626 pw.println(" space");
1627 pw.println(" speed-profile");
1628 pw.println(" speed");
1629 pw.println(" everything");
1630 pw.println(" -r: select compilation reason");
1631 pw.println(" REASON is one of:");
1632 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1633 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
1634 }
David Brazdilcf046952016-03-08 16:40:20 +00001635 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07001636 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08001637 pw.println(" --secondary-dex: compile app secondary dex files");
1638 pw.println(" bg-dexopt-job");
1639 pw.println(" Execute the background optimizations immediately.");
1640 pw.println(" Note that the command only runs the background optimizer logic. It may");
1641 pw.println(" overlap with the actual job but the job scheduler will not be able to");
1642 pw.println(" cancel it. It will also run even if the device is not in the idle");
1643 pw.println(" maintenance mode.");
Todd Kennedy60459ab2015-10-30 11:32:16 -07001644 pw.println(" list features");
1645 pw.println(" Prints all features of the system.");
1646 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +00001647 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
Todd Kennedy60459ab2015-10-30 11:32:16 -07001648 pw.println(" Options:");
1649 pw.println(" -f: dump the name of the .apk file containing the test package");
1650 pw.println(" list libraries");
1651 pw.println(" Prints all system libraries.");
Felipe Lemeeece9862016-06-29 11:45:03 -07001652 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] "
1653 + "[--uid UID] [--user USER_ID] [FILTER]");
Todd Kennedy60459ab2015-10-30 11:32:16 -07001654 pw.println(" Prints all packages; optionally only those whose name contains");
1655 pw.println(" the text in FILTER.");
1656 pw.println(" Options:");
1657 pw.println(" -f: see their associated file");
Felipe Leme3f24edf2015-11-18 15:04:13 -08001658 pw.println(" -d: filter to only show disabled packages");
Todd Kennedy60459ab2015-10-30 11:32:16 -07001659 pw.println(" -e: filter to only show enabled packages");
1660 pw.println(" -s: filter to only show system packages");
1661 pw.println(" -3: filter to only show third party packages");
1662 pw.println(" -i: see the installer for the packages");
Felipe Lemeeece9862016-06-29 11:45:03 -07001663 pw.println(" -l: ignored (used for compatibility with older releases)");
1664 pw.println(" -U: also show the package UID");
Todd Kennedy60459ab2015-10-30 11:32:16 -07001665 pw.println(" -u: also include uninstalled packages");
Felipe Lemeeece9862016-06-29 11:45:03 -07001666 pw.println(" --uid UID: filter to only show packages with the given UID");
1667 pw.println(" --user USER_ID: only list packages belonging to the given user");
Calin Juravle1aa5f882017-01-25 01:05:50 -08001668 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
1669 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Todd Kennedy60459ab2015-10-30 11:32:16 -07001670 pw.println(" list permission-groups");
1671 pw.println(" Prints all known permission groups.");
1672 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
1673 pw.println(" Prints all known permissions; optionally only those in GROUP.");
1674 pw.println(" Options:");
1675 pw.println(" -g: organize by group");
1676 pw.println(" -f: print all information");
1677 pw.println(" -s: short summary");
1678 pw.println(" -d: only list dangerous permissions");
1679 pw.println(" -u: list only the permissions users will see");
David Sehrcae13b02016-06-07 09:11:27 -07001680 pw.println(" dump-profiles TARGET-PACKAGE");
1681 pw.println(" Dumps method/class profile files to");
1682 pw.println(" /data/misc/profman/TARGET-PACKAGE.txt");
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001683 pw.println(" resolve-activity [--brief] [--components] [--user USER_ID] INTENT");
Dianne Hackborn99878e92015-12-02 16:27:41 -08001684 pw.println(" Prints the activity that resolves to the given Intent.");
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001685 pw.println(" query-activities [--brief] [--components] [--user USER_ID] INTENT");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001686 pw.println(" Prints all activities that can handle the given Intent.");
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001687 pw.println(" query-services [--brief] [--components] [--user USER_ID] INTENT");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001688 pw.println(" Prints all services that can handle the given Intent.");
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001689 pw.println(" query-receivers [--brief] [--components] [--user USER_ID] INTENT");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001690 pw.println(" Prints all broadcast receivers that can handle the given Intent.");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +00001691 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
1692 pw.println(" Suspends the specified package (as user).");
1693 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
1694 pw.println(" Unsuspends the specified package (as user).");
Makoto Onuki4828a592016-03-15 18:06:57 -07001695 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
1696 pw.println(" set the default home activity (aka launcher).");
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09001697 pw.println(" has-feature FEATURE_NAME [version]");
1698 pw.println(" prints true and returns exit status 0 when system has a FEATURE_NAME,");
1699 pw.println(" otherwise prints false and returns exit status 1");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001700 pw.println();
1701 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07001702 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001703
1704 private static class LocalIntentReceiver {
1705 private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();
1706
1707 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
1708 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07001709 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001710 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
1711 try {
1712 mResult.offer(intent, 5, TimeUnit.SECONDS);
1713 } catch (InterruptedException e) {
1714 throw new RuntimeException(e);
1715 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001716 }
1717 };
1718
1719 public IntentSender getIntentSender() {
1720 return new IntentSender((IIntentSender) mLocalSender);
1721 }
1722
1723 public Intent getResult() {
1724 try {
1725 return mResult.take();
1726 } catch (InterruptedException e) {
1727 throw new RuntimeException(e);
1728 }
1729 }
1730 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07001731}