blob: 90911688abbf3e7d2e462e7cd7d31b649a4193f2 [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
Jeff Sharkey0451de62018-02-02 11:27:21 -070019import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
20import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
21import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
22import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
23import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
24
Dianne Hackbornc81983a2017-10-20 16:16:32 -070025import android.accounts.IAccountManager;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080026import android.app.ActivityManager;
Alex Chauc12189b2018-01-16 15:01:15 +000027import android.app.ActivityManagerInternal;
Bookatz2b5a6012019-04-16 19:41:28 -070028import android.app.role.IRoleManager;
29import android.app.role.RoleManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070030import android.content.ComponentName;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070031import android.content.Context;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080032import android.content.IIntentReceiver;
33import android.content.IIntentSender;
34import android.content.Intent;
35import android.content.IntentSender;
Todd Kennedy60459ab2015-10-30 11:32:16 -070036import android.content.pm.ApplicationInfo;
37import android.content.pm.FeatureInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070038import android.content.pm.IPackageDataObserver;
Patrick Baumanna980e142018-02-12 11:45:23 -080039import android.content.pm.IPackageInstaller;
Todd Kennedy60459ab2015-10-30 11:32:16 -070040import android.content.pm.IPackageManager;
41import android.content.pm.InstrumentationInfo;
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +010042import android.content.pm.ModuleInfo;
Todd Kennedy60459ab2015-10-30 11:32:16 -070043import android.content.pm.PackageInfo;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080044import android.content.pm.PackageInstaller;
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +000045import android.content.pm.PackageInstaller.SessionInfo;
Jeff Sharkey0451de62018-02-02 11:27:21 -070046import android.content.pm.PackageInstaller.SessionParams;
Todd Kennedy60459ab2015-10-30 11:32:16 -070047import android.content.pm.PackageItemInfo;
48import android.content.pm.PackageManager;
Jeff Sharkey0451de62018-02-02 11:27:21 -070049import android.content.pm.PackageManager.NameNotFoundException;
Dario Freni788ecb12019-01-23 18:49:32 +000050import android.content.pm.PackageManagerInternal;
Shunta Sato4f26cb52016-06-28 09:29:19 +090051import android.content.pm.PackageParser;
52import android.content.pm.PackageParser.ApkLite;
53import android.content.pm.PackageParser.PackageLite;
54import android.content.pm.PackageParser.PackageParserException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070055import android.content.pm.ParceledListSlice;
56import android.content.pm.PermissionGroupInfo;
57import android.content.pm.PermissionInfo;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080058import android.content.pm.ResolveInfo;
Suprabh Shukla389cb6f2018-10-01 18:20:39 -070059import android.content.pm.SuspendDialogInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070060import android.content.pm.UserInfo;
Svet Ganov67882122016-12-11 16:36:34 -080061import android.content.pm.VersionedPackage;
Calin Juravle21216c62018-05-04 17:35:29 -070062import android.content.pm.dex.ArtManager;
Calin Juravle3fc56c32017-12-11 18:26:13 -080063import android.content.pm.dex.DexMetadataHelper;
Calin Juravle21216c62018-05-04 17:35:29 -070064import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
Todd Kennedy60459ab2015-10-30 11:32:16 -070065import android.content.res.AssetManager;
66import android.content.res.Resources;
Narayan Kamathc5d752e2019-01-23 14:06:35 +000067import android.content.rollback.IRollbackManager;
68import android.content.rollback.PackageRollbackInfo;
69import android.content.rollback.RollbackInfo;
70import android.content.rollback.RollbackManager;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080071import android.net.Uri;
72import android.os.Binder;
73import android.os.Build;
74import android.os.Bundle;
Dianne Hackborn98305522017-05-05 17:53:53 -070075import android.os.IBinder;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070076import android.os.IUserManager;
Dianne Hackbornca3872c2017-10-30 14:19:32 -070077import android.os.ParcelFileDescriptor;
Calin Juravle21216c62018-05-04 17:35:29 -070078import android.os.ParcelFileDescriptor.AutoCloseInputStream;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080079import android.os.PersistableBundle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070080import android.os.Process;
Bookatz2b5a6012019-04-16 19:41:28 -070081import android.os.RemoteCallback;
Todd Kennedy60459ab2015-10-30 11:32:16 -070082import android.os.RemoteException;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070083import android.os.ServiceManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070084import android.os.ShellCommand;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070085import android.os.SystemClock;
Calin Juravle8bc758b2016-03-28 12:31:52 +010086import android.os.SystemProperties;
Todd Kennedy60459ab2015-10-30 11:32:16 -070087import android.os.UserHandle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070088import android.os.UserManager;
89import android.os.storage.StorageManager;
Calin Juravlebdd94d92018-05-17 01:23:15 -070090import android.system.ErrnoException;
91import android.system.Os;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080092import android.text.TextUtils;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070093import android.text.format.DateUtils;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080094import android.util.ArraySet;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080095import android.util.PrintWriterPrinter;
Mohammad Samiul Islam40110562019-09-02 14:37:33 +010096import android.util.SparseArray;
Dario Freni2bef1762018-06-01 14:02:08 +010097
Shunta Sato4f26cb52016-06-28 09:29:19 +090098import com.android.internal.content.PackageHelper;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070099import com.android.internal.util.ArrayUtils;
Mohammad Samiul Islam40110562019-09-02 14:37:33 +0100100import com.android.internal.util.IndentingPrintWriter;
Alex Chauc12189b2018-01-16 15:01:15 +0000101import com.android.server.LocalServices;
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800102import com.android.server.SystemConfig;
Dario Freni2bef1762018-06-01 14:02:08 +0100103
Andreas Gampebdd30d82016-03-20 11:32:11 -0700104import dalvik.system.DexFile;
Dario Freni2bef1762018-06-01 14:02:08 +0100105
106import libcore.io.IoUtils;
107import libcore.io.Streams;
108
Calin Juravle21216c62018-05-04 17:35:29 -0700109import java.io.File;
110import java.io.FileOutputStream;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800111import java.io.IOException;
Calin Juravle21216c62018-05-04 17:35:29 -0700112import java.io.InputStream;
113import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700114import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800115import java.net.URISyntaxException;
Calin Juravle21216c62018-05-04 17:35:29 -0700116import java.util.ArrayList;
117import java.util.Collections;
118import java.util.Comparator;
119import java.util.LinkedList;
120import java.util.List;
121import java.util.Map;
122import java.util.Objects;
123import java.util.WeakHashMap;
Bookatz2b5a6012019-04-16 19:41:28 -0700124import java.util.concurrent.CompletableFuture;
Calin Juravle21216c62018-05-04 17:35:29 -0700125import java.util.concurrent.CountDownLatch;
wangmingming155414292018-04-10 09:35:25 +0800126import java.util.concurrent.LinkedBlockingQueue;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800127import java.util.concurrent.TimeUnit;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700128
129class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700130 /** Path for streaming APK content */
131 private static final String STDIN_PATH = "-";
Calin Juravle21216c62018-05-04 17:35:29 -0700132 /** Path where ART profiles snapshots are dumped for the shell user */
133 private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
Mohammad Samiul Islamf49c85f2019-05-17 18:02:12 +0100134 private static final int DEFAULT_WAIT_MS = 60 * 1000;
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700135
Todd Kennedy60459ab2015-10-30 11:32:16 -0700136 final IPackageManager mInterface;
137 final private WeakHashMap<String, Resources> mResourceCache =
138 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800139 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700140 boolean mBrief;
141 boolean mComponents;
Ng Zhi An73971312018-09-11 21:39:14 -0700142 int mQueryFlags;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700143
144 PackageManagerShellCommand(PackageManagerService service) {
145 mInterface = service;
146 }
147
148 @Override
149 public int onCommand(String cmd) {
150 if (cmd == null) {
151 return handleDefaultCommands(cmd);
152 }
153
154 final PrintWriter pw = getOutPrintWriter();
155 try {
156 switch(cmd) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700157 case "path":
158 return runPath();
159 case "dump":
160 return runDump();
161 case "list":
162 return runList();
163 case "resolve-activity":
164 return runResolveActivity();
165 case "query-activities":
166 return runQueryIntentActivities();
167 case "query-services":
168 return runQueryIntentServices();
169 case "query-receivers":
170 return runQueryIntentReceivers();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800171 case "install":
172 return runInstall();
173 case "install-abandon":
174 case "install-destroy":
175 return runInstallAbandon();
176 case "install-commit":
177 return runInstallCommit();
178 case "install-create":
179 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800180 case "install-remove":
181 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800182 case "install-write":
183 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800184 case "install-existing":
185 return runInstallExisting();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700186 case "set-install-location":
187 return runSetInstallLocation();
188 case "get-install-location":
189 return runGetInstallLocation();
Patrick Baumann0aff9b12018-11-08 14:05:08 +0000190 case "install-add-session":
191 return runInstallAddSession();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700192 case "move-package":
193 return runMovePackage();
194 case "move-primary-storage":
195 return runMovePrimaryStorage();
David Brazdil493411a2016-02-01 13:48:46 +0000196 case "compile":
197 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800198 case "reconcile-secondary-dex-files":
199 return runreconcileSecondaryDexFiles();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700200 case "force-dex-opt":
201 return runForceDexOpt();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800202 case "bg-dexopt-job":
203 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700204 case "dump-profiles":
205 return runDumpProfiles();
Calin Juravle21216c62018-05-04 17:35:29 -0700206 case "snapshot-profile":
207 return runSnapshotProfile();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800208 case "uninstall":
209 return runUninstall();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700210 case "clear":
211 return runClear();
212 case "enable":
213 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
214 case "disable":
215 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
216 case "disable-user":
217 return runSetEnabledSetting(
218 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
219 case "disable-until-used":
220 return runSetEnabledSetting(
221 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
222 case "default-state":
223 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
224 case "hide":
225 return runSetHiddenSetting(true);
226 case "unhide":
227 return runSetHiddenSetting(false);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000228 case "suspend":
229 return runSuspend(true);
230 case "unsuspend":
231 return runSuspend(false);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700232 case "grant":
233 return runGrantRevokePermission(true);
234 case "revoke":
235 return runGrantRevokePermission(false);
236 case "reset-permissions":
237 return runResetPermissions();
238 case "set-permission-enforced":
239 return runSetPermissionEnforced();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800240 case "get-privapp-permissions":
241 return runGetPrivappPermissions();
Todd Kennedy74629e32017-08-15 14:48:07 -0700242 case "get-privapp-deny-permissions":
243 return runGetPrivappDenyPermissions();
Svet Ganov087dce22017-09-07 15:42:16 -0700244 case "get-oem-permissions":
245 return runGetOemPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700246 case "set-app-link":
247 return runSetAppLink();
248 case "get-app-link":
249 return runGetAppLink();
250 case "trim-caches":
251 return runTrimCaches();
252 case "create-user":
253 return runCreateUser();
254 case "remove-user":
255 return runRemoveUser();
256 case "set-user-restriction":
257 return runSetUserRestriction();
258 case "get-max-users":
259 return runGetMaxUsers();
Alex Chauc12189b2018-01-16 15:01:15 +0000260 case "get-max-running-users":
261 return runGetMaxRunningUsers();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700262 case "set-home-activity":
263 return runSetHomeActivity();
264 case "set-installer":
265 return runSetInstaller();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700266 case "get-instantapp-resolver":
267 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900268 case "has-feature":
269 return runHasFeature();
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800270 case "set-harmful-app-warning":
271 return runSetHarmfulAppWarning();
Ben Gruver9ef60092018-01-10 11:32:30 -0800272 case "get-harmful-app-warning":
273 return runGetHarmfulAppWarning();
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000274 case "get-stagedsessions":
Mohammad Samiul Islam40110562019-09-02 14:37:33 +0100275 return runListStagedSessions();
Patrick Baumanna980e142018-02-12 11:45:23 -0800276 case "uninstall-system-updates":
277 return uninstallSystemUpdates();
Narayan Kamathc5d752e2019-01-23 14:06:35 +0000278 case "rollback-app":
279 return runRollbackApp();
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +0100280 case "get-moduleinfo":
281 return runGetModuleInfo();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700282 default: {
283 String nextArg = getNextArg();
284 if (nextArg == null) {
285 if (cmd.equalsIgnoreCase("-l")) {
286 return runListPackages(false);
287 } else if (cmd.equalsIgnoreCase("-lf")) {
288 return runListPackages(true);
289 }
290 } else if (getNextArg() == null) {
291 if (cmd.equalsIgnoreCase("-p")) {
292 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
293 }
294 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700295 return handleDefaultCommands(cmd);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700296 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700297 }
298 } catch (RemoteException e) {
299 pw.println("Remote exception: " + e);
300 }
301 return -1;
302 }
303
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +0100304 /**
305 * Shows module info
306 *
307 * Usage: get-moduleinfo [--all | --installed] [module-name]
308 * Example: get-moduleinfo, get-moduleinfo --all, get-moduleinfo xyz
309 */
310 private int runGetModuleInfo() {
311 final PrintWriter pw = getOutPrintWriter();
312 int flags = 0;
313
314 String opt;
315 while ((opt = getNextOption()) != null) {
316 switch (opt) {
317 case "--all":
318 flags |= PackageManager.MATCH_ALL;
319 break;
320 case "--installed":
321 break;
322 default:
323 pw.println("Error: Unknown option: " + opt);
324 return -1;
325 }
326 }
327
328 String moduleName = getNextArg();
329 try {
330 if (moduleName != null) {
331 ModuleInfo m = mInterface.getModuleInfo(moduleName, flags);
332 pw.println(m.toString() + " packageName: " + m.getPackageName());
333
334 } else {
335 List<ModuleInfo> modules = mInterface.getInstalledModules(flags);
336 for (ModuleInfo m: modules) {
337 pw.println(m.toString() + " packageName: " + m.getPackageName());
338 }
339 }
340 } catch (RemoteException e) {
341 pw.println("Failure [" + e.getClass().getName() + " - " + e.getMessage() + "]");
342 return -1;
343 }
344 return 1;
345 }
346
Patrick Baumanna980e142018-02-12 11:45:23 -0800347 private int uninstallSystemUpdates() {
348 final PrintWriter pw = getOutPrintWriter();
349 List<String> failedUninstalls = new LinkedList<>();
350 try {
351 final ParceledListSlice<ApplicationInfo> packages =
352 mInterface.getInstalledApplications(
353 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
354 final IPackageInstaller installer = mInterface.getPackageInstaller();
355 List<ApplicationInfo> list = packages.getList();
356 for (ApplicationInfo info : list) {
357 if (info.isUpdatedSystemApp()) {
358 pw.println("Uninstalling updates to " + info.packageName + "...");
359 final LocalIntentReceiver receiver = new LocalIntentReceiver();
360 installer.uninstall(new VersionedPackage(info.packageName,
361 info.versionCode), null /*callerPackageName*/, 0 /* flags */,
362 receiver.getIntentSender(), 0);
363
364 final Intent result = receiver.getResult();
365 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
366 PackageInstaller.STATUS_FAILURE);
367 if (status != PackageInstaller.STATUS_SUCCESS) {
368 failedUninstalls.add(info.packageName);
369 }
370 }
371 }
372 } catch (RemoteException e) {
373 pw.println("Failure ["
374 + e.getClass().getName() + " - "
375 + e.getMessage() + "]");
376 return 0;
377 }
378 if (!failedUninstalls.isEmpty()) {
379 pw.println("Failure [Couldn't uninstall packages: "
380 + TextUtils.join(", ", failedUninstalls)
381 + "]");
382 return 0;
383 }
384 pw.println("Success");
385 return 1;
386 }
387
Narayan Kamathc5d752e2019-01-23 14:06:35 +0000388 private int runRollbackApp() {
389 final PrintWriter pw = getOutPrintWriter();
390
391 final String packageName = getNextArgRequired();
392 if (packageName == null) {
393 pw.println("Error: package name not specified");
394 return 1;
395 }
396
397 final LocalIntentReceiver receiver = new LocalIntentReceiver();
398 try {
399 IRollbackManager rm = IRollbackManager.Stub.asInterface(
400 ServiceManager.getService(Context.ROLLBACK_SERVICE));
401
402 RollbackInfo rollback = null;
403 for (RollbackInfo r : (List<RollbackInfo>) rm.getAvailableRollbacks().getList()) {
404 for (PackageRollbackInfo info : r.getPackages()) {
405 if (packageName.equals(info.getPackageName())) {
406 rollback = r;
407 break;
408 }
409 }
410 }
411
412 if (rollback == null) {
413 pw.println("No available rollbacks for: " + packageName);
414 return 1;
415 }
416
417 rm.commitRollback(rollback.getRollbackId(),
418 ParceledListSlice.<VersionedPackage>emptyList(),
419 "com.android.shell", receiver.getIntentSender());
420 } catch (RemoteException re) {
421 // Cannot happen.
422 }
423
424 final Intent result = receiver.getResult();
425 final int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
426 RollbackManager.STATUS_FAILURE);
427 if (status == RollbackManager.STATUS_SUCCESS) {
428 pw.println("Success");
429 return 0;
430 } else {
431 pw.println("Failure ["
432 + result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE) + "]");
433 return 1;
434 }
435 }
436
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700437 private void setParamsSize(InstallParams params, String inPath) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700438 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700439 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
440 if (fd == null) {
441 getErrPrintWriter().println("Error: Can't open file: " + inPath);
442 throw new IllegalArgumentException("Error: Can't open file: " + inPath);
443 }
444 try {
445 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
446 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
447 null, null);
448 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
Dianne Hackborn1704e3c2017-10-31 19:55:42 +0000449 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700450 } catch (PackageParserException | IOException e) {
451 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
452 throw new IllegalArgumentException(
453 "Error: Failed to parse APK file: " + inPath, e);
454 } finally {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900455 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700456 fd.close();
457 } catch (IOException e) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900458 }
459 }
460 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700461 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700462 /**
463 * Displays the package file for a package.
464 * @param pckg
465 */
466 private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
Bill Lin7fd81af2019-10-04 00:31:21 +0800467 PackageInfo info = mInterface.getPackageInfo(pckg, PackageManager.MATCH_APEX, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700468 if (info != null && info.applicationInfo != null) {
469 final PrintWriter pw = getOutPrintWriter();
470 pw.print("package:");
471 pw.println(info.applicationInfo.sourceDir);
472 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
473 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
474 pw.print("package:");
475 pw.println(splitSourceDir);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800476 }
477 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700478 return 0;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800479 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700480 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800481 }
482
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700483 private int runPath() throws RemoteException {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000484 int userId = UserHandle.USER_SYSTEM;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700485 String option = getNextOption();
486 if (option != null && option.equals("--user")) {
487 userId = UserHandle.parseUserArg(getNextArgRequired());
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000488 }
489
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700490 String pkg = getNextArgRequired();
491 if (pkg == null) {
492 getErrPrintWriter().println("Error: no package specified");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000493 return 1;
494 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700495 return displayPackageFilePath(pkg, userId);
David Sehra8777082016-05-24 15:25:23 -0700496 }
497
Todd Kennedy60459ab2015-10-30 11:32:16 -0700498 private int runList() throws RemoteException {
499 final PrintWriter pw = getOutPrintWriter();
500 final String type = getNextArg();
501 if (type == null) {
502 pw.println("Error: didn't specify type of data to list");
503 return -1;
504 }
505 switch(type) {
506 case "features":
507 return runListFeatures();
508 case "instrumentation":
509 return runListInstrumentation();
510 case "libraries":
511 return runListLibraries();
512 case "package":
513 case "packages":
514 return runListPackages(false /*showSourceDir*/);
515 case "permission-groups":
516 return runListPermissionGroups();
517 case "permissions":
518 return runListPermissions();
Mohammad Samiul Islam40110562019-09-02 14:37:33 +0100519 case "staged-sessions":
520 return runListStagedSessions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700521 case "users":
522 ServiceManager.getService("user").shellCommand(
523 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
524 new String[] { "list" }, getShellCallback(), adoptResultReceiver());
525 return 0;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700526 }
527 pw.println("Error: unknown list type '" + type + "'");
528 return -1;
529 }
530
531 private int runListFeatures() throws RemoteException {
532 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700533 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700534
535 // sort by name
536 Collections.sort(list, new Comparator<FeatureInfo>() {
537 public int compare(FeatureInfo o1, FeatureInfo o2) {
538 if (o1.name == o2.name) return 0;
539 if (o1.name == null) return -1;
540 if (o2.name == null) return 1;
541 return o1.name.compareTo(o2.name);
542 }
543 });
544
545 final int count = (list != null) ? list.size() : 0;
546 for (int p = 0; p < count; p++) {
547 FeatureInfo fi = list.get(p);
548 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700549 if (fi.name != null) {
550 pw.print(fi.name);
551 if (fi.version > 0) {
552 pw.print("=");
553 pw.print(fi.version);
554 }
555 pw.println();
556 } else {
557 pw.println("reqGlEsVersion=0x"
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700558 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700559 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700560 }
561 return 0;
562 }
563
564 private int runListInstrumentation() throws RemoteException {
565 final PrintWriter pw = getOutPrintWriter();
566 boolean showSourceDir = false;
567 String targetPackage = null;
568
569 try {
570 String opt;
571 while ((opt = getNextArg()) != null) {
572 switch (opt) {
573 case "-f":
574 showSourceDir = true;
575 break;
576 default:
577 if (opt.charAt(0) != '-') {
578 targetPackage = opt;
579 } else {
580 pw.println("Error: Unknown option: " + opt);
581 return -1;
582 }
583 break;
584 }
585 }
586 } catch (RuntimeException ex) {
587 pw.println("Error: " + ex.toString());
588 return -1;
589 }
590
591 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700592 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700593
594 // sort by target package
595 Collections.sort(list, new Comparator<InstrumentationInfo>() {
596 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
597 return o1.targetPackage.compareTo(o2.targetPackage);
598 }
599 });
600
601 final int count = (list != null) ? list.size() : 0;
602 for (int p = 0; p < count; p++) {
603 final InstrumentationInfo ii = list.get(p);
604 pw.print("instrumentation:");
605 if (showSourceDir) {
606 pw.print(ii.sourceDir);
607 pw.print("=");
608 }
609 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
610 pw.print(cn.flattenToShortString());
611 pw.print(" (target=");
612 pw.print(ii.targetPackage);
613 pw.println(")");
614 }
615 return 0;
616 }
617
618 private int runListLibraries() throws RemoteException {
619 final PrintWriter pw = getOutPrintWriter();
620 final List<String> list = new ArrayList<String>();
621 final String[] rawList = mInterface.getSystemSharedLibraryNames();
622 for (int i = 0; i < rawList.length; i++) {
623 list.add(rawList[i]);
624 }
625
626 // sort by name
627 Collections.sort(list, new Comparator<String>() {
628 public int compare(String o1, String o2) {
629 if (o1 == o2) return 0;
630 if (o1 == null) return -1;
631 if (o2 == null) return 1;
632 return o1.compareTo(o2);
633 }
634 });
635
636 final int count = (list != null) ? list.size() : 0;
637 for (int p = 0; p < count; p++) {
638 String lib = list.get(p);
639 pw.print("library:");
640 pw.println(lib);
641 }
642 return 0;
643 }
644
645 private int runListPackages(boolean showSourceDir) throws RemoteException {
646 final PrintWriter pw = getOutPrintWriter();
647 int getFlags = 0;
648 boolean listDisabled = false, listEnabled = false;
649 boolean listSystem = false, listThirdParty = false;
650 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700651 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800652 boolean showVersionCode = false;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900653 boolean listApexOnly = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700654 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700655 int userId = UserHandle.USER_SYSTEM;
656 try {
657 String opt;
658 while ((opt = getNextOption()) != null) {
659 switch (opt) {
660 case "-d":
661 listDisabled = true;
662 break;
663 case "-e":
664 listEnabled = true;
665 break;
Andreas Gampe1f110452018-06-04 11:47:48 -0700666 case "-a":
667 getFlags |= PackageManager.MATCH_KNOWN_PACKAGES;
668 getFlags |= PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
669 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700670 case "-f":
671 showSourceDir = true;
672 break;
673 case "-i":
674 listInstaller = true;
675 break;
676 case "-l":
677 // old compat
678 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700679 case "-s":
680 listSystem = true;
681 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700682 case "-U":
683 showUid = true;
684 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700685 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700686 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700687 break;
688 case "-3":
689 listThirdParty = true;
690 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800691 case "--show-versioncode":
692 showVersionCode = true;
693 break;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900694 case "--apex-only":
695 getFlags |= PackageManager.MATCH_APEX;
696 listApexOnly = true;
697 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700698 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800699 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700700 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700701 case "--uid":
702 showUid = true;
703 uid = Integer.parseInt(getNextArgRequired());
704 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700705 default:
706 pw.println("Error: Unknown option: " + opt);
707 return -1;
708 }
709 }
710 } catch (RuntimeException ex) {
711 pw.println("Error: " + ex.toString());
712 return -1;
713 }
714
715 final String filter = getNextArg();
716
717 @SuppressWarnings("unchecked")
718 final ParceledListSlice<PackageInfo> slice =
719 mInterface.getInstalledPackages(getFlags, userId);
720 final List<PackageInfo> packages = slice.getList();
721
722 final int count = packages.size();
723 for (int p = 0; p < count; p++) {
724 final PackageInfo info = packages.get(p);
725 if (filter != null && !info.packageName.contains(filter)) {
726 continue;
727 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900728 final boolean isApex = info.isApex;
729 if (uid != -1 && !isApex && info.applicationInfo.uid != uid) {
Felipe Lemeeece9862016-06-29 11:45:03 -0700730 continue;
731 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900732
733 final boolean isSystem = !isApex &&
Todd Kennedy60459ab2015-10-30 11:32:16 -0700734 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900735 final boolean isEnabled = !isApex && info.applicationInfo.enabled;
736 if ((!listDisabled || !isEnabled) &&
737 (!listEnabled || isEnabled) &&
Todd Kennedy60459ab2015-10-30 11:32:16 -0700738 (!listSystem || isSystem) &&
Jiyong Park4f49abe2018-12-11 13:37:17 +0900739 (!listThirdParty || !isSystem) &&
740 (!listApexOnly || isApex)) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700741 pw.print("package:");
JW Wang9a722632019-09-30 10:42:30 +0800742 if (showSourceDir) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700743 pw.print(info.applicationInfo.sourceDir);
744 pw.print("=");
745 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800746 pw.print(info.packageName);
Jiyong Parkf50a2932018-12-17 13:54:40 +0900747 if (showVersionCode) {
Todd Kennedybadc69a2017-01-24 11:05:47 -0800748 pw.print(" versionCode:");
Jiyong Parkf50a2932018-12-17 13:54:40 +0900749 if (info.applicationInfo != null) {
Dario Freni788ecb12019-01-23 18:49:32 +0000750 pw.print(info.applicationInfo.longVersionCode);
Jiyong Parkf50a2932018-12-17 13:54:40 +0900751 } else {
Dario Freni788ecb12019-01-23 18:49:32 +0000752 pw.print(info.getLongVersionCode());
Jiyong Parkf50a2932018-12-17 13:54:40 +0900753 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800754 }
Mohammad Samiul Islam6b7ad942019-05-07 20:28:00 +0100755 if (listInstaller) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700756 pw.print(" installer=");
757 pw.print(mInterface.getInstallerPackageName(info.packageName));
758 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900759 if (showUid && !isApex) {
Felipe Lemeeece9862016-06-29 11:45:03 -0700760 pw.print(" uid:");
761 pw.print(info.applicationInfo.uid);
762 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700763 pw.println();
764 }
765 }
766 return 0;
767 }
768
769 private int runListPermissionGroups() throws RemoteException {
770 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700771 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700772
773 final int count = pgs.size();
774 for (int p = 0; p < count ; p++) {
775 final PermissionGroupInfo pgi = pgs.get(p);
776 pw.print("permission group:");
777 pw.println(pgi.name);
778 }
779 return 0;
780 }
781
782 private int runListPermissions() throws RemoteException {
783 final PrintWriter pw = getOutPrintWriter();
784 boolean labels = false;
785 boolean groups = false;
786 boolean userOnly = false;
787 boolean summary = false;
788 boolean dangerousOnly = false;
789 String opt;
790 while ((opt = getNextOption()) != null) {
791 switch (opt) {
792 case "-d":
793 dangerousOnly = true;
794 break;
795 case "-f":
796 labels = true;
797 break;
798 case "-g":
799 groups = true;
800 break;
801 case "-s":
802 groups = true;
803 labels = true;
804 summary = true;
805 break;
806 case "-u":
807 userOnly = true;
808 break;
809 default:
810 pw.println("Error: Unknown option: " + opt);
811 return 1;
812 }
813 }
814
815 final ArrayList<String> groupList = new ArrayList<String>();
816 if (groups) {
817 final List<PermissionGroupInfo> infos =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700818 mInterface.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700819 final int count = infos.size();
820 for (int i = 0; i < count; i++) {
821 groupList.add(infos.get(i).name);
822 }
823 groupList.add(null);
824 } else {
825 final String grp = getNextArg();
826 groupList.add(grp);
827 }
828
829 if (dangerousOnly) {
830 pw.println("Dangerous Permissions:");
831 pw.println("");
832 doListPermissions(groupList, groups, labels, summary,
833 PermissionInfo.PROTECTION_DANGEROUS,
834 PermissionInfo.PROTECTION_DANGEROUS);
835 if (userOnly) {
836 pw.println("Normal Permissions:");
837 pw.println("");
838 doListPermissions(groupList, groups, labels, summary,
839 PermissionInfo.PROTECTION_NORMAL,
840 PermissionInfo.PROTECTION_NORMAL);
841 }
842 } else if (userOnly) {
843 pw.println("Dangerous and Normal Permissions:");
844 pw.println("");
845 doListPermissions(groupList, groups, labels, summary,
846 PermissionInfo.PROTECTION_NORMAL,
847 PermissionInfo.PROTECTION_DANGEROUS);
848 } else {
849 pw.println("All Permissions:");
850 pw.println("");
851 doListPermissions(groupList, groups, labels, summary,
852 -10000, 10000);
853 }
854 return 0;
855 }
856
Mohammad Samiul Islam40110562019-09-02 14:37:33 +0100857 private static class SessionDump {
858 boolean onlyParent; // Show parent sessions only
859 boolean onlyReady; // Show only staged sessions that are in ready state
860 boolean onlySessionId; // Show sessionId only
861 }
862
863 // Returns true if the provided flag is a session flag and given SessionDump was updated
864 private boolean setSessionFlag(String flag, SessionDump sessionDump) {
865 switch (flag) {
866 case "--only-parent":
867 sessionDump.onlyParent = true;
868 break;
869 case "--only-ready":
870 sessionDump.onlyReady = true;
871 break;
872 case "--only-sessionid":
873 sessionDump.onlySessionId = true;
874 break;
875 default:
876 return false;
877 }
878 return true;
879 }
880
881 private int runListStagedSessions() {
882 final IndentingPrintWriter pw = new IndentingPrintWriter(
883 getOutPrintWriter(), /* singleIndent */ " ", /* wrapLength */ 120);
884
885 SessionDump sessionDump = new SessionDump();
886 String opt;
887 while ((opt = getNextOption()) != null) {
888 if (!setSessionFlag(opt, sessionDump)) {
889 pw.println("Error: Unknown option: " + opt);
890 return -1;
891 }
892 }
893
894 try {
895 List<SessionInfo> stagedSessions =
896 mInterface.getPackageInstaller().getStagedSessions().getList();
897 printSessionList(pw, stagedSessions, sessionDump);
898 } catch (RemoteException e) {
899 pw.println("Failure ["
900 + e.getClass().getName() + " - "
901 + e.getMessage() + "]");
902 return -1;
903 }
904 return 1;
905 }
906
907 private void printSessionList(IndentingPrintWriter pw, List<SessionInfo> stagedSessions,
908 SessionDump sessionDump) {
909 final SparseArray<SessionInfo> sessionById = new SparseArray<>(stagedSessions.size());
910 for (SessionInfo session : stagedSessions) {
911 sessionById.put(session.getSessionId(), session);
912 }
913 for (SessionInfo session: stagedSessions) {
914 if (sessionDump.onlyReady && !session.isStagedSessionReady()) {
915 continue;
916 }
917 if (session.getParentSessionId() != SessionInfo.INVALID_ID) {
918 continue;
919 }
920 printSession(pw, session, sessionDump);
921 if (session.isMultiPackage() && !sessionDump.onlyParent) {
922 pw.increaseIndent();
923 final int[] childIds = session.getChildSessionIds();
924 for (int i = 0; i < childIds.length; i++) {
925 final SessionInfo childSession = sessionById.get(childIds[i]);
926 if (childSession == null) {
927 if (sessionDump.onlySessionId) {
928 pw.println(childIds[i]);
929 } else {
930 pw.println("sessionId = " + childIds[i] + "; not found");
931 }
932 } else {
933 printSession(pw, childSession, sessionDump);
934 }
935 }
936 pw.decreaseIndent();
937 }
938 }
939 }
940
941 private static void printSession(PrintWriter pw, SessionInfo session, SessionDump sessionDump) {
942 if (sessionDump.onlySessionId) {
943 pw.println(session.getSessionId());
944 return;
945 }
946 pw.println("sessionId = " + session.getSessionId()
947 + "; appPackageName = " + session.getAppPackageName()
948 + "; isStaged = " + session.isStaged()
949 + "; isReady = " + session.isStagedSessionReady()
950 + "; isApplied = " + session.isStagedSessionApplied()
951 + "; isFailed = " + session.isStagedSessionFailed() + ";");
952 }
953
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800954 private Intent parseIntentAndUser() throws URISyntaxException {
955 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700956 mBrief = false;
957 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800958 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
959 @Override
960 public boolean handleOption(String opt, ShellCommand cmd) {
961 if ("--user".equals(opt)) {
962 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
963 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700964 } else if ("--brief".equals(opt)) {
965 mBrief = true;
966 return true;
967 } else if ("--components".equals(opt)) {
968 mComponents = true;
969 return true;
Ng Zhi An73971312018-09-11 21:39:14 -0700970 } else if ("--query-flags".equals(opt)) {
971 mQueryFlags = Integer.decode(cmd.getNextArgRequired());
972 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800973 }
974 return false;
975 }
976 });
977 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
978 Binder.getCallingUid(), mTargetUser, false, false, null, null);
979 return intent;
980 }
981
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700982 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
983 boolean brief, boolean components) {
984 if (brief || components) {
985 final ComponentName comp;
986 if (ri.activityInfo != null) {
987 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
988 } else if (ri.serviceInfo != null) {
989 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
990 } else if (ri.providerInfo != null) {
991 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
992 } else {
993 comp = null;
994 }
995 if (comp != null) {
996 if (!components) {
997 pr.println(prefix + "priority=" + ri.priority
998 + " preferredOrder=" + ri.preferredOrder
999 + " match=0x" + Integer.toHexString(ri.match)
1000 + " specificIndex=" + ri.specificIndex
1001 + " isDefault=" + ri.isDefault);
1002 }
1003 pr.println(prefix + comp.flattenToShortString());
1004 return;
1005 }
1006 }
1007 ri.dump(pr, prefix);
1008 }
1009
Dianne Hackborn99878e92015-12-02 16:27:41 -08001010 private int runResolveActivity() {
1011 Intent intent;
1012 try {
1013 intent = parseIntentAndUser();
1014 } catch (URISyntaxException e) {
1015 throw new RuntimeException(e.getMessage(), e);
1016 }
1017 try {
Ng Zhi An73971312018-09-11 21:39:14 -07001018 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), mQueryFlags,
1019 mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -08001020 PrintWriter pw = getOutPrintWriter();
1021 if (ri == null) {
1022 pw.println("No activity found");
1023 } else {
1024 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001025 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -08001026 }
1027 } catch (RemoteException e) {
1028 throw new RuntimeException("Failed calling service", e);
1029 }
1030 return 0;
1031 }
1032
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001033 private int runQueryIntentActivities() {
1034 Intent intent;
1035 try {
1036 intent = parseIntentAndUser();
1037 } catch (URISyntaxException e) {
1038 throw new RuntimeException(e.getMessage(), e);
1039 }
1040 try {
Ng Zhi An73971312018-09-11 21:39:14 -07001041 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(),
1042 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001043 PrintWriter pw = getOutPrintWriter();
1044 if (result == null || result.size() <= 0) {
1045 pw.println("No activities found");
1046 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001047 if (!mComponents) {
1048 pw.print(result.size()); pw.println(" activities found:");
1049 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1050 for (int i = 0; i < result.size(); i++) {
1051 pw.print(" Activity #"); pw.print(i); pw.println(":");
1052 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1053 }
1054 } else {
1055 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1056 for (int i = 0; i < result.size(); i++) {
1057 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1058 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001059 }
1060 }
1061 } catch (RemoteException e) {
1062 throw new RuntimeException("Failed calling service", e);
1063 }
1064 return 0;
1065 }
1066
1067 private int runQueryIntentServices() {
1068 Intent intent;
1069 try {
1070 intent = parseIntentAndUser();
1071 } catch (URISyntaxException e) {
1072 throw new RuntimeException(e.getMessage(), e);
1073 }
1074 try {
Ng Zhi An73971312018-09-11 21:39:14 -07001075 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(),
1076 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001077 PrintWriter pw = getOutPrintWriter();
1078 if (result == null || result.size() <= 0) {
1079 pw.println("No services found");
1080 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001081 if (!mComponents) {
1082 pw.print(result.size()); pw.println(" services found:");
1083 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1084 for (int i = 0; i < result.size(); i++) {
1085 pw.print(" Service #"); pw.print(i); pw.println(":");
1086 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1087 }
1088 } else {
1089 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1090 for (int i = 0; i < result.size(); i++) {
1091 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1092 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001093 }
1094 }
1095 } catch (RemoteException e) {
1096 throw new RuntimeException("Failed calling service", e);
1097 }
1098 return 0;
1099 }
1100
1101 private int runQueryIntentReceivers() {
1102 Intent intent;
1103 try {
1104 intent = parseIntentAndUser();
1105 } catch (URISyntaxException e) {
1106 throw new RuntimeException(e.getMessage(), e);
1107 }
1108 try {
Ng Zhi An73971312018-09-11 21:39:14 -07001109 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(),
1110 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001111 PrintWriter pw = getOutPrintWriter();
1112 if (result == null || result.size() <= 0) {
1113 pw.println("No receivers found");
1114 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001115 if (!mComponents) {
1116 pw.print(result.size()); pw.println(" receivers found:");
1117 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1118 for (int i = 0; i < result.size(); i++) {
1119 pw.print(" Receiver #"); pw.print(i); pw.println(":");
1120 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1121 }
1122 } else {
1123 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1124 for (int i = 0; i < result.size(); i++) {
1125 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1126 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001127 }
1128 }
1129 } catch (RemoteException e) {
1130 throw new RuntimeException("Failed calling service", e);
1131 }
1132 return 0;
1133 }
1134
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001135 private int runInstall() throws RemoteException {
1136 final PrintWriter pw = getOutPrintWriter();
1137 final InstallParams params = makeInstallParams();
1138 final String inPath = getNextArg();
1139
1140 setParamsSize(params, inPath);
1141 final int sessionId = doCreateSession(params.sessionParams,
1142 params.installerPackageName, params.userId);
1143 boolean abandonSession = true;
1144 try {
1145 if (inPath == null && params.sessionParams.sizeBytes == -1) {
1146 pw.println("Error: must either specify a package size or an APK file");
1147 return 1;
1148 }
Dario Frenid8bf22e2018-08-31 14:18:04 +01001149 final boolean isApex =
1150 (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
1151 String splitName = "base." + (isApex ? "apex" : "apk");
1152 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001153 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
1154 return 1;
1155 }
1156 if (doCommitSession(sessionId, false /*logSuccess*/)
1157 != PackageInstaller.STATUS_SUCCESS) {
1158 return 1;
1159 }
1160 abandonSession = false;
Mohammad Samiul Islamf49c85f2019-05-17 18:02:12 +01001161
1162 if (!params.sessionParams.isStaged || !params.waitForStagedSessionReady) {
1163 pw.println("Success");
1164 return 0;
1165 }
1166
1167 long timeoutMs = params.timeoutMs <= 0
1168 ? DEFAULT_WAIT_MS
1169 : params.timeoutMs;
1170 PackageInstaller.SessionInfo si = mInterface.getPackageInstaller()
1171 .getSessionInfo(sessionId);
1172 long currentTime = System.currentTimeMillis();
1173 long endTime = currentTime + timeoutMs;
1174 // Using a loop instead of BroadcastReceiver since we can receive session update
1175 // broadcast only if packageInstallerName is "android". We can't always force
1176 // "android" as packageIntallerName, e.g, rollback auto implies
1177 // "-i com.android.shell".
1178 while (currentTime < endTime) {
1179 if (si != null
1180 && (si.isStagedSessionReady() || si.isStagedSessionFailed())) {
1181 break;
1182 }
1183 SystemClock.sleep(Math.min(endTime - currentTime, 100));
1184 currentTime = System.currentTimeMillis();
1185 si = mInterface.getPackageInstaller().getSessionInfo(sessionId);
1186 }
1187 if (si == null) {
1188 pw.println("Failure [failed to retrieve SessionInfo]");
1189 return 1;
1190 }
1191 if (!si.isStagedSessionReady() && !si.isStagedSessionFailed()) {
1192 pw.println("Failure [timed out after " + timeoutMs + " ms]");
1193 return 1;
1194 }
1195 if (!si.isStagedSessionReady()) {
1196 pw.println("Error [" + si.getStagedSessionErrorCode() + "] ["
1197 + si.getStagedSessionErrorMessage() + "]");
1198 return 1;
1199 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001200 pw.println("Success");
1201 return 0;
1202 } finally {
1203 if (abandonSession) {
1204 try {
1205 doAbandonSession(sessionId, false /*logSuccess*/);
1206 } catch (Exception ignore) {
1207 }
1208 }
1209 }
1210 }
1211
1212 private int runInstallAbandon() throws RemoteException {
1213 final int sessionId = Integer.parseInt(getNextArg());
1214 return doAbandonSession(sessionId, true /*logSuccess*/);
1215 }
1216
1217 private int runInstallCommit() throws RemoteException {
1218 final int sessionId = Integer.parseInt(getNextArg());
1219 return doCommitSession(sessionId, true /*logSuccess*/);
1220 }
1221
1222 private int runInstallCreate() throws RemoteException {
1223 final PrintWriter pw = getOutPrintWriter();
1224 final InstallParams installParams = makeInstallParams();
1225 final int sessionId = doCreateSession(installParams.sessionParams,
1226 installParams.installerPackageName, installParams.userId);
1227
1228 // NOTE: adb depends on parsing this string
1229 pw.println("Success: created install session [" + sessionId + "]");
1230 return 0;
1231 }
1232
1233 private int runInstallWrite() throws RemoteException {
1234 long sizeBytes = -1;
1235
1236 String opt;
1237 while ((opt = getNextOption()) != null) {
1238 if (opt.equals("-S")) {
1239 sizeBytes = Long.parseLong(getNextArg());
1240 } else {
1241 throw new IllegalArgumentException("Unknown option: " + opt);
1242 }
1243 }
1244
1245 final int sessionId = Integer.parseInt(getNextArg());
1246 final String splitName = getNextArg();
1247 final String path = getNextArg();
1248 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
1249 }
1250
Patrick Baumann0aff9b12018-11-08 14:05:08 +00001251 private int runInstallAddSession() throws RemoteException {
1252 final PrintWriter pw = getOutPrintWriter();
1253 final int parentSessionId = Integer.parseInt(getNextArg());
1254
1255 List<Integer> otherSessionIds = new ArrayList<>();
1256 String opt;
1257 while ((opt = getNextArg()) != null) {
1258 otherSessionIds.add(Integer.parseInt(opt));
1259 }
1260 if (otherSessionIds.size() == 0) {
1261 pw.println("Error: At least two sessions are required.");
1262 return 1;
1263 }
1264 return doInstallAddSession(parentSessionId, ArrayUtils.convertToIntArray(otherSessionIds),
1265 true /*logSuccess*/);
1266 }
1267
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001268 private int runInstallRemove() throws RemoteException {
1269 final PrintWriter pw = getOutPrintWriter();
1270
1271 final int sessionId = Integer.parseInt(getNextArg());
1272
1273 final String splitName = getNextArg();
1274 if (splitName == null) {
1275 pw.println("Error: split name not specified");
1276 return 1;
1277 }
1278 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
1279 }
1280
1281 private int runInstallExisting() throws RemoteException {
1282 final PrintWriter pw = getOutPrintWriter();
1283 int userId = UserHandle.USER_SYSTEM;
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07001284 int installFlags = PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001285 String opt;
Chandan Nathe8e463b2019-01-28 15:23:38 +00001286 boolean waitTillComplete = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001287 while ((opt = getNextOption()) != null) {
1288 switch (opt) {
1289 case "--user":
1290 userId = UserHandle.parseUserArg(getNextArgRequired());
1291 break;
1292 case "--ephemeral":
1293 case "--instant":
1294 installFlags |= PackageManager.INSTALL_INSTANT_APP;
1295 installFlags &= ~PackageManager.INSTALL_FULL_APP;
1296 break;
1297 case "--full":
1298 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1299 installFlags |= PackageManager.INSTALL_FULL_APP;
1300 break;
Chandan Nathe8e463b2019-01-28 15:23:38 +00001301 case "--wait":
1302 waitTillComplete = true;
1303 break;
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07001304 case "--restrict-permissions":
1305 installFlags &= ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
1306 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001307 default:
1308 pw.println("Error: Unknown option: " + opt);
1309 return 1;
1310 }
1311 }
1312
1313 final String packageName = getNextArg();
1314 if (packageName == null) {
1315 pw.println("Error: package name not specified");
1316 return 1;
1317 }
1318
Chandan Nathe8e463b2019-01-28 15:23:38 +00001319 int installReason = PackageManager.INSTALL_REASON_UNKNOWN;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001320 try {
Chandan Nathe8e463b2019-01-28 15:23:38 +00001321 if (waitTillComplete) {
1322 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1323 final IPackageInstaller installer = mInterface.getPackageInstaller();
1324 pw.println("Installing package " + packageName + " for user: " + userId);
1325 installer.installExistingPackage(packageName, installFlags, installReason,
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07001326 receiver.getIntentSender(), userId, null);
Chandan Nathe8e463b2019-01-28 15:23:38 +00001327 final Intent result = receiver.getResult();
1328 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1329 PackageInstaller.STATUS_FAILURE);
1330 pw.println("Received intent for package install");
1331 return status == PackageInstaller.STATUS_SUCCESS ? 0 : 1;
1332 }
1333
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001334 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07001335 installFlags, installReason, null);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001336 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
1337 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1338 }
1339 pw.println("Package " + packageName + " installed for user: " + userId);
1340 return 0;
1341 } catch (RemoteException | NameNotFoundException e) {
1342 pw.println(e.toString());
1343 return 1;
1344 }
1345 }
1346
1347 private int runSetInstallLocation() throws RemoteException {
1348 int loc;
1349
1350 String arg = getNextArg();
1351 if (arg == null) {
1352 getErrPrintWriter().println("Error: no install location specified.");
1353 return 1;
1354 }
1355 try {
1356 loc = Integer.parseInt(arg);
1357 } catch (NumberFormatException e) {
1358 getErrPrintWriter().println("Error: install location has to be a number.");
1359 return 1;
1360 }
1361 if (!mInterface.setInstallLocation(loc)) {
1362 getErrPrintWriter().println("Error: install location has to be a number.");
1363 return 1;
1364 }
1365 return 0;
1366 }
1367
1368 private int runGetInstallLocation() throws RemoteException {
1369 int loc = mInterface.getInstallLocation();
1370 String locStr = "invalid";
1371 if (loc == PackageHelper.APP_INSTALL_AUTO) {
1372 locStr = "auto";
1373 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
1374 locStr = "internal";
1375 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
1376 locStr = "external";
1377 }
1378 getOutPrintWriter().println(loc + "[" + locStr + "]");
1379 return 0;
1380 }
1381
1382 public int runMovePackage() throws RemoteException {
1383 final String packageName = getNextArg();
1384 if (packageName == null) {
1385 getErrPrintWriter().println("Error: package name not specified");
1386 return 1;
1387 }
1388 String volumeUuid = getNextArg();
1389 if ("internal".equals(volumeUuid)) {
1390 volumeUuid = null;
1391 }
1392
1393 final int moveId = mInterface.movePackage(packageName, volumeUuid);
1394
1395 int status = mInterface.getMoveStatus(moveId);
1396 while (!PackageManager.isMoveStatusFinished(status)) {
1397 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1398 status = mInterface.getMoveStatus(moveId);
1399 }
1400
1401 if (status == PackageManager.MOVE_SUCCEEDED) {
1402 getOutPrintWriter().println("Success");
1403 return 0;
1404 } else {
1405 getErrPrintWriter().println("Failure [" + status + "]");
1406 return 1;
1407 }
1408 }
1409
1410 public int runMovePrimaryStorage() throws RemoteException {
1411 String volumeUuid = getNextArg();
1412 if ("internal".equals(volumeUuid)) {
1413 volumeUuid = null;
1414 }
1415
1416 final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1417
1418 int status = mInterface.getMoveStatus(moveId);
1419 while (!PackageManager.isMoveStatusFinished(status)) {
1420 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1421 status = mInterface.getMoveStatus(moveId);
1422 }
1423
1424 if (status == PackageManager.MOVE_SUCCEEDED) {
1425 getOutPrintWriter().println("Success");
1426 return 0;
1427 } else {
1428 getErrPrintWriter().println("Failure [" + status + "]");
1429 return 1;
1430 }
1431 }
1432
1433 private int runCompile() throws RemoteException {
1434 final PrintWriter pw = getOutPrintWriter();
1435 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1436 boolean forceCompilation = false;
1437 boolean allPackages = false;
1438 boolean clearProfileData = false;
1439 String compilerFilter = null;
1440 String compilationReason = null;
1441 String checkProfilesRaw = null;
1442 boolean secondaryDex = false;
1443 String split = null;
Eric Holka1485f62019-01-07 13:58:25 -08001444 boolean compileLayouts = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001445
1446 String opt;
1447 while ((opt = getNextOption()) != null) {
1448 switch (opt) {
1449 case "-a":
1450 allPackages = true;
1451 break;
1452 case "-c":
1453 clearProfileData = true;
1454 break;
1455 case "-f":
1456 forceCompilation = true;
1457 break;
1458 case "-m":
1459 compilerFilter = getNextArgRequired();
1460 break;
1461 case "-r":
1462 compilationReason = getNextArgRequired();
1463 break;
Eric Holka1485f62019-01-07 13:58:25 -08001464 case "--compile-layouts":
1465 compileLayouts = true;
1466 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001467 case "--check-prof":
1468 checkProfilesRaw = getNextArgRequired();
1469 break;
1470 case "--reset":
1471 forceCompilation = true;
1472 clearProfileData = true;
1473 compilationReason = "install";
1474 break;
1475 case "--secondary-dex":
1476 secondaryDex = true;
1477 break;
1478 case "--split":
1479 split = getNextArgRequired();
1480 break;
1481 default:
1482 pw.println("Error: Unknown option: " + opt);
1483 return 1;
1484 }
1485 }
1486
1487 if (checkProfilesRaw != null) {
1488 if ("true".equals(checkProfilesRaw)) {
1489 checkProfiles = true;
1490 } else if ("false".equals(checkProfilesRaw)) {
1491 checkProfiles = false;
1492 } else {
1493 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1494 return 1;
1495 }
1496 }
1497
Eric Holka1485f62019-01-07 13:58:25 -08001498 final boolean compilerFilterGiven = compilerFilter != null;
1499 final boolean compilationReasonGiven = compilationReason != null;
1500 // Make sure exactly one of -m, -r, or --compile-layouts is given.
1501 if ((!compilerFilterGiven && !compilationReasonGiven && !compileLayouts)
1502 || (!compilerFilterGiven && compilationReasonGiven && compileLayouts)
1503 || (compilerFilterGiven && !compilationReasonGiven && compileLayouts)
1504 || (compilerFilterGiven && compilationReasonGiven && !compileLayouts)
1505 || (compilerFilterGiven && compilationReasonGiven && compileLayouts)) {
1506 pw.println("Must specify exactly one of compilation filter (\"-m\"), compilation " +
1507 "reason (\"-r\"), or compile layouts (\"--compile-layouts\")");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001508 return 1;
1509 }
1510
1511 if (allPackages && split != null) {
1512 pw.println("-a cannot be specified together with --split");
1513 return 1;
1514 }
1515
1516 if (secondaryDex && split != null) {
1517 pw.println("--secondary-dex cannot be specified together with --split");
1518 return 1;
1519 }
1520
Eric Holka1485f62019-01-07 13:58:25 -08001521 String targetCompilerFilter = null;
1522 if (compilerFilterGiven) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001523 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1524 pw.println("Error: \"" + compilerFilter +
1525 "\" is not a valid compilation filter.");
1526 return 1;
1527 }
1528 targetCompilerFilter = compilerFilter;
Eric Holka1485f62019-01-07 13:58:25 -08001529 }
1530 if (compilationReasonGiven) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001531 int reason = -1;
1532 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1533 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1534 compilationReason)) {
1535 reason = i;
1536 break;
1537 }
1538 }
1539 if (reason == -1) {
1540 pw.println("Error: Unknown compilation reason: " + compilationReason);
1541 return 1;
1542 }
1543 targetCompilerFilter =
1544 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1545 }
1546
1547
1548 List<String> packageNames = null;
1549 if (allPackages) {
1550 packageNames = mInterface.getAllPackages();
1551 } else {
1552 String packageName = getNextArg();
1553 if (packageName == null) {
1554 pw.println("Error: package name not specified");
1555 return 1;
1556 }
1557 packageNames = Collections.singletonList(packageName);
1558 }
1559
1560 List<String> failedPackages = new ArrayList<>();
Andreas Gampecbd08d42017-11-20 17:03:17 -08001561 int index = 0;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001562 for (String packageName : packageNames) {
1563 if (clearProfileData) {
1564 mInterface.clearApplicationProfileData(packageName);
1565 }
1566
Andreas Gampecbd08d42017-11-20 17:03:17 -08001567 if (allPackages) {
1568 pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1569 pw.flush();
1570 }
1571
Eric Holka1485f62019-01-07 13:58:25 -08001572 boolean result = true;
1573 if (compileLayouts) {
1574 PackageManagerInternal internal = LocalServices.getService(
1575 PackageManagerInternal.class);
1576 result = internal.compileLayouts(packageName);
1577 } else {
1578 result = secondaryDex
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001579 ? mInterface.performDexOptSecondary(packageName,
1580 targetCompilerFilter, forceCompilation)
1581 : mInterface.performDexOptMode(packageName,
1582 checkProfiles, targetCompilerFilter, forceCompilation,
1583 true /* bootComplete */, split);
Eric Holka1485f62019-01-07 13:58:25 -08001584 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001585 if (!result) {
1586 failedPackages.add(packageName);
1587 }
1588 }
1589
1590 if (failedPackages.isEmpty()) {
1591 pw.println("Success");
1592 return 0;
1593 } else if (failedPackages.size() == 1) {
1594 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1595 return 1;
1596 } else {
1597 pw.print("Failure: the following packages could not be compiled: ");
1598 boolean is_first = true;
1599 for (String packageName : failedPackages) {
1600 if (is_first) {
1601 is_first = false;
1602 } else {
1603 pw.print(", ");
1604 }
1605 pw.print(packageName);
1606 }
1607 pw.println();
1608 return 1;
1609 }
1610 }
1611
1612 private int runreconcileSecondaryDexFiles() throws RemoteException {
1613 String packageName = getNextArg();
1614 mInterface.reconcileSecondaryDexFiles(packageName);
1615 return 0;
1616 }
1617
1618 public int runForceDexOpt() throws RemoteException {
1619 mInterface.forceDexOpt(getNextArgRequired());
1620 return 0;
1621 }
1622
1623 private int runDexoptJob() throws RemoteException {
Arthur Eubanks09dd1ec2017-09-15 09:28:51 -07001624 String arg;
1625 List<String> packageNames = new ArrayList<>();
1626 while ((arg = getNextArg()) != null) {
1627 packageNames.add(arg);
1628 }
1629 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1630 packageNames);
Andreas Gampefa8b57d2018-08-31 15:47:01 -07001631 getOutPrintWriter().println(result ? "Success" : "Failure");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001632 return result ? 0 : -1;
1633 }
1634
1635 private int runDumpProfiles() throws RemoteException {
1636 String packageName = getNextArg();
1637 mInterface.dumpProfiles(packageName);
1638 return 0;
1639 }
1640
Calin Juravle21216c62018-05-04 17:35:29 -07001641 private int runSnapshotProfile() throws RemoteException {
1642 PrintWriter pw = getOutPrintWriter();
1643
1644 // Parse the arguments
1645 final String packageName = getNextArg();
1646 final boolean isBootImage = "android".equals(packageName);
1647
1648 String codePath = null;
1649 String opt;
1650 while ((opt = getNextArg()) != null) {
1651 switch (opt) {
1652 case "--code-path":
1653 if (isBootImage) {
1654 pw.write("--code-path cannot be used for the boot image.");
1655 return -1;
1656 }
1657 codePath = getNextArg();
1658 break;
1659 default:
1660 pw.write("Unknown arg: " + opt);
1661 return -1;
1662 }
1663 }
1664
1665 // If no code path was explicitly requested, select the base code path.
1666 String baseCodePath = null;
1667 if (!isBootImage) {
1668 PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
1669 /* userId */0);
1670 if (packageInfo == null) {
1671 pw.write("Package not found " + packageName);
1672 return -1;
1673 }
1674 baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
1675 if (codePath == null) {
1676 codePath = baseCodePath;
1677 }
1678 }
1679
1680 // Create the profile snapshot.
1681 final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
1682 // The calling package is needed to debug permission access.
1683 final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
1684 ? "root" : "com.android.shell";
1685 final int profileType = isBootImage
1686 ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
1687 if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
1688 pw.println("Error: Runtime profiling is not enabled");
1689 return -1;
1690 }
1691 mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
1692 codePath, callback, callingPackage);
1693 if (!callback.waitTillDone()) {
1694 pw.println("Error: callback not called");
1695 return callback.mErrCode;
1696 }
1697
1698 // Copy the snapshot profile to the output profile file.
1699 try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
1700 final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
1701 ? "" : ("-" + new File(codePath).getName());
1702 final String outputProfilePath =
1703 ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
1704 try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
1705 Streams.copy(inStream, outStream);
1706 }
Calin Juravlebdd94d92018-05-17 01:23:15 -07001707 // Give read permissions to the other group.
1708 Os.chmod(outputProfilePath, /*mode*/ 0644 );
1709 } catch (IOException | ErrnoException e) {
Calin Juravle21216c62018-05-04 17:35:29 -07001710 pw.println("Error when reading the profile fd: " + e.getMessage());
1711 e.printStackTrace(pw);
1712 return -1;
1713 }
1714 return 0;
1715 }
1716
1717 private static class SnapshotRuntimeProfileCallback
1718 extends ISnapshotRuntimeProfileCallback.Stub {
1719 private boolean mSuccess = false;
1720 private int mErrCode = -1;
1721 private ParcelFileDescriptor mProfileReadFd = null;
1722 private CountDownLatch mDoneSignal = new CountDownLatch(1);
1723
1724 @Override
1725 public void onSuccess(ParcelFileDescriptor profileReadFd) {
1726 mSuccess = true;
1727 try {
1728 // We need to dup the descriptor. We are in the same process as system server
1729 // and we will be receiving the same object (which will be closed on the
1730 // server side).
1731 mProfileReadFd = profileReadFd.dup();
1732 } catch (IOException e) {
1733 e.printStackTrace();
1734 }
1735 mDoneSignal.countDown();
1736 }
1737
1738 @Override
1739 public void onError(int errCode) {
1740 mSuccess = false;
1741 mErrCode = errCode;
1742 mDoneSignal.countDown();
1743 }
1744
1745 boolean waitTillDone() {
1746 boolean done = false;
1747 try {
1748 // The time-out is an arbitrary large value. Since this is a local call the result
1749 // will come very fast.
1750 done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS);
1751 } catch (InterruptedException ignored) {
1752 }
1753 return done && mSuccess;
1754 }
1755 }
1756
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001757 private int runUninstall() throws RemoteException {
1758 final PrintWriter pw = getOutPrintWriter();
1759 int flags = 0;
1760 int userId = UserHandle.USER_ALL;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001761 long versionCode = PackageManager.VERSION_CODE_HIGHEST;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001762
1763 String opt;
1764 while ((opt = getNextOption()) != null) {
1765 switch (opt) {
1766 case "-k":
1767 flags |= PackageManager.DELETE_KEEP_DATA;
1768 break;
1769 case "--user":
1770 userId = UserHandle.parseUserArg(getNextArgRequired());
1771 break;
1772 case "--versionCode":
Dianne Hackborn3accca02013-09-20 09:32:11 -07001773 versionCode = Long.parseLong(getNextArgRequired());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001774 break;
1775 default:
1776 pw.println("Error: Unknown option: " + opt);
1777 return 1;
1778 }
1779 }
1780
1781 final String packageName = getNextArg();
1782 if (packageName == null) {
1783 pw.println("Error: package name not specified");
1784 return 1;
1785 }
1786
1787 // if a split is specified, just remove it and not the whole package
1788 final String splitName = getNextArg();
1789 if (splitName != null) {
1790 return runRemoveSplit(packageName, splitName);
1791 }
1792
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08001793 userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001794 final LocalIntentReceiver receiver = new LocalIntentReceiver();
Nikita Ioffef012a222019-03-05 22:37:55 +00001795 PackageManagerInternal internal = LocalServices.getService(PackageManagerInternal.class);
1796
1797 if (internal.isApexPackage(packageName)) {
1798 internal.uninstallApex(packageName, versionCode, userId, receiver.getIntentSender());
1799 } else {
1800 if (userId == UserHandle.USER_ALL) {
1801 userId = UserHandle.USER_SYSTEM;
1802 flags |= PackageManager.DELETE_ALL_USERS;
1803 } else {
1804 final PackageInfo info = mInterface.getPackageInfo(packageName,
1805 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1806 if (info == null) {
1807 pw.println("Failure [not installed for " + userId + "]");
1808 return 1;
1809 }
1810 final boolean isSystem =
1811 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1812 // If we are being asked to delete a system app for just one
1813 // user set flag so it disables rather than reverting to system
1814 // version of the app.
1815 if (isSystem) {
1816 flags |= PackageManager.DELETE_SYSTEM_APP;
1817 }
1818 }
1819
1820 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1821 versionCode), null /*callerPackageName*/, flags,
1822 receiver.getIntentSender(), userId);
1823 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001824
1825 final Intent result = receiver.getResult();
1826 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1827 PackageInstaller.STATUS_FAILURE);
1828 if (status == PackageInstaller.STATUS_SUCCESS) {
1829 pw.println("Success");
1830 return 0;
1831 } else {
1832 pw.println("Failure ["
1833 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1834 return 1;
1835 }
1836 }
1837
1838 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1839 final PrintWriter pw = getOutPrintWriter();
1840 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1841 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1842 sessionParams.appPackageName = packageName;
1843 final int sessionId =
1844 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1845 boolean abandonSession = true;
1846 try {
1847 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1848 != PackageInstaller.STATUS_SUCCESS) {
1849 return 1;
1850 }
1851 if (doCommitSession(sessionId, false /*logSuccess*/)
1852 != PackageInstaller.STATUS_SUCCESS) {
1853 return 1;
1854 }
1855 abandonSession = false;
1856 pw.println("Success");
1857 return 0;
1858 } finally {
1859 if (abandonSession) {
1860 try {
1861 doAbandonSession(sessionId, false /*logSuccess*/);
1862 } catch (Exception ignore) {
1863 }
1864 }
1865 }
1866 }
1867
1868 static class ClearDataObserver extends IPackageDataObserver.Stub {
1869 boolean finished;
1870 boolean result;
1871
1872 @Override
1873 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1874 synchronized (this) {
1875 finished = true;
1876 result = succeeded;
1877 notifyAll();
1878 }
1879 }
1880 }
1881
1882 private int runClear() throws RemoteException {
1883 int userId = UserHandle.USER_SYSTEM;
1884 String option = getNextOption();
1885 if (option != null && option.equals("--user")) {
1886 userId = UserHandle.parseUserArg(getNextArgRequired());
1887 }
1888
1889 String pkg = getNextArg();
1890 if (pkg == null) {
1891 getErrPrintWriter().println("Error: no package specified");
1892 return 1;
1893 }
1894
1895 ClearDataObserver obs = new ClearDataObserver();
Christopher Tate1d99c392017-12-07 16:54:04 -08001896 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001897 synchronized (obs) {
1898 while (!obs.finished) {
1899 try {
1900 obs.wait();
1901 } catch (InterruptedException e) {
1902 }
1903 }
1904 }
1905
1906 if (obs.result) {
1907 getOutPrintWriter().println("Success");
1908 return 0;
1909 } else {
1910 getErrPrintWriter().println("Failed");
1911 return 1;
1912 }
1913 }
1914
1915 private static String enabledSettingToString(int state) {
1916 switch (state) {
1917 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1918 return "default";
1919 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1920 return "enabled";
1921 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1922 return "disabled";
1923 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1924 return "disabled-user";
1925 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1926 return "disabled-until-used";
1927 }
1928 return "unknown";
1929 }
1930
1931 private int runSetEnabledSetting(int state) throws RemoteException {
1932 int userId = UserHandle.USER_SYSTEM;
1933 String option = getNextOption();
1934 if (option != null && option.equals("--user")) {
1935 userId = UserHandle.parseUserArg(getNextArgRequired());
1936 }
1937
1938 String pkg = getNextArg();
1939 if (pkg == null) {
1940 getErrPrintWriter().println("Error: no package or component specified");
1941 return 1;
1942 }
1943 ComponentName cn = ComponentName.unflattenFromString(pkg);
1944 if (cn == null) {
1945 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1946 "shell:" + android.os.Process.myUid());
1947 getOutPrintWriter().println("Package " + pkg + " new state: "
1948 + enabledSettingToString(
1949 mInterface.getApplicationEnabledSetting(pkg, userId)));
1950 return 0;
1951 } else {
1952 mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1953 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1954 + enabledSettingToString(
1955 mInterface.getComponentEnabledSetting(cn, userId)));
1956 return 0;
1957 }
1958 }
1959
1960 private int runSetHiddenSetting(boolean state) throws RemoteException {
1961 int userId = UserHandle.USER_SYSTEM;
1962 String option = getNextOption();
1963 if (option != null && option.equals("--user")) {
1964 userId = UserHandle.parseUserArg(getNextArgRequired());
1965 }
1966
1967 String pkg = getNextArg();
1968 if (pkg == null) {
1969 getErrPrintWriter().println("Error: no package or component specified");
1970 return 1;
1971 }
1972 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1973 getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1974 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1975 return 0;
1976 }
1977
1978 private int runSuspend(boolean suspendedState) {
1979 final PrintWriter pw = getOutPrintWriter();
1980 int userId = UserHandle.USER_SYSTEM;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001981 String dialogMessage = null;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001982 final PersistableBundle appExtras = new PersistableBundle();
1983 final PersistableBundle launcherExtras = new PersistableBundle();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001984 String opt;
1985 while ((opt = getNextOption()) != null) {
1986 switch (opt) {
1987 case "--user":
1988 userId = UserHandle.parseUserArg(getNextArgRequired());
1989 break;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001990 case "--dialogMessage":
1991 dialogMessage = getNextArgRequired();
1992 break;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001993 case "--ael":
1994 case "--aes":
1995 case "--aed":
1996 case "--lel":
1997 case "--les":
1998 case "--led":
1999 final String key = getNextArgRequired();
2000 final String val = getNextArgRequired();
2001 if (!suspendedState) {
2002 break;
2003 }
2004 final PersistableBundle bundleToInsert =
2005 opt.startsWith("--a") ? appExtras : launcherExtras;
2006 switch (opt.charAt(4)) {
2007 case 'l':
2008 bundleToInsert.putLong(key, Long.valueOf(val));
2009 break;
2010 case 'd':
2011 bundleToInsert.putDouble(key, Double.valueOf(val));
2012 break;
2013 case 's':
2014 bundleToInsert.putString(key, val);
2015 break;
2016 }
2017 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002018 default:
2019 pw.println("Error: Unknown option: " + opt);
2020 return 1;
2021 }
2022 }
2023
Suprabh Shukla021b57a2018-03-08 18:21:50 -08002024 final String packageName = getNextArg();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002025 if (packageName == null) {
2026 pw.println("Error: package name not specified");
2027 return 1;
2028 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -08002029 final String callingPackage =
2030 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07002031
2032 final SuspendDialogInfo info;
2033 if (!TextUtils.isEmpty(dialogMessage)) {
2034 info = new SuspendDialogInfo.Builder()
2035 .setMessage(dialogMessage)
2036 .build();
2037 } else {
2038 info = null;
2039 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002040 try {
2041 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07002042 appExtras, launcherExtras, info, callingPackage, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002043 pw.println("Package " + packageName + " new suspended state: "
2044 + mInterface.isPackageSuspendedForUser(packageName, userId));
2045 return 0;
2046 } catch (RemoteException | IllegalArgumentException e) {
2047 pw.println(e.toString());
2048 return 1;
2049 }
2050 }
2051
2052 private int runGrantRevokePermission(boolean grant) throws RemoteException {
2053 int userId = UserHandle.USER_SYSTEM;
2054
2055 String opt = null;
2056 while ((opt = getNextOption()) != null) {
2057 if (opt.equals("--user")) {
2058 userId = UserHandle.parseUserArg(getNextArgRequired());
2059 }
2060 }
2061
2062 String pkg = getNextArg();
2063 if (pkg == null) {
2064 getErrPrintWriter().println("Error: no package specified");
2065 return 1;
2066 }
2067 String perm = getNextArg();
2068 if (perm == null) {
2069 getErrPrintWriter().println("Error: no permission specified");
2070 return 1;
2071 }
2072
2073 if (grant) {
2074 mInterface.grantRuntimePermission(pkg, perm, userId);
2075 } else {
2076 mInterface.revokeRuntimePermission(pkg, perm, userId);
2077 }
2078 return 0;
2079 }
2080
2081 private int runResetPermissions() throws RemoteException {
2082 mInterface.resetRuntimePermissions();
2083 return 0;
2084 }
2085
2086 private int runSetPermissionEnforced() throws RemoteException {
2087 final String permission = getNextArg();
2088 if (permission == null) {
2089 getErrPrintWriter().println("Error: no permission specified");
2090 return 1;
2091 }
2092 final String enforcedRaw = getNextArg();
2093 if (enforcedRaw == null) {
2094 getErrPrintWriter().println("Error: no enforcement specified");
2095 return 1;
2096 }
2097 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
2098 return 0;
2099 }
2100
Jiyong Park002fdbd2017-02-13 20:50:31 +09002101 private boolean isVendorApp(String pkg) {
2102 try {
2103 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
2104 return info != null && info.applicationInfo.isVendor();
2105 } catch (RemoteException e) {
2106 return false;
2107 }
2108 }
2109
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002110 private boolean isProductApp(String pkg) {
2111 try {
2112 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
2113 return info != null && info.applicationInfo.isProduct();
2114 } catch (RemoteException e) {
2115 return false;
2116 }
2117 }
2118
Jeongik Chaf6629832019-07-04 21:12:06 +09002119 private boolean isSystemExtApp(String pkg) {
Dario Freni2bef1762018-06-01 14:02:08 +01002120 try {
2121 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
Jeongik Chaf6629832019-07-04 21:12:06 +09002122 return info != null && info.applicationInfo.isSystemExt();
Dario Freni2bef1762018-06-01 14:02:08 +01002123 } catch (RemoteException e) {
2124 return false;
2125 }
2126 }
2127
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002128 private int runGetPrivappPermissions() {
2129 final String pkg = getNextArg();
2130 if (pkg == null) {
2131 getErrPrintWriter().println("Error: no package specified.");
2132 return 1;
2133 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002134
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002135 ArraySet<String> privAppPermissions = null;
2136 if (isVendorApp(pkg)) {
2137 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
2138 } else if (isProductApp(pkg)) {
2139 privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
Jeongik Chaf6629832019-07-04 21:12:06 +09002140 } else if (isSystemExtApp(pkg)) {
Dario Freni2bef1762018-06-01 14:02:08 +01002141 privAppPermissions = SystemConfig.getInstance()
Jeongik Chaf6629832019-07-04 21:12:06 +09002142 .getSystemExtPrivAppPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002143 } else {
2144 privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
2145 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002146
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002147 getOutPrintWriter().println(privAppPermissions == null
2148 ? "{}" : privAppPermissions.toString());
2149 return 0;
2150 }
2151
2152 private int runGetPrivappDenyPermissions() {
2153 final String pkg = getNextArg();
2154 if (pkg == null) {
2155 getErrPrintWriter().println("Error: no package specified.");
2156 return 1;
2157 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002158
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002159 ArraySet<String> privAppPermissions = null;
2160 if (isVendorApp(pkg)) {
2161 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
2162 } else if (isProductApp(pkg)) {
2163 privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
Jeongik Chaf6629832019-07-04 21:12:06 +09002164 } else if (isSystemExtApp(pkg)) {
Dario Freni2bef1762018-06-01 14:02:08 +01002165 privAppPermissions = SystemConfig.getInstance()
Jeongik Chaf6629832019-07-04 21:12:06 +09002166 .getSystemExtPrivAppDenyPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002167 } else {
2168 privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
2169 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002170
2171 getOutPrintWriter().println(privAppPermissions == null
2172 ? "{}" : privAppPermissions.toString());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002173 return 0;
2174 }
2175
2176 private int runGetOemPermissions() {
2177 final String pkg = getNextArg();
2178 if (pkg == null) {
2179 getErrPrintWriter().println("Error: no package specified.");
2180 return 1;
2181 }
2182 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
2183 .getOemPermissions(pkg);
2184 if (oemPermissions == null || oemPermissions.isEmpty()) {
2185 getOutPrintWriter().println("{}");
2186 } else {
2187 oemPermissions.forEach((permission, granted) ->
2188 getOutPrintWriter().println(permission + " granted:" + granted)
2189 );
2190 }
2191 return 0;
2192 }
2193
2194 private String linkStateToString(int state) {
2195 switch (state) {
2196 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
2197 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
2198 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
2199 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
2200 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
2201 }
2202 return "Unknown link state: " + state;
2203 }
2204
2205 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
2206 private int runSetAppLink() throws RemoteException {
2207 int userId = UserHandle.USER_SYSTEM;
2208
2209 String opt;
2210 while ((opt = getNextOption()) != null) {
2211 if (opt.equals("--user")) {
2212 userId = UserHandle.parseUserArg(getNextArgRequired());
2213 } else {
2214 getErrPrintWriter().println("Error: unknown option: " + opt);
2215 return 1;
2216 }
2217 }
2218
2219 // Package name to act on; required
2220 final String pkg = getNextArg();
2221 if (pkg == null) {
2222 getErrPrintWriter().println("Error: no package specified.");
2223 return 1;
2224 }
2225
2226 // State to apply; {always|ask|never|undefined}, required
2227 final String modeString = getNextArg();
2228 if (modeString == null) {
2229 getErrPrintWriter().println("Error: no app link state specified.");
2230 return 1;
2231 }
2232
2233 final int newMode;
2234 switch (modeString.toLowerCase()) {
2235 case "undefined":
2236 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
2237 break;
2238
2239 case "always":
2240 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
2241 break;
2242
2243 case "ask":
2244 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
2245 break;
2246
2247 case "always-ask":
2248 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
2249 break;
2250
2251 case "never":
2252 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
2253 break;
2254
2255 default:
2256 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
2257 return 1;
2258 }
2259
2260 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
2261 if (info == null) {
2262 getErrPrintWriter().println("Error: package " + pkg + " not found.");
2263 return 1;
2264 }
2265
2266 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2267 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2268 return 1;
2269 }
2270
2271 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
2272 getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
2273 return 1;
2274 }
2275
2276 return 0;
2277 }
2278
2279 // pm get-app-link [--user USER_ID] PACKAGE
2280 private int runGetAppLink() throws RemoteException {
2281 int userId = UserHandle.USER_SYSTEM;
2282
2283 String opt;
2284 while ((opt = getNextOption()) != null) {
2285 if (opt.equals("--user")) {
2286 userId = UserHandle.parseUserArg(getNextArgRequired());
2287 } else {
2288 getErrPrintWriter().println("Error: unknown option: " + opt);
2289 return 1;
2290 }
2291 }
2292
2293 // Package name to act on; required
2294 final String pkg = getNextArg();
2295 if (pkg == null) {
2296 getErrPrintWriter().println("Error: no package specified.");
2297 return 1;
2298 }
2299
2300 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
2301 if (info == null) {
2302 getErrPrintWriter().println("Error: package " + pkg + " not found.");
2303 return 1;
2304 }
2305
2306 if ((info.applicationInfo.privateFlags
2307 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2308 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2309 return 1;
2310 }
2311
2312 getOutPrintWriter().println(linkStateToString(
2313 mInterface.getIntentVerificationStatus(pkg, userId)));
2314
2315 return 0;
2316 }
2317
2318 private int runTrimCaches() throws RemoteException {
2319 String size = getNextArg();
2320 if (size == null) {
2321 getErrPrintWriter().println("Error: no size specified");
2322 return 1;
2323 }
2324 long multiplier = 1;
2325 int len = size.length();
2326 char c = size.charAt(len - 1);
2327 if (c < '0' || c > '9') {
2328 if (c == 'K' || c == 'k') {
2329 multiplier = 1024L;
2330 } else if (c == 'M' || c == 'm') {
2331 multiplier = 1024L*1024L;
2332 } else if (c == 'G' || c == 'g') {
2333 multiplier = 1024L*1024L*1024L;
2334 } else {
2335 getErrPrintWriter().println("Invalid suffix: " + c);
2336 return 1;
2337 }
2338 size = size.substring(0, len-1);
2339 }
2340 long sizeVal;
2341 try {
2342 sizeVal = Long.parseLong(size) * multiplier;
2343 } catch (NumberFormatException e) {
2344 getErrPrintWriter().println("Error: expected number at: " + size);
2345 return 1;
2346 }
2347 String volumeUuid = getNextArg();
2348 if ("internal".equals(volumeUuid)) {
2349 volumeUuid = null;
2350 }
2351 ClearDataObserver obs = new ClearDataObserver();
2352 mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
2353 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
2354 synchronized (obs) {
2355 while (!obs.finished) {
2356 try {
2357 obs.wait();
2358 } catch (InterruptedException e) {
2359 }
2360 }
2361 }
2362 return 0;
2363 }
2364
2365 private static boolean isNumber(String s) {
2366 try {
2367 Integer.parseInt(s);
2368 } catch (NumberFormatException nfe) {
2369 return false;
2370 }
2371 return true;
2372 }
2373
2374 public int runCreateUser() throws RemoteException {
2375 String name;
2376 int userId = -1;
2377 int flags = 0;
2378 String opt;
2379 while ((opt = getNextOption()) != null) {
2380 if ("--profileOf".equals(opt)) {
2381 userId = UserHandle.parseUserArg(getNextArgRequired());
2382 } else if ("--managed".equals(opt)) {
2383 flags |= UserInfo.FLAG_MANAGED_PROFILE;
2384 } else if ("--restricted".equals(opt)) {
2385 flags |= UserInfo.FLAG_RESTRICTED;
2386 } else if ("--ephemeral".equals(opt)) {
2387 flags |= UserInfo.FLAG_EPHEMERAL;
2388 } else if ("--guest".equals(opt)) {
2389 flags |= UserInfo.FLAG_GUEST;
2390 } else if ("--demo".equals(opt)) {
2391 flags |= UserInfo.FLAG_DEMO;
2392 } else {
2393 getErrPrintWriter().println("Error: unknown option " + opt);
2394 return 1;
2395 }
2396 }
2397 String arg = getNextArg();
2398 if (arg == null) {
2399 getErrPrintWriter().println("Error: no user name specified.");
2400 return 1;
2401 }
2402 name = arg;
2403 UserInfo info;
2404 IUserManager um = IUserManager.Stub.asInterface(
2405 ServiceManager.getService(Context.USER_SERVICE));
2406 IAccountManager accm = IAccountManager.Stub.asInterface(
2407 ServiceManager.getService(Context.ACCOUNT_SERVICE));
2408 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
2409 // In non-split user mode, userId can only be SYSTEM
2410 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
2411 info = um.createRestrictedProfile(name, parentUserId);
2412 accm.addSharedAccountsFromParentUser(parentUserId, userId,
2413 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
2414 } else if (userId < 0) {
2415 info = um.createUser(name, flags);
2416 } else {
2417 info = um.createProfileForUser(name, flags, userId, null);
2418 }
2419
2420 if (info != null) {
2421 getOutPrintWriter().println("Success: created user id " + info.id);
2422 return 0;
2423 } else {
2424 getErrPrintWriter().println("Error: couldn't create User.");
2425 return 1;
2426 }
2427 }
2428
2429 public int runRemoveUser() throws RemoteException {
2430 int userId;
2431 String arg = getNextArg();
2432 if (arg == null) {
2433 getErrPrintWriter().println("Error: no user id specified.");
2434 return 1;
2435 }
2436 userId = UserHandle.parseUserArg(arg);
2437 IUserManager um = IUserManager.Stub.asInterface(
2438 ServiceManager.getService(Context.USER_SERVICE));
2439 if (um.removeUser(userId)) {
2440 getOutPrintWriter().println("Success: removed user");
2441 return 0;
2442 } else {
2443 getErrPrintWriter().println("Error: couldn't remove user id " + userId);
2444 return 1;
2445 }
2446 }
2447
2448 public int runSetUserRestriction() throws RemoteException {
2449 int userId = UserHandle.USER_SYSTEM;
2450 String opt = getNextOption();
2451 if (opt != null && "--user".equals(opt)) {
2452 userId = UserHandle.parseUserArg(getNextArgRequired());
2453 }
2454
2455 String restriction = getNextArg();
2456 String arg = getNextArg();
2457 boolean value;
2458 if ("1".equals(arg)) {
2459 value = true;
2460 } else if ("0".equals(arg)) {
2461 value = false;
2462 } else {
2463 getErrPrintWriter().println("Error: valid value not specified");
2464 return 1;
2465 }
2466 IUserManager um = IUserManager.Stub.asInterface(
2467 ServiceManager.getService(Context.USER_SERVICE));
2468 um.setUserRestriction(restriction, value, userId);
2469 return 0;
2470 }
2471
2472 public int runGetMaxUsers() {
2473 getOutPrintWriter().println("Maximum supported users: "
2474 + UserManager.getMaxSupportedUsers());
2475 return 0;
2476 }
2477
Alex Chauc12189b2018-01-16 15:01:15 +00002478 public int runGetMaxRunningUsers() {
2479 ActivityManagerInternal activityManagerInternal =
2480 LocalServices.getService(ActivityManagerInternal.class);
2481 getOutPrintWriter().println("Maximum supported running users: "
2482 + activityManagerInternal.getMaxRunningUsers());
2483 return 0;
2484 }
2485
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002486 private static class InstallParams {
2487 SessionParams sessionParams;
2488 String installerPackageName;
2489 int userId = UserHandle.USER_ALL;
Mohammad Samiul Islamf49c85f2019-05-17 18:02:12 +01002490 boolean waitForStagedSessionReady = false;
2491 long timeoutMs = DEFAULT_WAIT_MS;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002492 }
2493
2494 private InstallParams makeInstallParams() {
2495 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
2496 final InstallParams params = new InstallParams();
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07002497
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002498 params.sessionParams = sessionParams;
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07002499 // Whitelist all permissions by default
2500 sessionParams.installFlags |= PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
2501
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002502 String opt;
Patrick Baumanna9333492017-11-28 15:23:49 -08002503 boolean replaceExisting = true;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002504 while ((opt = getNextOption()) != null) {
2505 switch (opt) {
Patrick Baumanna9333492017-11-28 15:23:49 -08002506 case "-r": // ignore
2507 break;
2508 case "-R":
2509 replaceExisting = false;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002510 break;
2511 case "-i":
2512 params.installerPackageName = getNextArg();
2513 if (params.installerPackageName == null) {
2514 throw new IllegalArgumentException("Missing installer package");
2515 }
2516 break;
2517 case "-t":
2518 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
2519 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002520 case "-f":
2521 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
2522 break;
2523 case "-d":
Nikita Ioffeb1d60f12019-03-06 18:56:49 +00002524 sessionParams.installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002525 break;
2526 case "-g":
2527 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002528 break;
2529 case "--restrict-permissions":
2530 sessionParams.installFlags &=
2531 ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002532 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002533 case "--dont-kill":
2534 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
2535 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002536 case "--originating-uri":
2537 sessionParams.originatingUri = Uri.parse(getNextArg());
2538 break;
2539 case "--referrer":
2540 sessionParams.referrerUri = Uri.parse(getNextArg());
2541 break;
2542 case "-p":
2543 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
2544 sessionParams.appPackageName = getNextArg();
2545 if (sessionParams.appPackageName == null) {
2546 throw new IllegalArgumentException("Missing inherit package name");
2547 }
2548 break;
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002549 case "--pkg":
2550 sessionParams.appPackageName = getNextArg();
2551 if (sessionParams.appPackageName == null) {
2552 throw new IllegalArgumentException("Missing package name");
2553 }
2554 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002555 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002556 final long sizeBytes = Long.parseLong(getNextArg());
2557 if (sizeBytes <= 0) {
2558 throw new IllegalArgumentException("Size must be positive");
2559 }
2560 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002561 break;
2562 case "--abi":
2563 sessionParams.abiOverride = checkAbiArgument(getNextArg());
2564 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08002565 case "--ephemeral":
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002566 case "--instant":
Todd Kennedybe0b8892017-02-15 14:13:52 -08002567 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08002568 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08002569 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08002570 case "--full":
2571 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
2572 break;
Todd Kennedy78a72502017-07-19 12:49:30 -07002573 case "--preload":
2574 sessionParams.setInstallAsVirtualPreload();
2575 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002576 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002577 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002578 break;
2579 case "--install-location":
2580 sessionParams.installLocation = Integer.parseInt(getNextArg());
2581 break;
Sunny Goyalabd4d442018-09-19 15:49:50 -07002582 case "--install-reason":
2583 sessionParams.installReason = Integer.parseInt(getNextArg());
2584 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002585 case "--force-uuid":
2586 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
2587 sessionParams.volumeUuid = getNextArg();
2588 if ("internal".equals(sessionParams.volumeUuid)) {
2589 sessionParams.volumeUuid = null;
2590 }
2591 break;
Nicholas Lativyeb23e4d2019-02-01 13:39:28 +00002592 case "--force-sdk": // ignore
Todd Kennedyb1072712016-04-26 15:41:20 -07002593 break;
Dario Frenid8bf22e2018-08-31 14:18:04 +01002594 case "--apex":
Dario Freni3fa46d82019-01-23 19:31:47 +00002595 sessionParams.setInstallAsApex();
Dario Freni505b8152019-01-08 12:30:43 +00002596 sessionParams.setStaged();
Dario Frenid8bf22e2018-08-31 14:18:04 +01002597 break;
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002598 case "--multi-package":
2599 sessionParams.setMultiPackage();
2600 break;
Dario Freniaac4ba42018-12-06 15:47:16 +00002601 case "--staged":
2602 sessionParams.setStaged();
2603 break;
Richard Uhlerb29f1452018-09-12 16:38:15 +01002604 case "--enable-rollback":
Richard Uhler88184a62019-04-16 11:30:25 +01002605 if (params.installerPackageName == null) {
2606 // com.android.shell has the TEST_MANAGE_ROLLBACKS
2607 // permission needed to enable rollback for non-module
2608 // packages, which is likely what the user wants when
2609 // enabling rollback through the shell command. Set
2610 // the installer to com.android.shell if no installer
2611 // has been provided so that the user doesn't have to
2612 // remember to set it themselves.
2613 params.installerPackageName = "com.android.shell";
2614 }
Richard Uhlerb29f1452018-09-12 16:38:15 +01002615 sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
2616 break;
Mohammad Samiul Islamf49c85f2019-05-17 18:02:12 +01002617 case "--wait":
2618 params.waitForStagedSessionReady = true;
2619 try {
2620 params.timeoutMs = Long.parseLong(peekNextArg());
2621 getNextArg();
2622 } catch (NumberFormatException ignore) {
2623 }
2624 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002625 default:
2626 throw new IllegalArgumentException("Unknown option " + opt);
2627 }
Patrick Baumanndcf19162019-05-29 09:18:58 -07002628 }
2629 if (replaceExisting) {
2630 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002631 }
2632 return params;
2633 }
2634
Makoto Onuki4828a592016-03-15 18:06:57 -07002635 private int runSetHomeActivity() {
2636 final PrintWriter pw = getOutPrintWriter();
2637 int userId = UserHandle.USER_SYSTEM;
2638 String opt;
2639 while ((opt = getNextOption()) != null) {
2640 switch (opt) {
2641 case "--user":
2642 userId = UserHandle.parseUserArg(getNextArgRequired());
2643 break;
2644 default:
2645 pw.println("Error: Unknown option: " + opt);
2646 return 1;
2647 }
2648 }
2649
Bookatz2b5a6012019-04-16 19:41:28 -07002650 String pkgName;
Makoto Onuki4828a592016-03-15 18:06:57 -07002651 String component = getNextArg();
Bookatz2b5a6012019-04-16 19:41:28 -07002652 if (component.indexOf('/') < 0) {
2653 // No component specified, so assume it's just a package name.
2654 pkgName = component;
2655 } else {
2656 ComponentName componentName =
2657 component != null ? ComponentName.unflattenFromString(component) : null;
2658 if (componentName == null) {
2659 pw.println("Error: invalid component name");
2660 return 1;
2661 }
2662 pkgName = componentName.getPackageName();
Makoto Onuki4828a592016-03-15 18:06:57 -07002663 }
2664
Bookatz2b5a6012019-04-16 19:41:28 -07002665
2666 final CompletableFuture<Boolean> future = new CompletableFuture<>();
2667 final RemoteCallback callback = new RemoteCallback(res -> future.complete(res != null));
Makoto Onuki4828a592016-03-15 18:06:57 -07002668 try {
Bookatz2b5a6012019-04-16 19:41:28 -07002669 IRoleManager roleManager = android.app.role.IRoleManager.Stub.asInterface(
2670 ServiceManager.getServiceOrThrow(Context.ROLE_SERVICE));
2671 roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, pkgName,
2672 0, userId, callback);
2673 boolean success = future.get();
2674 if (success) {
2675 pw.println("Success");
2676 return 0;
2677 } else {
2678 pw.println("Error: Failed to set default home.");
2679 return 1;
2680 }
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002681 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07002682 pw.println(e.toString());
2683 return 1;
2684 }
2685 }
2686
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002687 private int runSetInstaller() throws RemoteException {
2688 final String targetPackage = getNextArg();
2689 final String installerPackageName = getNextArg();
Fyodor Kupolov51245c72016-12-01 11:34:10 -08002690
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002691 if (targetPackage == null || installerPackageName == null) {
2692 getErrPrintWriter().println("Must provide both target and installer package names");
Todd Kennedy74629e32017-08-15 14:48:07 -07002693 return 1;
2694 }
Todd Kennedy74629e32017-08-15 14:48:07 -07002695
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002696 mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2697 getOutPrintWriter().println("Success");
Svet Ganov087dce22017-09-07 15:42:16 -07002698 return 0;
2699 }
2700
Todd Kennedy0a3f0812017-05-08 14:43:15 -07002701 private int runGetInstantAppResolver() {
2702 final PrintWriter pw = getOutPrintWriter();
2703 try {
2704 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2705 if (instantAppsResolver == null) {
2706 return 1;
2707 }
2708 pw.println(instantAppsResolver.flattenToString());
2709 return 0;
2710 } catch (Exception e) {
2711 pw.println(e.toString());
2712 return 1;
2713 }
2714 }
2715
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09002716 private int runHasFeature() {
2717 final PrintWriter err = getErrPrintWriter();
2718 final String featureName = getNextArg();
2719 if (featureName == null) {
2720 err.println("Error: expected FEATURE name");
2721 return 1;
2722 }
2723 final String versionString = getNextArg();
2724 try {
2725 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2726 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2727 getOutPrintWriter().println(hasFeature);
2728 return hasFeature ? 0 : 1;
2729 } catch (NumberFormatException e) {
2730 err.println("Error: illegal version number " + versionString);
2731 return 1;
2732 } catch (RemoteException e) {
2733 err.println(e.toString());
2734 return 1;
2735 }
2736 }
2737
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002738 private int runDump() {
2739 String pkg = getNextArg();
2740 if (pkg == null) {
2741 getErrPrintWriter().println("Error: no package specified");
2742 return 1;
2743 }
2744 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2745 return 0;
2746 }
2747
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002748 private int runSetHarmfulAppWarning() throws RemoteException {
2749 int userId = UserHandle.USER_CURRENT;
2750
2751 String opt;
2752 while ((opt = getNextOption()) != null) {
2753 if (opt.equals("--user")) {
2754 userId = UserHandle.parseUserArg(getNextArgRequired());
2755 } else {
2756 getErrPrintWriter().println("Error: Unknown option: " + opt);
2757 return -1;
2758 }
2759 }
2760
2761 userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning");
2762
2763 final String packageName = getNextArgRequired();
2764 final String warning = getNextArg();
2765
2766 mInterface.setHarmfulAppWarning(packageName, warning, userId);
2767
2768 return 0;
2769 }
2770
Ben Gruver9ef60092018-01-10 11:32:30 -08002771 private int runGetHarmfulAppWarning() throws RemoteException {
2772 int userId = UserHandle.USER_CURRENT;
2773
2774 String opt;
2775 while ((opt = getNextOption()) != null) {
2776 if (opt.equals("--user")) {
2777 userId = UserHandle.parseUserArg(getNextArgRequired());
2778 } else {
2779 getErrPrintWriter().println("Error: Unknown option: " + opt);
2780 return -1;
2781 }
2782 }
2783
2784 userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning");
2785
2786 final String packageName = getNextArgRequired();
2787 final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId);
2788 if (!TextUtils.isEmpty(warning)) {
2789 getOutPrintWriter().println(warning);
2790 return 0;
2791 } else {
2792 return 1;
2793 }
2794 }
2795
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002796 private static String checkAbiArgument(String abi) {
2797 if (TextUtils.isEmpty(abi)) {
2798 throw new IllegalArgumentException("Missing ABI argument");
2799 }
2800
2801 if ("-".equals(abi)) {
2802 return abi;
2803 }
2804
2805 final String[] supportedAbis = Build.SUPPORTED_ABIS;
2806 for (String supportedAbi : supportedAbis) {
2807 if (supportedAbi.equals(abi)) {
2808 return abi;
2809 }
2810 }
2811
2812 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2813 }
2814
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002815 private int translateUserId(int userId, boolean allowAll, String logContext) {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002816 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002817 userId, allowAll, true, logContext, "pm command");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002818 }
2819
2820 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2821 throws RemoteException {
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002822 userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002823 if (userId == UserHandle.USER_ALL) {
2824 userId = UserHandle.USER_SYSTEM;
2825 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2826 }
2827
2828 final int sessionId = mInterface.getPackageInstaller()
2829 .createSession(params, installerPackageName, userId);
2830 return sessionId;
2831 }
2832
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002833 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002834 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002835 PackageInstaller.Session session = null;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002836 try {
Jeff Sharkeya651b782018-07-23 13:45:28 -06002837 final PrintWriter pw = getOutPrintWriter();
2838 final ParcelFileDescriptor fd;
2839 if (STDIN_PATH.equals(inPath)) {
2840 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2841 } else if (inPath != null) {
2842 fd = openFileForSystem(inPath, "r");
2843 if (fd == null) {
2844 return -1;
2845 }
2846 sizeBytes = fd.getStatSize();
2847 if (sizeBytes < 0) {
2848 getErrPrintWriter().println("Unable to get size of: " + inPath);
2849 return -1;
2850 }
2851 } else {
2852 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2853 }
2854 if (sizeBytes <= 0) {
2855 getErrPrintWriter().println("Error: must specify a APK size");
2856 return 1;
2857 }
2858
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002859 session = new PackageInstaller.Session(
2860 mInterface.getPackageInstaller().openSession(sessionId));
Jeff Sharkey0451de62018-02-02 11:27:21 -07002861 session.write(splitName, 0, sizeBytes, fd);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002862
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002863 if (logSuccess) {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002864 pw.println("Success: streamed " + sizeBytes + " bytes");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002865 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002866 return 0;
2867 } catch (IOException e) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002868 getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002869 return 1;
2870 } finally {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002871 IoUtils.closeQuietly(session);
2872 }
2873 }
2874
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002875 private int doInstallAddSession(int parentId, int[] sessionIds, boolean logSuccess)
2876 throws RemoteException {
2877 final PrintWriter pw = getOutPrintWriter();
2878 PackageInstaller.Session session = null;
2879 try {
2880 session = new PackageInstaller.Session(
2881 mInterface.getPackageInstaller().openSession(parentId));
2882 if (!session.isMultiPackage()) {
2883 getErrPrintWriter().println(
2884 "Error: parent session ID is not a multi-package session");
2885 return 1;
2886 }
2887 for (int i = 0; i < sessionIds.length; i++) {
2888 session.addChildSessionId(sessionIds[i]);
2889 }
2890 if (logSuccess) {
2891 pw.println("Success");
2892 }
2893 return 0;
2894 } finally {
2895 IoUtils.closeQuietly(session);
2896 }
2897 }
2898
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002899 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2900 throws RemoteException {
2901 final PrintWriter pw = getOutPrintWriter();
2902 PackageInstaller.Session session = null;
2903 try {
2904 session = new PackageInstaller.Session(
2905 mInterface.getPackageInstaller().openSession(sessionId));
2906 session.removeSplit(splitName);
2907
2908 if (logSuccess) {
2909 pw.println("Success");
2910 }
2911 return 0;
2912 } catch (IOException e) {
2913 pw.println("Error: failed to remove split; " + e.getMessage());
2914 return 1;
2915 } finally {
2916 IoUtils.closeQuietly(session);
2917 }
2918 }
2919
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002920 private int doCommitSession(int sessionId, boolean logSuccess)
2921 throws RemoteException {
2922
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002923 final PrintWriter pw = getOutPrintWriter();
2924 PackageInstaller.Session session = null;
2925 try {
2926 session = new PackageInstaller.Session(
2927 mInterface.getPackageInstaller().openSession(sessionId));
Dario Frenia8f4b132018-12-30 00:36:49 +00002928 if (!session.isMultiPackage() && !session.isStaged()) {
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002929 // Sanity check that all .dm files match an apk.
2930 // (The installer does not support standalone .dm files and will not process them.)
2931 try {
2932 DexMetadataHelper.validateDexPaths(session.getNames());
2933 } catch (IllegalStateException | IOException e) {
2934 pw.println(
2935 "Warning [Could not validate the dex paths: " + e.getMessage() + "]");
2936 }
Calin Juravle3fc56c32017-12-11 18:26:13 -08002937 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002938 final LocalIntentReceiver receiver = new LocalIntentReceiver();
2939 session.commit(receiver.getIntentSender());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002940 final Intent result = receiver.getResult();
2941 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2942 PackageInstaller.STATUS_FAILURE);
2943 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002944 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07002945 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002946 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002947 } else {
2948 pw.println("Failure ["
2949 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002950 }
2951 return status;
2952 } finally {
2953 IoUtils.closeQuietly(session);
2954 }
2955 }
2956
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002957 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002958 final PrintWriter pw = getOutPrintWriter();
2959 PackageInstaller.Session session = null;
2960 try {
2961 session = new PackageInstaller.Session(
2962 mInterface.getPackageInstaller().openSession(sessionId));
2963 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002964 if (logSuccess) {
2965 pw.println("Success");
2966 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002967 return 0;
2968 } finally {
2969 IoUtils.closeQuietly(session);
2970 }
2971 }
2972
Todd Kennedy60459ab2015-10-30 11:32:16 -07002973 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2974 boolean summary, int startProtectionLevel, int endProtectionLevel)
2975 throws RemoteException {
2976 final PrintWriter pw = getOutPrintWriter();
2977 final int groupCount = groupList.size();
2978 for (int i = 0; i < groupCount; i++) {
2979 String groupName = groupList.get(i);
2980 String prefix = "";
2981 if (groups) {
2982 if (i > 0) {
2983 pw.println("");
2984 }
2985 if (groupName != null) {
2986 PermissionGroupInfo pgi =
2987 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2988 if (summary) {
2989 Resources res = getResources(pgi);
2990 if (res != null) {
2991 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2992 } else {
2993 pw.print(pgi.name + ": ");
2994
2995 }
2996 } else {
2997 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2998 if (labels) {
2999 pw.println(" package:" + pgi.packageName);
3000 Resources res = getResources(pgi);
3001 if (res != null) {
3002 pw.println(" label:"
3003 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
3004 pw.println(" description:"
3005 + loadText(pgi, pgi.descriptionRes,
3006 pgi.nonLocalizedDescription));
3007 }
3008 }
3009 }
3010 } else {
3011 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
3012 }
3013 prefix = " ";
3014 }
3015 List<PermissionInfo> ps =
Jeff Sharkeyd5896632016-03-04 16:16:00 -07003016 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07003017 final int count = ps.size();
3018 boolean first = true;
3019 for (int p = 0 ; p < count ; p++) {
3020 PermissionInfo pi = ps.get(p);
3021 if (groups && groupName == null && pi.group != null) {
3022 continue;
3023 }
3024 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
3025 if (base < startProtectionLevel
3026 || base > endProtectionLevel) {
3027 continue;
3028 }
3029 if (summary) {
3030 if (first) {
3031 first = false;
3032 } else {
3033 pw.print(", ");
3034 }
3035 Resources res = getResources(pi);
3036 if (res != null) {
3037 pw.print(loadText(pi, pi.labelRes,
3038 pi.nonLocalizedLabel));
3039 } else {
3040 pw.print(pi.name);
3041 }
3042 } else {
3043 pw.println(prefix + (labels ? "+ " : "")
3044 + "permission:" + pi.name);
3045 if (labels) {
3046 pw.println(prefix + " package:" + pi.packageName);
3047 Resources res = getResources(pi);
3048 if (res != null) {
3049 pw.println(prefix + " label:"
3050 + loadText(pi, pi.labelRes,
3051 pi.nonLocalizedLabel));
3052 pw.println(prefix + " description:"
3053 + loadText(pi, pi.descriptionRes,
3054 pi.nonLocalizedDescription));
3055 }
3056 pw.println(prefix + " protectionLevel:"
3057 + PermissionInfo.protectionToString(pi.protectionLevel));
3058 }
3059 }
3060 }
3061
3062 if (summary) {
3063 pw.println("");
3064 }
3065 }
3066 }
3067
3068 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
3069 throws RemoteException {
3070 if (nonLocalized != null) {
3071 return nonLocalized.toString();
3072 }
3073 if (res != 0) {
3074 Resources r = getResources(pii);
3075 if (r != null) {
3076 try {
3077 return r.getString(res);
3078 } catch (Resources.NotFoundException e) {
3079 }
3080 }
3081 }
3082 return null;
3083 }
3084
3085 private Resources getResources(PackageItemInfo pii) throws RemoteException {
3086 Resources res = mResourceCache.get(pii.packageName);
3087 if (res != null) return res;
3088
3089 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
3090 AssetManager am = new AssetManager();
3091 am.addAssetPath(ai.publicSourceDir);
3092 res = new Resources(am, null, null);
3093 mResourceCache.put(pii.packageName, res);
3094 return res;
3095 }
3096
3097 @Override
3098 public void onHelp() {
3099 final PrintWriter pw = getOutPrintWriter();
3100 pw.println("Package manager (package) commands:");
3101 pw.println(" help");
3102 pw.println(" Print this help text.");
3103 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003104 pw.println(" path [--user USER_ID] PACKAGE");
3105 pw.println(" Print the path to the .apk of the given PACKAGE.");
3106 pw.println("");
3107 pw.println(" dump PACKAGE");
3108 pw.println(" Print various system state associated with the given PACKAGE.");
3109 pw.println("");
3110 pw.println(" list features");
3111 pw.println(" Prints all features of the system.");
3112 pw.println("");
3113 pw.println(" has-feature FEATURE_NAME [version]");
3114 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,");
3115 pw.println(" otherwise prints false and returns exit status 1");
3116 pw.println("");
3117 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
3118 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
3119 pw.println(" Options:");
3120 pw.println(" -f: dump the name of the .apk file containing the test package");
3121 pw.println("");
3122 pw.println(" list libraries");
3123 pw.println(" Prints all system libraries.");
3124 pw.println("");
3125 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
Jiyong Parkf50a2932018-12-17 13:54:40 +09003126 pw.println(" [--show-versioncode] [--apex-only] [--uid UID] [--user USER_ID] [FILTER]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003127 pw.println(" Prints all packages; optionally only those whose name contains");
3128 pw.println(" the text in FILTER. Options are:");
3129 pw.println(" -f: see their associated file");
Jiyong Park4f49abe2018-12-11 13:37:17 +09003130 pw.println(" -a: all known packages (but excluding APEXes)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003131 pw.println(" -d: filter to only show disabled packages");
3132 pw.println(" -e: filter to only show enabled packages");
3133 pw.println(" -s: filter to only show system packages");
3134 pw.println(" -3: filter to only show third party packages");
3135 pw.println(" -i: see the installer for the packages");
3136 pw.println(" -l: ignored (used for compatibility with older releases)");
3137 pw.println(" -U: also show the package UID");
3138 pw.println(" -u: also include uninstalled packages");
Jiyong Parkf50a2932018-12-17 13:54:40 +09003139 pw.println(" --show-versioncode: also show the version code");
Jiyong Park4f49abe2018-12-11 13:37:17 +09003140 pw.println(" --apex-only: only show APEX packages");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003141 pw.println(" --uid UID: filter to only show packages with the given UID");
3142 pw.println(" --user USER_ID: only list packages belonging to the given user");
3143 pw.println("");
3144 pw.println(" list permission-groups");
3145 pw.println(" Prints all known permission groups.");
3146 pw.println("");
3147 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
3148 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:");
3149 pw.println(" -g: organize by group");
3150 pw.println(" -f: print all information");
3151 pw.println(" -s: short summary");
3152 pw.println(" -d: only list dangerous permissions");
3153 pw.println(" -u: list only the permissions users will see");
3154 pw.println("");
Mohammad Samiul Islam40110562019-09-02 14:37:33 +01003155 pw.println(" list staged-sessions [--only-ready] [--only-sessionid] [--only-parent]");
3156 pw.println(" Displays list of all staged sessions on device.");
3157 pw.println(" --only-ready: show only staged sessions that are ready");
3158 pw.println(" --only-sessionid: show only sessionId of each session");
3159 pw.println(" --only-parent: hide all children sessions");
3160 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003161 pw.println(" resolve-activity [--brief] [--components] [--query-flags FLAGS]");
3162 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003163 pw.println(" Prints the activity that resolves to the given INTENT.");
3164 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003165 pw.println(" query-activities [--brief] [--components] [--query-flags FLAGS]");
3166 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003167 pw.println(" Prints all activities that can handle the given INTENT.");
3168 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003169 pw.println(" query-services [--brief] [--components] [--query-flags FLAGS]");
3170 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003171 pw.println(" Prints all services that can handle the given INTENT.");
3172 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003173 pw.println(" query-receivers [--brief] [--components] [--query-flags FLAGS]");
3174 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003175 pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
3176 pw.println("");
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003177 pw.println(" install [-lrtsfdgw] [-i PACKAGE] [--user USER_ID|all|current]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003178 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003179 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
3180 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003181 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
Richard Uhlerb29f1452018-09-12 16:38:15 +01003182 pw.println(" [--enable-rollback]");
Mohammad Samiul Islamf49c85f2019-05-17 18:02:12 +01003183 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
3184 pw.println(" [--apex] [--wait TIMEOUT]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003185 pw.println(" [PATH|-]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003186 pw.println(" Install an application. Must provide the apk data to install, either as a");
3187 pw.println(" file path or '-' to read from stdin. Options are:");
3188 pw.println(" -l: forward lock application");
Patrick Baumanna9333492017-11-28 15:23:49 -08003189 pw.println(" -R: disallow replacement of existing application");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003190 pw.println(" -t: allow test packages");
3191 pw.println(" -i: specify package name of installer owning the app");
3192 pw.println(" -s: install application on sdcard");
3193 pw.println(" -f: install application on internal flash");
3194 pw.println(" -d: allow version code downgrade (debuggable packages only)");
3195 pw.println(" -p: partial application install (new split on top of existing pkg)");
3196 pw.println(" -g: grant all runtime permissions");
3197 pw.println(" -S: size in bytes of package, required for stdin");
3198 pw.println(" --user: install under the given user.");
3199 pw.println(" --dont-kill: installing a new feature split, don't kill running app");
Svet Ganov83a3a4a2019-05-03 18:50:43 -07003200 pw.println(" --restrict-permissions: don't whitelist restricted permissions at install");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003201 pw.println(" --originating-uri: set URI where app was downloaded from");
3202 pw.println(" --referrer: set URI that instigated the install of the app");
3203 pw.println(" --pkg: specify expected package name of app being installed");
3204 pw.println(" --abi: override the default ABI of the platform");
3205 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app");
3206 pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
3207 pw.println(" --install-location: force the install location:");
3208 pw.println(" 0=auto, 1=internal only, 2=prefer external");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003209 pw.println(" --install-reason: indicates why the app is being installed:");
3210 pw.println(" 0=unknown, 1=admin policy, 2=device restore,");
3211 pw.println(" 3=device setup, 4=user request");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003212 pw.println(" --force-uuid: force install on to disk volume with given UUID");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003213 pw.println(" --apex: install an .apex file, not an .apk");
Mohammad Samiul Islamf49c85f2019-05-17 18:02:12 +01003214 pw.println(" --wait: when performing staged install, wait TIMEOUT milliseconds");
3215 pw.println(" for pre-reboot verification to complete. If TIMEOUT is not");
3216 pw.println(" specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003217 pw.println("");
3218 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
3219 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003220 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
3221 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003222 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003223 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [--apex] [-S BYTES]");
Dario Freniaac4ba42018-12-06 15:47:16 +00003224 pw.println(" [--multi-package] [--staged]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003225 pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
3226 pw.println(" to push data into the session, and \"install-commit\" to finish.");
3227 pw.println("");
3228 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
3229 pw.println(" Write an apk into the given install session. If the path is '-', data");
3230 pw.println(" will be read from stdin. Options are:");
3231 pw.println(" -S: size in bytes of package, required for stdin");
3232 pw.println("");
Patrick Baumann0aff9b12018-11-08 14:05:08 +00003233 pw.println(" install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs");
3234 pw.println(" Add one or more session IDs to a multi-package session.");
3235 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003236 pw.println(" install-commit SESSION_ID");
3237 pw.println(" Commit the given active install session, installing the app.");
3238 pw.println("");
3239 pw.println(" install-abandon SESSION_ID");
3240 pw.println(" Delete the given active install session.");
3241 pw.println("");
3242 pw.println(" set-install-location LOCATION");
3243 pw.println(" Changes the default install location. NOTE this is only intended for debugging;");
3244 pw.println(" using this can cause applications to break and other undersireable behavior.");
3245 pw.println(" LOCATION is one of:");
3246 pw.println(" 0 [auto]: Let system decide the best location");
3247 pw.println(" 1 [internal]: Install on internal device storage");
3248 pw.println(" 2 [external]: Install on external media");
3249 pw.println("");
3250 pw.println(" get-install-location");
3251 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location.");
3252 pw.println("");
3253 pw.println(" move-package PACKAGE [internal|UUID]");
3254 pw.println("");
3255 pw.println(" move-primary-storage [internal|UUID]");
3256 pw.println("");
3257 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
3258 pw.println(" Remove the given package name from the system. May remove an entire app");
3259 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
3260 pw.println(" given app. Options are:");
3261 pw.println(" -k: keep the data and cache directories around after package removal.");
3262 pw.println(" --user: remove the app from the given user.");
3263 pw.println(" --versionCode: only uninstall if the app has the given version code.");
3264 pw.println("");
3265 pw.println(" clear [--user USER_ID] PACKAGE");
3266 pw.println(" Deletes all data associated with a package.");
3267 pw.println("");
3268 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT");
3269 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT");
3270 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
3271 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
3272 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
3273 pw.println(" These commands change the enabled state of a given package or");
3274 pw.println(" component (written as \"package/class\").");
3275 pw.println("");
3276 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT");
3277 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
3278 pw.println("");
3279 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
3280 pw.println(" Suspends the specified package (as user).");
3281 pw.println("");
3282 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
3283 pw.println(" Unsuspends the specified package (as user).");
3284 pw.println("");
3285 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
3286 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
3287 pw.println(" These commands either grant or revoke permissions to apps. The permissions");
3288 pw.println(" must be declared as used in the app's manifest, be runtime permissions");
3289 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
3290 pw.println("");
3291 pw.println(" reset-permissions");
3292 pw.println(" Revert all runtime permissions to their default state.");
3293 pw.println("");
3294 pw.println(" set-permission-enforced PERMISSION [true|false]");
3295 pw.println("");
3296 pw.println(" get-privapp-permissions TARGET-PACKAGE");
3297 pw.println(" Prints all privileged permissions for a package.");
3298 pw.println("");
3299 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE");
3300 pw.println(" Prints all privileged permissions that are denied for a package.");
3301 pw.println("");
3302 pw.println(" get-oem-permissions TARGET-PACKAGE");
3303 pw.println(" Prints all OEM permissions for a package.");
3304 pw.println("");
3305 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
3306 pw.println(" get-app-link [--user USER_ID] PACKAGE");
3307 pw.println("");
3308 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
3309 pw.println(" Trim cache files to reach the given free space.");
3310 pw.println("");
3311 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
3312 pw.println(" [--guest] USER_NAME");
3313 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
3314 pw.println(" of the user.");
3315 pw.println("");
3316 pw.println(" remove-user USER_ID");
3317 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data");
3318 pw.println(" associated with that user");
3319 pw.println("");
3320 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE");
3321 pw.println("");
3322 pw.println(" get-max-users");
3323 pw.println("");
Alex Chauc12189b2018-01-16 15:01:15 +00003324 pw.println(" get-max-running-users");
3325 pw.println("");
Calin Juravleb6f844d2017-07-17 15:23:21 -07003326 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
Richard Uhler568a9692016-05-03 16:02:52 -07003327 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003328 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
David Brazdil990fb6b2016-03-01 10:02:27 +00003329 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00003330 pw.println(" -c: clear profile data before compiling");
3331 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00003332 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07003333 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01003334 pw.println(" assume-verified");
3335 pw.println(" extract");
3336 pw.println(" verify");
3337 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07003338 pw.println(" space-profile");
3339 pw.println(" space");
3340 pw.println(" speed-profile");
3341 pw.println(" speed");
3342 pw.println(" everything");
3343 pw.println(" -r: select compilation reason");
3344 pw.println(" REASON is one of:");
3345 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
3346 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
3347 }
David Brazdilcf046952016-03-08 16:40:20 +00003348 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07003349 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08003350 pw.println(" --secondary-dex: compile app secondary dex files");
Calin Juravleb6f844d2017-07-17 15:23:21 -07003351 pw.println(" --split SPLIT: compile only the given split name");
Eric Holka1485f62019-01-07 13:58:25 -08003352 pw.println(" --compile-layouts: compile layout resources for faster inflation");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003353 pw.println("");
3354 pw.println(" force-dex-opt PACKAGE");
3355 pw.println(" Force immediate execution of dex opt for the given PACKAGE.");
3356 pw.println("");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08003357 pw.println(" bg-dexopt-job");
3358 pw.println(" Execute the background optimizations immediately.");
3359 pw.println(" Note that the command only runs the background optimizer logic. It may");
3360 pw.println(" overlap with the actual job but the job scheduler will not be able to");
3361 pw.println(" cancel it. It will also run even if the device is not in the idle");
3362 pw.println(" maintenance mode.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003363 pw.println("");
Calin Juravle1aa5f882017-01-25 01:05:50 -08003364 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
3365 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003366 pw.println("");
David Sehrcae13b02016-06-07 09:11:27 -07003367 pw.println(" dump-profiles TARGET-PACKAGE");
3368 pw.println(" Dumps method/class profile files to");
Calin Juravle21216c62018-05-04 17:35:29 -07003369 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt");
3370 pw.println("");
3371 pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]");
3372 pw.println(" Take a snapshot of the package profiles to");
3373 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
3374 + "TARGET-PACKAGE[-code-path].prof");
3375 pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003376 pw.println("");
Makoto Onuki4828a592016-03-15 18:06:57 -07003377 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003378 pw.println(" Set the default home activity (aka launcher).");
Bookatz2b5a6012019-04-16 19:41:28 -07003379 pw.println(" TARGET-COMPONENT can be a package name (com.package.my) or a full");
3380 pw.println(" component (com.package.my/component.name). However, only the package name");
3381 pw.println(" matters: the actual component used will be determined automatically from");
3382 pw.println(" the package.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003383 pw.println("");
3384 pw.println(" set-installer PACKAGE INSTALLER");
3385 pw.println(" Set installer package name");
3386 pw.println("");
3387 pw.println(" get-instantapp-resolver");
3388 pw.println(" Return the name of the component that is the current instant app installer.");
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08003389 pw.println("");
3390 pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
3391 pw.println(" Mark the app as harmful with the given warning message.");
Ben Gruver9ef60092018-01-10 11:32:30 -08003392 pw.println("");
3393 pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
3394 pw.println(" Return the harmful app warning message for the given app, if present");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003395 pw.println();
Patrick Baumanna980e142018-02-12 11:45:23 -08003396 pw.println(" uninstall-system-updates");
3397 pw.println(" Remove updates to all system applications and fall back to their /system " +
3398 "version.");
Mohammad Samiul Islam40110562019-09-02 14:37:33 +01003399 pw.println("");
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +01003400 pw.println(" get-moduleinfo [--all | --installed] [module-name]");
3401 pw.println(" Displays module info. If module-name is specified only that info is shown");
3402 pw.println(" By default, without any argument only installed modules are shown.");
3403 pw.println(" --all: show all module info");
3404 pw.println(" --installed: show only installed modules");
3405 pw.println("");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003406 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07003407 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003408
3409 private static class LocalIntentReceiver {
wangmingming155414292018-04-10 09:35:25 +08003410 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003411
3412 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
3413 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07003414 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003415 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
3416 try {
3417 mResult.offer(intent, 5, TimeUnit.SECONDS);
3418 } catch (InterruptedException e) {
3419 throw new RuntimeException(e);
3420 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003421 }
3422 };
3423
3424 public IntentSender getIntentSender() {
3425 return new IntentSender((IIntentSender) mLocalSender);
3426 }
3427
3428 public Intent getResult() {
3429 try {
3430 return mResult.take();
3431 } catch (InterruptedException e) {
3432 throw new RuntimeException(e);
3433 }
3434 }
3435 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07003436}