blob: 3a6784585092f1389ce1224f8af5634f0cb6fb89 [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;
Dario Freni2bef1762018-06-01 14:02:08 +010096
Shunta Sato4f26cb52016-06-28 09:29:19 +090097import com.android.internal.content.PackageHelper;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070098import com.android.internal.util.ArrayUtils;
Alex Chauc12189b2018-01-16 15:01:15 +000099import com.android.server.LocalServices;
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800100import com.android.server.SystemConfig;
Dario Freni2bef1762018-06-01 14:02:08 +0100101
Andreas Gampebdd30d82016-03-20 11:32:11 -0700102import dalvik.system.DexFile;
Dario Freni2bef1762018-06-01 14:02:08 +0100103
104import libcore.io.IoUtils;
105import libcore.io.Streams;
106
Calin Juravle21216c62018-05-04 17:35:29 -0700107import java.io.File;
108import java.io.FileOutputStream;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800109import java.io.IOException;
Calin Juravle21216c62018-05-04 17:35:29 -0700110import java.io.InputStream;
111import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700112import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800113import java.net.URISyntaxException;
Calin Juravle21216c62018-05-04 17:35:29 -0700114import java.util.ArrayList;
115import java.util.Collections;
116import java.util.Comparator;
117import java.util.LinkedList;
118import java.util.List;
119import java.util.Map;
120import java.util.Objects;
121import java.util.WeakHashMap;
Bookatz2b5a6012019-04-16 19:41:28 -0700122import java.util.concurrent.CompletableFuture;
Calin Juravle21216c62018-05-04 17:35:29 -0700123import java.util.concurrent.CountDownLatch;
wangmingming155414292018-04-10 09:35:25 +0800124import java.util.concurrent.LinkedBlockingQueue;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800125import java.util.concurrent.TimeUnit;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700126
127class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700128 /** Path for streaming APK content */
129 private static final String STDIN_PATH = "-";
Calin Juravle21216c62018-05-04 17:35:29 -0700130 /** Path where ART profiles snapshots are dumped for the shell user */
131 private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700132
Todd Kennedy60459ab2015-10-30 11:32:16 -0700133 final IPackageManager mInterface;
134 final private WeakHashMap<String, Resources> mResourceCache =
135 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800136 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700137 boolean mBrief;
138 boolean mComponents;
Ng Zhi An73971312018-09-11 21:39:14 -0700139 int mQueryFlags;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700140
141 PackageManagerShellCommand(PackageManagerService service) {
142 mInterface = service;
143 }
144
145 @Override
146 public int onCommand(String cmd) {
147 if (cmd == null) {
148 return handleDefaultCommands(cmd);
149 }
150
151 final PrintWriter pw = getOutPrintWriter();
152 try {
153 switch(cmd) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700154 case "path":
155 return runPath();
156 case "dump":
157 return runDump();
158 case "list":
159 return runList();
160 case "resolve-activity":
161 return runResolveActivity();
162 case "query-activities":
163 return runQueryIntentActivities();
164 case "query-services":
165 return runQueryIntentServices();
166 case "query-receivers":
167 return runQueryIntentReceivers();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800168 case "install":
169 return runInstall();
170 case "install-abandon":
171 case "install-destroy":
172 return runInstallAbandon();
173 case "install-commit":
174 return runInstallCommit();
175 case "install-create":
176 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800177 case "install-remove":
178 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800179 case "install-write":
180 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800181 case "install-existing":
182 return runInstallExisting();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700183 case "set-install-location":
184 return runSetInstallLocation();
185 case "get-install-location":
186 return runGetInstallLocation();
Patrick Baumann0aff9b12018-11-08 14:05:08 +0000187 case "install-add-session":
188 return runInstallAddSession();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700189 case "move-package":
190 return runMovePackage();
191 case "move-primary-storage":
192 return runMovePrimaryStorage();
David Brazdil493411a2016-02-01 13:48:46 +0000193 case "compile":
194 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800195 case "reconcile-secondary-dex-files":
196 return runreconcileSecondaryDexFiles();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700197 case "force-dex-opt":
198 return runForceDexOpt();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800199 case "bg-dexopt-job":
200 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700201 case "dump-profiles":
202 return runDumpProfiles();
Calin Juravle21216c62018-05-04 17:35:29 -0700203 case "snapshot-profile":
204 return runSnapshotProfile();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800205 case "uninstall":
206 return runUninstall();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700207 case "clear":
208 return runClear();
209 case "enable":
210 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
211 case "disable":
212 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
213 case "disable-user":
214 return runSetEnabledSetting(
215 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
216 case "disable-until-used":
217 return runSetEnabledSetting(
218 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
219 case "default-state":
220 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
221 case "hide":
222 return runSetHiddenSetting(true);
223 case "unhide":
224 return runSetHiddenSetting(false);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000225 case "suspend":
226 return runSuspend(true);
227 case "unsuspend":
228 return runSuspend(false);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700229 case "grant":
230 return runGrantRevokePermission(true);
231 case "revoke":
232 return runGrantRevokePermission(false);
233 case "reset-permissions":
234 return runResetPermissions();
235 case "set-permission-enforced":
236 return runSetPermissionEnforced();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800237 case "get-privapp-permissions":
238 return runGetPrivappPermissions();
Todd Kennedy74629e32017-08-15 14:48:07 -0700239 case "get-privapp-deny-permissions":
240 return runGetPrivappDenyPermissions();
Svet Ganov087dce22017-09-07 15:42:16 -0700241 case "get-oem-permissions":
242 return runGetOemPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700243 case "set-app-link":
244 return runSetAppLink();
245 case "get-app-link":
246 return runGetAppLink();
247 case "trim-caches":
248 return runTrimCaches();
249 case "create-user":
250 return runCreateUser();
251 case "remove-user":
252 return runRemoveUser();
253 case "set-user-restriction":
254 return runSetUserRestriction();
255 case "get-max-users":
256 return runGetMaxUsers();
Alex Chauc12189b2018-01-16 15:01:15 +0000257 case "get-max-running-users":
258 return runGetMaxRunningUsers();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700259 case "set-home-activity":
260 return runSetHomeActivity();
261 case "set-installer":
262 return runSetInstaller();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700263 case "get-instantapp-resolver":
264 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900265 case "has-feature":
266 return runHasFeature();
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800267 case "set-harmful-app-warning":
268 return runSetHarmfulAppWarning();
Ben Gruver9ef60092018-01-10 11:32:30 -0800269 case "get-harmful-app-warning":
270 return runGetHarmfulAppWarning();
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000271 case "get-stagedsessions":
272 return getStagedSessions();
Patrick Baumanna980e142018-02-12 11:45:23 -0800273 case "uninstall-system-updates":
274 return uninstallSystemUpdates();
Narayan Kamathc5d752e2019-01-23 14:06:35 +0000275 case "rollback-app":
276 return runRollbackApp();
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +0100277 case "get-moduleinfo":
278 return runGetModuleInfo();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700279 default: {
280 String nextArg = getNextArg();
281 if (nextArg == null) {
282 if (cmd.equalsIgnoreCase("-l")) {
283 return runListPackages(false);
284 } else if (cmd.equalsIgnoreCase("-lf")) {
285 return runListPackages(true);
286 }
287 } else if (getNextArg() == null) {
288 if (cmd.equalsIgnoreCase("-p")) {
289 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
290 }
291 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700292 return handleDefaultCommands(cmd);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700293 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700294 }
295 } catch (RemoteException e) {
296 pw.println("Remote exception: " + e);
297 }
298 return -1;
299 }
300
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +0100301 /**
302 * Shows module info
303 *
304 * Usage: get-moduleinfo [--all | --installed] [module-name]
305 * Example: get-moduleinfo, get-moduleinfo --all, get-moduleinfo xyz
306 */
307 private int runGetModuleInfo() {
308 final PrintWriter pw = getOutPrintWriter();
309 int flags = 0;
310
311 String opt;
312 while ((opt = getNextOption()) != null) {
313 switch (opt) {
314 case "--all":
315 flags |= PackageManager.MATCH_ALL;
316 break;
317 case "--installed":
318 break;
319 default:
320 pw.println("Error: Unknown option: " + opt);
321 return -1;
322 }
323 }
324
325 String moduleName = getNextArg();
326 try {
327 if (moduleName != null) {
328 ModuleInfo m = mInterface.getModuleInfo(moduleName, flags);
329 pw.println(m.toString() + " packageName: " + m.getPackageName());
330
331 } else {
332 List<ModuleInfo> modules = mInterface.getInstalledModules(flags);
333 for (ModuleInfo m: modules) {
334 pw.println(m.toString() + " packageName: " + m.getPackageName());
335 }
336 }
337 } catch (RemoteException e) {
338 pw.println("Failure [" + e.getClass().getName() + " - " + e.getMessage() + "]");
339 return -1;
340 }
341 return 1;
342 }
343
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000344 private int getStagedSessions() {
345 final PrintWriter pw = getOutPrintWriter();
346 try {
347 List<SessionInfo> stagedSessionsList =
348 mInterface.getPackageInstaller().getStagedSessions().getList();
349 for (SessionInfo session: stagedSessionsList) {
350 pw.println("appPackageName = " + session.getAppPackageName()
351 + "; sessionId = " + session.getSessionId()
352 + "; isStaged = " + session.isStaged()
Dario Freni60a96c12019-02-24 21:01:29 +0000353 + "; isStagedSessionReady = " + session.isStagedSessionReady()
354 + "; isStagedSessionApplied = " + session.isStagedSessionApplied()
355 + "; isStagedSessionFailed = " + session.isStagedSessionFailed() + ";");
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000356 }
357 } catch (RemoteException e) {
358 pw.println("Failure ["
359 + e.getClass().getName() + " - "
360 + e.getMessage() + "]");
361 return 0;
362 }
363 return 1;
364 }
365
Patrick Baumanna980e142018-02-12 11:45:23 -0800366 private int uninstallSystemUpdates() {
367 final PrintWriter pw = getOutPrintWriter();
368 List<String> failedUninstalls = new LinkedList<>();
369 try {
370 final ParceledListSlice<ApplicationInfo> packages =
371 mInterface.getInstalledApplications(
372 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
373 final IPackageInstaller installer = mInterface.getPackageInstaller();
374 List<ApplicationInfo> list = packages.getList();
375 for (ApplicationInfo info : list) {
376 if (info.isUpdatedSystemApp()) {
377 pw.println("Uninstalling updates to " + info.packageName + "...");
378 final LocalIntentReceiver receiver = new LocalIntentReceiver();
379 installer.uninstall(new VersionedPackage(info.packageName,
380 info.versionCode), null /*callerPackageName*/, 0 /* flags */,
381 receiver.getIntentSender(), 0);
382
383 final Intent result = receiver.getResult();
384 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
385 PackageInstaller.STATUS_FAILURE);
386 if (status != PackageInstaller.STATUS_SUCCESS) {
387 failedUninstalls.add(info.packageName);
388 }
389 }
390 }
391 } catch (RemoteException e) {
392 pw.println("Failure ["
393 + e.getClass().getName() + " - "
394 + e.getMessage() + "]");
395 return 0;
396 }
397 if (!failedUninstalls.isEmpty()) {
398 pw.println("Failure [Couldn't uninstall packages: "
399 + TextUtils.join(", ", failedUninstalls)
400 + "]");
401 return 0;
402 }
403 pw.println("Success");
404 return 1;
405 }
406
Narayan Kamathc5d752e2019-01-23 14:06:35 +0000407 private int runRollbackApp() {
408 final PrintWriter pw = getOutPrintWriter();
409
410 final String packageName = getNextArgRequired();
411 if (packageName == null) {
412 pw.println("Error: package name not specified");
413 return 1;
414 }
415
416 final LocalIntentReceiver receiver = new LocalIntentReceiver();
417 try {
418 IRollbackManager rm = IRollbackManager.Stub.asInterface(
419 ServiceManager.getService(Context.ROLLBACK_SERVICE));
420
421 RollbackInfo rollback = null;
422 for (RollbackInfo r : (List<RollbackInfo>) rm.getAvailableRollbacks().getList()) {
423 for (PackageRollbackInfo info : r.getPackages()) {
424 if (packageName.equals(info.getPackageName())) {
425 rollback = r;
426 break;
427 }
428 }
429 }
430
431 if (rollback == null) {
432 pw.println("No available rollbacks for: " + packageName);
433 return 1;
434 }
435
436 rm.commitRollback(rollback.getRollbackId(),
437 ParceledListSlice.<VersionedPackage>emptyList(),
438 "com.android.shell", receiver.getIntentSender());
439 } catch (RemoteException re) {
440 // Cannot happen.
441 }
442
443 final Intent result = receiver.getResult();
444 final int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
445 RollbackManager.STATUS_FAILURE);
446 if (status == RollbackManager.STATUS_SUCCESS) {
447 pw.println("Success");
448 return 0;
449 } else {
450 pw.println("Failure ["
451 + result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE) + "]");
452 return 1;
453 }
454 }
455
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700456 private void setParamsSize(InstallParams params, String inPath) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700457 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700458 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
459 if (fd == null) {
460 getErrPrintWriter().println("Error: Can't open file: " + inPath);
461 throw new IllegalArgumentException("Error: Can't open file: " + inPath);
462 }
463 try {
464 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
465 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
466 null, null);
467 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
Dianne Hackborn1704e3c2017-10-31 19:55:42 +0000468 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700469 } catch (PackageParserException | IOException e) {
470 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
471 throw new IllegalArgumentException(
472 "Error: Failed to parse APK file: " + inPath, e);
473 } finally {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900474 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700475 fd.close();
476 } catch (IOException e) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900477 }
478 }
479 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700480 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700481 /**
482 * Displays the package file for a package.
483 * @param pckg
484 */
485 private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
486 PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId);
487 if (info != null && info.applicationInfo != null) {
488 final PrintWriter pw = getOutPrintWriter();
489 pw.print("package:");
490 pw.println(info.applicationInfo.sourceDir);
491 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
492 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
493 pw.print("package:");
494 pw.println(splitSourceDir);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800495 }
496 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700497 return 0;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800498 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700499 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800500 }
501
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700502 private int runPath() throws RemoteException {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000503 int userId = UserHandle.USER_SYSTEM;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700504 String option = getNextOption();
505 if (option != null && option.equals("--user")) {
506 userId = UserHandle.parseUserArg(getNextArgRequired());
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000507 }
508
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700509 String pkg = getNextArgRequired();
510 if (pkg == null) {
511 getErrPrintWriter().println("Error: no package specified");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000512 return 1;
513 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700514 return displayPackageFilePath(pkg, userId);
David Sehra8777082016-05-24 15:25:23 -0700515 }
516
Todd Kennedy60459ab2015-10-30 11:32:16 -0700517 private int runList() throws RemoteException {
518 final PrintWriter pw = getOutPrintWriter();
519 final String type = getNextArg();
520 if (type == null) {
521 pw.println("Error: didn't specify type of data to list");
522 return -1;
523 }
524 switch(type) {
525 case "features":
526 return runListFeatures();
527 case "instrumentation":
528 return runListInstrumentation();
529 case "libraries":
530 return runListLibraries();
531 case "package":
532 case "packages":
533 return runListPackages(false /*showSourceDir*/);
534 case "permission-groups":
535 return runListPermissionGroups();
536 case "permissions":
537 return runListPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700538 case "users":
539 ServiceManager.getService("user").shellCommand(
540 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
541 new String[] { "list" }, getShellCallback(), adoptResultReceiver());
542 return 0;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700543 }
544 pw.println("Error: unknown list type '" + type + "'");
545 return -1;
546 }
547
548 private int runListFeatures() throws RemoteException {
549 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700550 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700551
552 // sort by name
553 Collections.sort(list, new Comparator<FeatureInfo>() {
554 public int compare(FeatureInfo o1, FeatureInfo o2) {
555 if (o1.name == o2.name) return 0;
556 if (o1.name == null) return -1;
557 if (o2.name == null) return 1;
558 return o1.name.compareTo(o2.name);
559 }
560 });
561
562 final int count = (list != null) ? list.size() : 0;
563 for (int p = 0; p < count; p++) {
564 FeatureInfo fi = list.get(p);
565 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700566 if (fi.name != null) {
567 pw.print(fi.name);
568 if (fi.version > 0) {
569 pw.print("=");
570 pw.print(fi.version);
571 }
572 pw.println();
573 } else {
574 pw.println("reqGlEsVersion=0x"
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700575 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700576 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700577 }
578 return 0;
579 }
580
581 private int runListInstrumentation() throws RemoteException {
582 final PrintWriter pw = getOutPrintWriter();
583 boolean showSourceDir = false;
584 String targetPackage = null;
585
586 try {
587 String opt;
588 while ((opt = getNextArg()) != null) {
589 switch (opt) {
590 case "-f":
591 showSourceDir = true;
592 break;
593 default:
594 if (opt.charAt(0) != '-') {
595 targetPackage = opt;
596 } else {
597 pw.println("Error: Unknown option: " + opt);
598 return -1;
599 }
600 break;
601 }
602 }
603 } catch (RuntimeException ex) {
604 pw.println("Error: " + ex.toString());
605 return -1;
606 }
607
608 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700609 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700610
611 // sort by target package
612 Collections.sort(list, new Comparator<InstrumentationInfo>() {
613 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
614 return o1.targetPackage.compareTo(o2.targetPackage);
615 }
616 });
617
618 final int count = (list != null) ? list.size() : 0;
619 for (int p = 0; p < count; p++) {
620 final InstrumentationInfo ii = list.get(p);
621 pw.print("instrumentation:");
622 if (showSourceDir) {
623 pw.print(ii.sourceDir);
624 pw.print("=");
625 }
626 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
627 pw.print(cn.flattenToShortString());
628 pw.print(" (target=");
629 pw.print(ii.targetPackage);
630 pw.println(")");
631 }
632 return 0;
633 }
634
635 private int runListLibraries() throws RemoteException {
636 final PrintWriter pw = getOutPrintWriter();
637 final List<String> list = new ArrayList<String>();
638 final String[] rawList = mInterface.getSystemSharedLibraryNames();
639 for (int i = 0; i < rawList.length; i++) {
640 list.add(rawList[i]);
641 }
642
643 // sort by name
644 Collections.sort(list, new Comparator<String>() {
645 public int compare(String o1, String o2) {
646 if (o1 == o2) return 0;
647 if (o1 == null) return -1;
648 if (o2 == null) return 1;
649 return o1.compareTo(o2);
650 }
651 });
652
653 final int count = (list != null) ? list.size() : 0;
654 for (int p = 0; p < count; p++) {
655 String lib = list.get(p);
656 pw.print("library:");
657 pw.println(lib);
658 }
659 return 0;
660 }
661
662 private int runListPackages(boolean showSourceDir) throws RemoteException {
663 final PrintWriter pw = getOutPrintWriter();
664 int getFlags = 0;
665 boolean listDisabled = false, listEnabled = false;
666 boolean listSystem = false, listThirdParty = false;
667 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700668 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800669 boolean showVersionCode = false;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900670 boolean listApexOnly = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700671 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700672 int userId = UserHandle.USER_SYSTEM;
673 try {
674 String opt;
675 while ((opt = getNextOption()) != null) {
676 switch (opt) {
677 case "-d":
678 listDisabled = true;
679 break;
680 case "-e":
681 listEnabled = true;
682 break;
Andreas Gampe1f110452018-06-04 11:47:48 -0700683 case "-a":
684 getFlags |= PackageManager.MATCH_KNOWN_PACKAGES;
685 getFlags |= PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
686 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700687 case "-f":
688 showSourceDir = true;
689 break;
690 case "-i":
691 listInstaller = true;
692 break;
693 case "-l":
694 // old compat
695 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700696 case "-s":
697 listSystem = true;
698 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700699 case "-U":
700 showUid = true;
701 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700702 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700703 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700704 break;
705 case "-3":
706 listThirdParty = true;
707 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800708 case "--show-versioncode":
709 showVersionCode = true;
710 break;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900711 case "--apex-only":
712 getFlags |= PackageManager.MATCH_APEX;
713 listApexOnly = true;
714 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700715 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800716 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700717 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700718 case "--uid":
719 showUid = true;
720 uid = Integer.parseInt(getNextArgRequired());
721 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700722 default:
723 pw.println("Error: Unknown option: " + opt);
724 return -1;
725 }
726 }
727 } catch (RuntimeException ex) {
728 pw.println("Error: " + ex.toString());
729 return -1;
730 }
731
732 final String filter = getNextArg();
733
734 @SuppressWarnings("unchecked")
735 final ParceledListSlice<PackageInfo> slice =
736 mInterface.getInstalledPackages(getFlags, userId);
737 final List<PackageInfo> packages = slice.getList();
738
739 final int count = packages.size();
740 for (int p = 0; p < count; p++) {
741 final PackageInfo info = packages.get(p);
742 if (filter != null && !info.packageName.contains(filter)) {
743 continue;
744 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900745 final boolean isApex = info.isApex;
746 if (uid != -1 && !isApex && info.applicationInfo.uid != uid) {
Felipe Lemeeece9862016-06-29 11:45:03 -0700747 continue;
748 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900749
750 final boolean isSystem = !isApex &&
Todd Kennedy60459ab2015-10-30 11:32:16 -0700751 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900752 final boolean isEnabled = !isApex && info.applicationInfo.enabled;
753 if ((!listDisabled || !isEnabled) &&
754 (!listEnabled || isEnabled) &&
Todd Kennedy60459ab2015-10-30 11:32:16 -0700755 (!listSystem || isSystem) &&
Jiyong Park4f49abe2018-12-11 13:37:17 +0900756 (!listThirdParty || !isSystem) &&
757 (!listApexOnly || isApex)) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700758 pw.print("package:");
Jiyong Park4f49abe2018-12-11 13:37:17 +0900759 if (showSourceDir && !isApex) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700760 pw.print(info.applicationInfo.sourceDir);
761 pw.print("=");
762 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800763 pw.print(info.packageName);
Jiyong Parkf50a2932018-12-17 13:54:40 +0900764 if (showVersionCode) {
Todd Kennedybadc69a2017-01-24 11:05:47 -0800765 pw.print(" versionCode:");
Jiyong Parkf50a2932018-12-17 13:54:40 +0900766 if (info.applicationInfo != null) {
Dario Freni788ecb12019-01-23 18:49:32 +0000767 pw.print(info.applicationInfo.longVersionCode);
Jiyong Parkf50a2932018-12-17 13:54:40 +0900768 } else {
Dario Freni788ecb12019-01-23 18:49:32 +0000769 pw.print(info.getLongVersionCode());
Jiyong Parkf50a2932018-12-17 13:54:40 +0900770 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800771 }
Mohammad Samiul Islam6b7ad942019-05-07 20:28:00 +0100772 if (listInstaller) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700773 pw.print(" installer=");
774 pw.print(mInterface.getInstallerPackageName(info.packageName));
775 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900776 if (showUid && !isApex) {
Felipe Lemeeece9862016-06-29 11:45:03 -0700777 pw.print(" uid:");
778 pw.print(info.applicationInfo.uid);
779 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700780 pw.println();
781 }
782 }
783 return 0;
784 }
785
786 private int runListPermissionGroups() throws RemoteException {
787 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700788 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700789
790 final int count = pgs.size();
791 for (int p = 0; p < count ; p++) {
792 final PermissionGroupInfo pgi = pgs.get(p);
793 pw.print("permission group:");
794 pw.println(pgi.name);
795 }
796 return 0;
797 }
798
799 private int runListPermissions() throws RemoteException {
800 final PrintWriter pw = getOutPrintWriter();
801 boolean labels = false;
802 boolean groups = false;
803 boolean userOnly = false;
804 boolean summary = false;
805 boolean dangerousOnly = false;
806 String opt;
807 while ((opt = getNextOption()) != null) {
808 switch (opt) {
809 case "-d":
810 dangerousOnly = true;
811 break;
812 case "-f":
813 labels = true;
814 break;
815 case "-g":
816 groups = true;
817 break;
818 case "-s":
819 groups = true;
820 labels = true;
821 summary = true;
822 break;
823 case "-u":
824 userOnly = true;
825 break;
826 default:
827 pw.println("Error: Unknown option: " + opt);
828 return 1;
829 }
830 }
831
832 final ArrayList<String> groupList = new ArrayList<String>();
833 if (groups) {
834 final List<PermissionGroupInfo> infos =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700835 mInterface.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700836 final int count = infos.size();
837 for (int i = 0; i < count; i++) {
838 groupList.add(infos.get(i).name);
839 }
840 groupList.add(null);
841 } else {
842 final String grp = getNextArg();
843 groupList.add(grp);
844 }
845
846 if (dangerousOnly) {
847 pw.println("Dangerous Permissions:");
848 pw.println("");
849 doListPermissions(groupList, groups, labels, summary,
850 PermissionInfo.PROTECTION_DANGEROUS,
851 PermissionInfo.PROTECTION_DANGEROUS);
852 if (userOnly) {
853 pw.println("Normal Permissions:");
854 pw.println("");
855 doListPermissions(groupList, groups, labels, summary,
856 PermissionInfo.PROTECTION_NORMAL,
857 PermissionInfo.PROTECTION_NORMAL);
858 }
859 } else if (userOnly) {
860 pw.println("Dangerous and Normal Permissions:");
861 pw.println("");
862 doListPermissions(groupList, groups, labels, summary,
863 PermissionInfo.PROTECTION_NORMAL,
864 PermissionInfo.PROTECTION_DANGEROUS);
865 } else {
866 pw.println("All Permissions:");
867 pw.println("");
868 doListPermissions(groupList, groups, labels, summary,
869 -10000, 10000);
870 }
871 return 0;
872 }
873
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800874 private Intent parseIntentAndUser() throws URISyntaxException {
875 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700876 mBrief = false;
877 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800878 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
879 @Override
880 public boolean handleOption(String opt, ShellCommand cmd) {
881 if ("--user".equals(opt)) {
882 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
883 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700884 } else if ("--brief".equals(opt)) {
885 mBrief = true;
886 return true;
887 } else if ("--components".equals(opt)) {
888 mComponents = true;
889 return true;
Ng Zhi An73971312018-09-11 21:39:14 -0700890 } else if ("--query-flags".equals(opt)) {
891 mQueryFlags = Integer.decode(cmd.getNextArgRequired());
892 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800893 }
894 return false;
895 }
896 });
897 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
898 Binder.getCallingUid(), mTargetUser, false, false, null, null);
899 return intent;
900 }
901
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700902 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
903 boolean brief, boolean components) {
904 if (brief || components) {
905 final ComponentName comp;
906 if (ri.activityInfo != null) {
907 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
908 } else if (ri.serviceInfo != null) {
909 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
910 } else if (ri.providerInfo != null) {
911 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
912 } else {
913 comp = null;
914 }
915 if (comp != null) {
916 if (!components) {
917 pr.println(prefix + "priority=" + ri.priority
918 + " preferredOrder=" + ri.preferredOrder
919 + " match=0x" + Integer.toHexString(ri.match)
920 + " specificIndex=" + ri.specificIndex
921 + " isDefault=" + ri.isDefault);
922 }
923 pr.println(prefix + comp.flattenToShortString());
924 return;
925 }
926 }
927 ri.dump(pr, prefix);
928 }
929
Dianne Hackborn99878e92015-12-02 16:27:41 -0800930 private int runResolveActivity() {
931 Intent intent;
932 try {
933 intent = parseIntentAndUser();
934 } catch (URISyntaxException e) {
935 throw new RuntimeException(e.getMessage(), e);
936 }
937 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700938 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), mQueryFlags,
939 mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800940 PrintWriter pw = getOutPrintWriter();
941 if (ri == null) {
942 pw.println("No activity found");
943 } else {
944 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700945 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800946 }
947 } catch (RemoteException e) {
948 throw new RuntimeException("Failed calling service", e);
949 }
950 return 0;
951 }
952
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800953 private int runQueryIntentActivities() {
954 Intent intent;
955 try {
956 intent = parseIntentAndUser();
957 } catch (URISyntaxException e) {
958 throw new RuntimeException(e.getMessage(), e);
959 }
960 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700961 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(),
962 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800963 PrintWriter pw = getOutPrintWriter();
964 if (result == null || result.size() <= 0) {
965 pw.println("No activities found");
966 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700967 if (!mComponents) {
968 pw.print(result.size()); pw.println(" activities found:");
969 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
970 for (int i = 0; i < result.size(); i++) {
971 pw.print(" Activity #"); pw.print(i); pw.println(":");
972 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
973 }
974 } else {
975 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
976 for (int i = 0; i < result.size(); i++) {
977 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
978 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800979 }
980 }
981 } catch (RemoteException e) {
982 throw new RuntimeException("Failed calling service", e);
983 }
984 return 0;
985 }
986
987 private int runQueryIntentServices() {
988 Intent intent;
989 try {
990 intent = parseIntentAndUser();
991 } catch (URISyntaxException e) {
992 throw new RuntimeException(e.getMessage(), e);
993 }
994 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700995 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(),
996 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800997 PrintWriter pw = getOutPrintWriter();
998 if (result == null || result.size() <= 0) {
999 pw.println("No services found");
1000 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001001 if (!mComponents) {
1002 pw.print(result.size()); pw.println(" services found:");
1003 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1004 for (int i = 0; i < result.size(); i++) {
1005 pw.print(" Service #"); pw.print(i); pw.println(":");
1006 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1007 }
1008 } else {
1009 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1010 for (int i = 0; i < result.size(); i++) {
1011 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1012 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001013 }
1014 }
1015 } catch (RemoteException e) {
1016 throw new RuntimeException("Failed calling service", e);
1017 }
1018 return 0;
1019 }
1020
1021 private int runQueryIntentReceivers() {
1022 Intent intent;
1023 try {
1024 intent = parseIntentAndUser();
1025 } catch (URISyntaxException e) {
1026 throw new RuntimeException(e.getMessage(), e);
1027 }
1028 try {
Ng Zhi An73971312018-09-11 21:39:14 -07001029 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(),
1030 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001031 PrintWriter pw = getOutPrintWriter();
1032 if (result == null || result.size() <= 0) {
1033 pw.println("No receivers found");
1034 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001035 if (!mComponents) {
1036 pw.print(result.size()); pw.println(" receivers found:");
1037 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1038 for (int i = 0; i < result.size(); i++) {
1039 pw.print(" Receiver #"); pw.print(i); pw.println(":");
1040 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1041 }
1042 } else {
1043 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1044 for (int i = 0; i < result.size(); i++) {
1045 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1046 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001047 }
1048 }
1049 } catch (RemoteException e) {
1050 throw new RuntimeException("Failed calling service", e);
1051 }
1052 return 0;
1053 }
1054
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001055 private int runInstall() throws RemoteException {
1056 final PrintWriter pw = getOutPrintWriter();
1057 final InstallParams params = makeInstallParams();
1058 final String inPath = getNextArg();
1059
1060 setParamsSize(params, inPath);
1061 final int sessionId = doCreateSession(params.sessionParams,
1062 params.installerPackageName, params.userId);
1063 boolean abandonSession = true;
1064 try {
1065 if (inPath == null && params.sessionParams.sizeBytes == -1) {
1066 pw.println("Error: must either specify a package size or an APK file");
1067 return 1;
1068 }
Dario Frenid8bf22e2018-08-31 14:18:04 +01001069 final boolean isApex =
1070 (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
1071 String splitName = "base." + (isApex ? "apex" : "apk");
1072 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001073 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
1074 return 1;
1075 }
1076 if (doCommitSession(sessionId, false /*logSuccess*/)
1077 != PackageInstaller.STATUS_SUCCESS) {
1078 return 1;
1079 }
1080 abandonSession = false;
1081 pw.println("Success");
1082 return 0;
1083 } finally {
1084 if (abandonSession) {
1085 try {
1086 doAbandonSession(sessionId, false /*logSuccess*/);
1087 } catch (Exception ignore) {
1088 }
1089 }
1090 }
1091 }
1092
1093 private int runInstallAbandon() throws RemoteException {
1094 final int sessionId = Integer.parseInt(getNextArg());
1095 return doAbandonSession(sessionId, true /*logSuccess*/);
1096 }
1097
1098 private int runInstallCommit() throws RemoteException {
1099 final int sessionId = Integer.parseInt(getNextArg());
1100 return doCommitSession(sessionId, true /*logSuccess*/);
1101 }
1102
1103 private int runInstallCreate() throws RemoteException {
1104 final PrintWriter pw = getOutPrintWriter();
1105 final InstallParams installParams = makeInstallParams();
1106 final int sessionId = doCreateSession(installParams.sessionParams,
1107 installParams.installerPackageName, installParams.userId);
1108
1109 // NOTE: adb depends on parsing this string
1110 pw.println("Success: created install session [" + sessionId + "]");
1111 return 0;
1112 }
1113
1114 private int runInstallWrite() throws RemoteException {
1115 long sizeBytes = -1;
1116
1117 String opt;
1118 while ((opt = getNextOption()) != null) {
1119 if (opt.equals("-S")) {
1120 sizeBytes = Long.parseLong(getNextArg());
1121 } else {
1122 throw new IllegalArgumentException("Unknown option: " + opt);
1123 }
1124 }
1125
1126 final int sessionId = Integer.parseInt(getNextArg());
1127 final String splitName = getNextArg();
1128 final String path = getNextArg();
1129 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
1130 }
1131
Patrick Baumann0aff9b12018-11-08 14:05:08 +00001132 private int runInstallAddSession() throws RemoteException {
1133 final PrintWriter pw = getOutPrintWriter();
1134 final int parentSessionId = Integer.parseInt(getNextArg());
1135
1136 List<Integer> otherSessionIds = new ArrayList<>();
1137 String opt;
1138 while ((opt = getNextArg()) != null) {
1139 otherSessionIds.add(Integer.parseInt(opt));
1140 }
1141 if (otherSessionIds.size() == 0) {
1142 pw.println("Error: At least two sessions are required.");
1143 return 1;
1144 }
1145 return doInstallAddSession(parentSessionId, ArrayUtils.convertToIntArray(otherSessionIds),
1146 true /*logSuccess*/);
1147 }
1148
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001149 private int runInstallRemove() throws RemoteException {
1150 final PrintWriter pw = getOutPrintWriter();
1151
1152 final int sessionId = Integer.parseInt(getNextArg());
1153
1154 final String splitName = getNextArg();
1155 if (splitName == null) {
1156 pw.println("Error: split name not specified");
1157 return 1;
1158 }
1159 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
1160 }
1161
1162 private int runInstallExisting() throws RemoteException {
1163 final PrintWriter pw = getOutPrintWriter();
1164 int userId = UserHandle.USER_SYSTEM;
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07001165 int installFlags = PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001166 String opt;
Chandan Nathe8e463b2019-01-28 15:23:38 +00001167 boolean waitTillComplete = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001168 while ((opt = getNextOption()) != null) {
1169 switch (opt) {
1170 case "--user":
1171 userId = UserHandle.parseUserArg(getNextArgRequired());
1172 break;
1173 case "--ephemeral":
1174 case "--instant":
1175 installFlags |= PackageManager.INSTALL_INSTANT_APP;
1176 installFlags &= ~PackageManager.INSTALL_FULL_APP;
1177 break;
1178 case "--full":
1179 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1180 installFlags |= PackageManager.INSTALL_FULL_APP;
1181 break;
Chandan Nathe8e463b2019-01-28 15:23:38 +00001182 case "--wait":
1183 waitTillComplete = true;
1184 break;
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07001185 case "--restrict-permissions":
1186 installFlags &= ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
1187 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001188 default:
1189 pw.println("Error: Unknown option: " + opt);
1190 return 1;
1191 }
1192 }
1193
1194 final String packageName = getNextArg();
1195 if (packageName == null) {
1196 pw.println("Error: package name not specified");
1197 return 1;
1198 }
1199
Chandan Nathe8e463b2019-01-28 15:23:38 +00001200 int installReason = PackageManager.INSTALL_REASON_UNKNOWN;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001201 try {
Chandan Nathe8e463b2019-01-28 15:23:38 +00001202 if (waitTillComplete) {
1203 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1204 final IPackageInstaller installer = mInterface.getPackageInstaller();
1205 pw.println("Installing package " + packageName + " for user: " + userId);
1206 installer.installExistingPackage(packageName, installFlags, installReason,
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07001207 receiver.getIntentSender(), userId, null);
Chandan Nathe8e463b2019-01-28 15:23:38 +00001208 final Intent result = receiver.getResult();
1209 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1210 PackageInstaller.STATUS_FAILURE);
1211 pw.println("Received intent for package install");
1212 return status == PackageInstaller.STATUS_SUCCESS ? 0 : 1;
1213 }
1214
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001215 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07001216 installFlags, installReason, null);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001217 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
1218 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1219 }
1220 pw.println("Package " + packageName + " installed for user: " + userId);
1221 return 0;
1222 } catch (RemoteException | NameNotFoundException e) {
1223 pw.println(e.toString());
1224 return 1;
1225 }
1226 }
1227
1228 private int runSetInstallLocation() throws RemoteException {
1229 int loc;
1230
1231 String arg = getNextArg();
1232 if (arg == null) {
1233 getErrPrintWriter().println("Error: no install location specified.");
1234 return 1;
1235 }
1236 try {
1237 loc = Integer.parseInt(arg);
1238 } catch (NumberFormatException e) {
1239 getErrPrintWriter().println("Error: install location has to be a number.");
1240 return 1;
1241 }
1242 if (!mInterface.setInstallLocation(loc)) {
1243 getErrPrintWriter().println("Error: install location has to be a number.");
1244 return 1;
1245 }
1246 return 0;
1247 }
1248
1249 private int runGetInstallLocation() throws RemoteException {
1250 int loc = mInterface.getInstallLocation();
1251 String locStr = "invalid";
1252 if (loc == PackageHelper.APP_INSTALL_AUTO) {
1253 locStr = "auto";
1254 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
1255 locStr = "internal";
1256 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
1257 locStr = "external";
1258 }
1259 getOutPrintWriter().println(loc + "[" + locStr + "]");
1260 return 0;
1261 }
1262
1263 public int runMovePackage() throws RemoteException {
1264 final String packageName = getNextArg();
1265 if (packageName == null) {
1266 getErrPrintWriter().println("Error: package name not specified");
1267 return 1;
1268 }
1269 String volumeUuid = getNextArg();
1270 if ("internal".equals(volumeUuid)) {
1271 volumeUuid = null;
1272 }
1273
1274 final int moveId = mInterface.movePackage(packageName, volumeUuid);
1275
1276 int status = mInterface.getMoveStatus(moveId);
1277 while (!PackageManager.isMoveStatusFinished(status)) {
1278 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1279 status = mInterface.getMoveStatus(moveId);
1280 }
1281
1282 if (status == PackageManager.MOVE_SUCCEEDED) {
1283 getOutPrintWriter().println("Success");
1284 return 0;
1285 } else {
1286 getErrPrintWriter().println("Failure [" + status + "]");
1287 return 1;
1288 }
1289 }
1290
1291 public int runMovePrimaryStorage() throws RemoteException {
1292 String volumeUuid = getNextArg();
1293 if ("internal".equals(volumeUuid)) {
1294 volumeUuid = null;
1295 }
1296
1297 final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1298
1299 int status = mInterface.getMoveStatus(moveId);
1300 while (!PackageManager.isMoveStatusFinished(status)) {
1301 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1302 status = mInterface.getMoveStatus(moveId);
1303 }
1304
1305 if (status == PackageManager.MOVE_SUCCEEDED) {
1306 getOutPrintWriter().println("Success");
1307 return 0;
1308 } else {
1309 getErrPrintWriter().println("Failure [" + status + "]");
1310 return 1;
1311 }
1312 }
1313
1314 private int runCompile() throws RemoteException {
1315 final PrintWriter pw = getOutPrintWriter();
1316 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1317 boolean forceCompilation = false;
1318 boolean allPackages = false;
1319 boolean clearProfileData = false;
1320 String compilerFilter = null;
1321 String compilationReason = null;
1322 String checkProfilesRaw = null;
1323 boolean secondaryDex = false;
1324 String split = null;
Eric Holka1485f62019-01-07 13:58:25 -08001325 boolean compileLayouts = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001326
1327 String opt;
1328 while ((opt = getNextOption()) != null) {
1329 switch (opt) {
1330 case "-a":
1331 allPackages = true;
1332 break;
1333 case "-c":
1334 clearProfileData = true;
1335 break;
1336 case "-f":
1337 forceCompilation = true;
1338 break;
1339 case "-m":
1340 compilerFilter = getNextArgRequired();
1341 break;
1342 case "-r":
1343 compilationReason = getNextArgRequired();
1344 break;
Eric Holka1485f62019-01-07 13:58:25 -08001345 case "--compile-layouts":
1346 compileLayouts = true;
1347 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001348 case "--check-prof":
1349 checkProfilesRaw = getNextArgRequired();
1350 break;
1351 case "--reset":
1352 forceCompilation = true;
1353 clearProfileData = true;
1354 compilationReason = "install";
1355 break;
1356 case "--secondary-dex":
1357 secondaryDex = true;
1358 break;
1359 case "--split":
1360 split = getNextArgRequired();
1361 break;
1362 default:
1363 pw.println("Error: Unknown option: " + opt);
1364 return 1;
1365 }
1366 }
1367
1368 if (checkProfilesRaw != null) {
1369 if ("true".equals(checkProfilesRaw)) {
1370 checkProfiles = true;
1371 } else if ("false".equals(checkProfilesRaw)) {
1372 checkProfiles = false;
1373 } else {
1374 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1375 return 1;
1376 }
1377 }
1378
Eric Holka1485f62019-01-07 13:58:25 -08001379 final boolean compilerFilterGiven = compilerFilter != null;
1380 final boolean compilationReasonGiven = compilationReason != null;
1381 // Make sure exactly one of -m, -r, or --compile-layouts is given.
1382 if ((!compilerFilterGiven && !compilationReasonGiven && !compileLayouts)
1383 || (!compilerFilterGiven && compilationReasonGiven && compileLayouts)
1384 || (compilerFilterGiven && !compilationReasonGiven && compileLayouts)
1385 || (compilerFilterGiven && compilationReasonGiven && !compileLayouts)
1386 || (compilerFilterGiven && compilationReasonGiven && compileLayouts)) {
1387 pw.println("Must specify exactly one of compilation filter (\"-m\"), compilation " +
1388 "reason (\"-r\"), or compile layouts (\"--compile-layouts\")");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001389 return 1;
1390 }
1391
1392 if (allPackages && split != null) {
1393 pw.println("-a cannot be specified together with --split");
1394 return 1;
1395 }
1396
1397 if (secondaryDex && split != null) {
1398 pw.println("--secondary-dex cannot be specified together with --split");
1399 return 1;
1400 }
1401
Eric Holka1485f62019-01-07 13:58:25 -08001402 String targetCompilerFilter = null;
1403 if (compilerFilterGiven) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001404 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1405 pw.println("Error: \"" + compilerFilter +
1406 "\" is not a valid compilation filter.");
1407 return 1;
1408 }
1409 targetCompilerFilter = compilerFilter;
Eric Holka1485f62019-01-07 13:58:25 -08001410 }
1411 if (compilationReasonGiven) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001412 int reason = -1;
1413 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1414 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1415 compilationReason)) {
1416 reason = i;
1417 break;
1418 }
1419 }
1420 if (reason == -1) {
1421 pw.println("Error: Unknown compilation reason: " + compilationReason);
1422 return 1;
1423 }
1424 targetCompilerFilter =
1425 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1426 }
1427
1428
1429 List<String> packageNames = null;
1430 if (allPackages) {
1431 packageNames = mInterface.getAllPackages();
1432 } else {
1433 String packageName = getNextArg();
1434 if (packageName == null) {
1435 pw.println("Error: package name not specified");
1436 return 1;
1437 }
1438 packageNames = Collections.singletonList(packageName);
1439 }
1440
1441 List<String> failedPackages = new ArrayList<>();
Andreas Gampecbd08d42017-11-20 17:03:17 -08001442 int index = 0;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001443 for (String packageName : packageNames) {
1444 if (clearProfileData) {
1445 mInterface.clearApplicationProfileData(packageName);
1446 }
1447
Andreas Gampecbd08d42017-11-20 17:03:17 -08001448 if (allPackages) {
1449 pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1450 pw.flush();
1451 }
1452
Eric Holka1485f62019-01-07 13:58:25 -08001453 boolean result = true;
1454 if (compileLayouts) {
1455 PackageManagerInternal internal = LocalServices.getService(
1456 PackageManagerInternal.class);
1457 result = internal.compileLayouts(packageName);
1458 } else {
1459 result = secondaryDex
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001460 ? mInterface.performDexOptSecondary(packageName,
1461 targetCompilerFilter, forceCompilation)
1462 : mInterface.performDexOptMode(packageName,
1463 checkProfiles, targetCompilerFilter, forceCompilation,
1464 true /* bootComplete */, split);
Eric Holka1485f62019-01-07 13:58:25 -08001465 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001466 if (!result) {
1467 failedPackages.add(packageName);
1468 }
1469 }
1470
1471 if (failedPackages.isEmpty()) {
1472 pw.println("Success");
1473 return 0;
1474 } else if (failedPackages.size() == 1) {
1475 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1476 return 1;
1477 } else {
1478 pw.print("Failure: the following packages could not be compiled: ");
1479 boolean is_first = true;
1480 for (String packageName : failedPackages) {
1481 if (is_first) {
1482 is_first = false;
1483 } else {
1484 pw.print(", ");
1485 }
1486 pw.print(packageName);
1487 }
1488 pw.println();
1489 return 1;
1490 }
1491 }
1492
1493 private int runreconcileSecondaryDexFiles() throws RemoteException {
1494 String packageName = getNextArg();
1495 mInterface.reconcileSecondaryDexFiles(packageName);
1496 return 0;
1497 }
1498
1499 public int runForceDexOpt() throws RemoteException {
1500 mInterface.forceDexOpt(getNextArgRequired());
1501 return 0;
1502 }
1503
1504 private int runDexoptJob() throws RemoteException {
Arthur Eubanks09dd1ec2017-09-15 09:28:51 -07001505 String arg;
1506 List<String> packageNames = new ArrayList<>();
1507 while ((arg = getNextArg()) != null) {
1508 packageNames.add(arg);
1509 }
1510 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1511 packageNames);
Andreas Gampefa8b57d2018-08-31 15:47:01 -07001512 getOutPrintWriter().println(result ? "Success" : "Failure");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001513 return result ? 0 : -1;
1514 }
1515
1516 private int runDumpProfiles() throws RemoteException {
1517 String packageName = getNextArg();
1518 mInterface.dumpProfiles(packageName);
1519 return 0;
1520 }
1521
Calin Juravle21216c62018-05-04 17:35:29 -07001522 private int runSnapshotProfile() throws RemoteException {
1523 PrintWriter pw = getOutPrintWriter();
1524
1525 // Parse the arguments
1526 final String packageName = getNextArg();
1527 final boolean isBootImage = "android".equals(packageName);
1528
1529 String codePath = null;
1530 String opt;
1531 while ((opt = getNextArg()) != null) {
1532 switch (opt) {
1533 case "--code-path":
1534 if (isBootImage) {
1535 pw.write("--code-path cannot be used for the boot image.");
1536 return -1;
1537 }
1538 codePath = getNextArg();
1539 break;
1540 default:
1541 pw.write("Unknown arg: " + opt);
1542 return -1;
1543 }
1544 }
1545
1546 // If no code path was explicitly requested, select the base code path.
1547 String baseCodePath = null;
1548 if (!isBootImage) {
1549 PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
1550 /* userId */0);
1551 if (packageInfo == null) {
1552 pw.write("Package not found " + packageName);
1553 return -1;
1554 }
1555 baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
1556 if (codePath == null) {
1557 codePath = baseCodePath;
1558 }
1559 }
1560
1561 // Create the profile snapshot.
1562 final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
1563 // The calling package is needed to debug permission access.
1564 final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
1565 ? "root" : "com.android.shell";
1566 final int profileType = isBootImage
1567 ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
1568 if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
1569 pw.println("Error: Runtime profiling is not enabled");
1570 return -1;
1571 }
1572 mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
1573 codePath, callback, callingPackage);
1574 if (!callback.waitTillDone()) {
1575 pw.println("Error: callback not called");
1576 return callback.mErrCode;
1577 }
1578
1579 // Copy the snapshot profile to the output profile file.
1580 try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
1581 final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
1582 ? "" : ("-" + new File(codePath).getName());
1583 final String outputProfilePath =
1584 ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
1585 try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
1586 Streams.copy(inStream, outStream);
1587 }
Calin Juravlebdd94d92018-05-17 01:23:15 -07001588 // Give read permissions to the other group.
1589 Os.chmod(outputProfilePath, /*mode*/ 0644 );
1590 } catch (IOException | ErrnoException e) {
Calin Juravle21216c62018-05-04 17:35:29 -07001591 pw.println("Error when reading the profile fd: " + e.getMessage());
1592 e.printStackTrace(pw);
1593 return -1;
1594 }
1595 return 0;
1596 }
1597
1598 private static class SnapshotRuntimeProfileCallback
1599 extends ISnapshotRuntimeProfileCallback.Stub {
1600 private boolean mSuccess = false;
1601 private int mErrCode = -1;
1602 private ParcelFileDescriptor mProfileReadFd = null;
1603 private CountDownLatch mDoneSignal = new CountDownLatch(1);
1604
1605 @Override
1606 public void onSuccess(ParcelFileDescriptor profileReadFd) {
1607 mSuccess = true;
1608 try {
1609 // We need to dup the descriptor. We are in the same process as system server
1610 // and we will be receiving the same object (which will be closed on the
1611 // server side).
1612 mProfileReadFd = profileReadFd.dup();
1613 } catch (IOException e) {
1614 e.printStackTrace();
1615 }
1616 mDoneSignal.countDown();
1617 }
1618
1619 @Override
1620 public void onError(int errCode) {
1621 mSuccess = false;
1622 mErrCode = errCode;
1623 mDoneSignal.countDown();
1624 }
1625
1626 boolean waitTillDone() {
1627 boolean done = false;
1628 try {
1629 // The time-out is an arbitrary large value. Since this is a local call the result
1630 // will come very fast.
1631 done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS);
1632 } catch (InterruptedException ignored) {
1633 }
1634 return done && mSuccess;
1635 }
1636 }
1637
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001638 private int runUninstall() throws RemoteException {
1639 final PrintWriter pw = getOutPrintWriter();
1640 int flags = 0;
1641 int userId = UserHandle.USER_ALL;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001642 long versionCode = PackageManager.VERSION_CODE_HIGHEST;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001643
1644 String opt;
1645 while ((opt = getNextOption()) != null) {
1646 switch (opt) {
1647 case "-k":
1648 flags |= PackageManager.DELETE_KEEP_DATA;
1649 break;
1650 case "--user":
1651 userId = UserHandle.parseUserArg(getNextArgRequired());
1652 break;
1653 case "--versionCode":
Dianne Hackborn3accca02013-09-20 09:32:11 -07001654 versionCode = Long.parseLong(getNextArgRequired());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001655 break;
1656 default:
1657 pw.println("Error: Unknown option: " + opt);
1658 return 1;
1659 }
1660 }
1661
1662 final String packageName = getNextArg();
1663 if (packageName == null) {
1664 pw.println("Error: package name not specified");
1665 return 1;
1666 }
1667
1668 // if a split is specified, just remove it and not the whole package
1669 final String splitName = getNextArg();
1670 if (splitName != null) {
1671 return runRemoveSplit(packageName, splitName);
1672 }
1673
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08001674 userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001675 final LocalIntentReceiver receiver = new LocalIntentReceiver();
Nikita Ioffef012a222019-03-05 22:37:55 +00001676 PackageManagerInternal internal = LocalServices.getService(PackageManagerInternal.class);
1677
1678 if (internal.isApexPackage(packageName)) {
1679 internal.uninstallApex(packageName, versionCode, userId, receiver.getIntentSender());
1680 } else {
1681 if (userId == UserHandle.USER_ALL) {
1682 userId = UserHandle.USER_SYSTEM;
1683 flags |= PackageManager.DELETE_ALL_USERS;
1684 } else {
1685 final PackageInfo info = mInterface.getPackageInfo(packageName,
1686 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1687 if (info == null) {
1688 pw.println("Failure [not installed for " + userId + "]");
1689 return 1;
1690 }
1691 final boolean isSystem =
1692 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1693 // If we are being asked to delete a system app for just one
1694 // user set flag so it disables rather than reverting to system
1695 // version of the app.
1696 if (isSystem) {
1697 flags |= PackageManager.DELETE_SYSTEM_APP;
1698 }
1699 }
1700
1701 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1702 versionCode), null /*callerPackageName*/, flags,
1703 receiver.getIntentSender(), userId);
1704 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001705
1706 final Intent result = receiver.getResult();
1707 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1708 PackageInstaller.STATUS_FAILURE);
1709 if (status == PackageInstaller.STATUS_SUCCESS) {
1710 pw.println("Success");
1711 return 0;
1712 } else {
1713 pw.println("Failure ["
1714 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1715 return 1;
1716 }
1717 }
1718
1719 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1720 final PrintWriter pw = getOutPrintWriter();
1721 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1722 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1723 sessionParams.appPackageName = packageName;
1724 final int sessionId =
1725 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1726 boolean abandonSession = true;
1727 try {
1728 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1729 != PackageInstaller.STATUS_SUCCESS) {
1730 return 1;
1731 }
1732 if (doCommitSession(sessionId, false /*logSuccess*/)
1733 != PackageInstaller.STATUS_SUCCESS) {
1734 return 1;
1735 }
1736 abandonSession = false;
1737 pw.println("Success");
1738 return 0;
1739 } finally {
1740 if (abandonSession) {
1741 try {
1742 doAbandonSession(sessionId, false /*logSuccess*/);
1743 } catch (Exception ignore) {
1744 }
1745 }
1746 }
1747 }
1748
1749 static class ClearDataObserver extends IPackageDataObserver.Stub {
1750 boolean finished;
1751 boolean result;
1752
1753 @Override
1754 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1755 synchronized (this) {
1756 finished = true;
1757 result = succeeded;
1758 notifyAll();
1759 }
1760 }
1761 }
1762
1763 private int runClear() throws RemoteException {
1764 int userId = UserHandle.USER_SYSTEM;
1765 String option = getNextOption();
1766 if (option != null && option.equals("--user")) {
1767 userId = UserHandle.parseUserArg(getNextArgRequired());
1768 }
1769
1770 String pkg = getNextArg();
1771 if (pkg == null) {
1772 getErrPrintWriter().println("Error: no package specified");
1773 return 1;
1774 }
1775
1776 ClearDataObserver obs = new ClearDataObserver();
Christopher Tate1d99c392017-12-07 16:54:04 -08001777 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001778 synchronized (obs) {
1779 while (!obs.finished) {
1780 try {
1781 obs.wait();
1782 } catch (InterruptedException e) {
1783 }
1784 }
1785 }
1786
1787 if (obs.result) {
1788 getOutPrintWriter().println("Success");
1789 return 0;
1790 } else {
1791 getErrPrintWriter().println("Failed");
1792 return 1;
1793 }
1794 }
1795
1796 private static String enabledSettingToString(int state) {
1797 switch (state) {
1798 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1799 return "default";
1800 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1801 return "enabled";
1802 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1803 return "disabled";
1804 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1805 return "disabled-user";
1806 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1807 return "disabled-until-used";
1808 }
1809 return "unknown";
1810 }
1811
1812 private int runSetEnabledSetting(int state) throws RemoteException {
1813 int userId = UserHandle.USER_SYSTEM;
1814 String option = getNextOption();
1815 if (option != null && option.equals("--user")) {
1816 userId = UserHandle.parseUserArg(getNextArgRequired());
1817 }
1818
1819 String pkg = getNextArg();
1820 if (pkg == null) {
1821 getErrPrintWriter().println("Error: no package or component specified");
1822 return 1;
1823 }
1824 ComponentName cn = ComponentName.unflattenFromString(pkg);
1825 if (cn == null) {
1826 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1827 "shell:" + android.os.Process.myUid());
1828 getOutPrintWriter().println("Package " + pkg + " new state: "
1829 + enabledSettingToString(
1830 mInterface.getApplicationEnabledSetting(pkg, userId)));
1831 return 0;
1832 } else {
1833 mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1834 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1835 + enabledSettingToString(
1836 mInterface.getComponentEnabledSetting(cn, userId)));
1837 return 0;
1838 }
1839 }
1840
1841 private int runSetHiddenSetting(boolean state) throws RemoteException {
1842 int userId = UserHandle.USER_SYSTEM;
1843 String option = getNextOption();
1844 if (option != null && option.equals("--user")) {
1845 userId = UserHandle.parseUserArg(getNextArgRequired());
1846 }
1847
1848 String pkg = getNextArg();
1849 if (pkg == null) {
1850 getErrPrintWriter().println("Error: no package or component specified");
1851 return 1;
1852 }
1853 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1854 getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1855 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1856 return 0;
1857 }
1858
1859 private int runSuspend(boolean suspendedState) {
1860 final PrintWriter pw = getOutPrintWriter();
1861 int userId = UserHandle.USER_SYSTEM;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001862 String dialogMessage = null;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001863 final PersistableBundle appExtras = new PersistableBundle();
1864 final PersistableBundle launcherExtras = new PersistableBundle();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001865 String opt;
1866 while ((opt = getNextOption()) != null) {
1867 switch (opt) {
1868 case "--user":
1869 userId = UserHandle.parseUserArg(getNextArgRequired());
1870 break;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001871 case "--dialogMessage":
1872 dialogMessage = getNextArgRequired();
1873 break;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001874 case "--ael":
1875 case "--aes":
1876 case "--aed":
1877 case "--lel":
1878 case "--les":
1879 case "--led":
1880 final String key = getNextArgRequired();
1881 final String val = getNextArgRequired();
1882 if (!suspendedState) {
1883 break;
1884 }
1885 final PersistableBundle bundleToInsert =
1886 opt.startsWith("--a") ? appExtras : launcherExtras;
1887 switch (opt.charAt(4)) {
1888 case 'l':
1889 bundleToInsert.putLong(key, Long.valueOf(val));
1890 break;
1891 case 'd':
1892 bundleToInsert.putDouble(key, Double.valueOf(val));
1893 break;
1894 case 's':
1895 bundleToInsert.putString(key, val);
1896 break;
1897 }
1898 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001899 default:
1900 pw.println("Error: Unknown option: " + opt);
1901 return 1;
1902 }
1903 }
1904
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001905 final String packageName = getNextArg();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001906 if (packageName == null) {
1907 pw.println("Error: package name not specified");
1908 return 1;
1909 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001910 final String callingPackage =
1911 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07001912
1913 final SuspendDialogInfo info;
1914 if (!TextUtils.isEmpty(dialogMessage)) {
1915 info = new SuspendDialogInfo.Builder()
1916 .setMessage(dialogMessage)
1917 .build();
1918 } else {
1919 info = null;
1920 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001921 try {
1922 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07001923 appExtras, launcherExtras, info, callingPackage, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001924 pw.println("Package " + packageName + " new suspended state: "
1925 + mInterface.isPackageSuspendedForUser(packageName, userId));
1926 return 0;
1927 } catch (RemoteException | IllegalArgumentException e) {
1928 pw.println(e.toString());
1929 return 1;
1930 }
1931 }
1932
1933 private int runGrantRevokePermission(boolean grant) throws RemoteException {
1934 int userId = UserHandle.USER_SYSTEM;
1935
1936 String opt = null;
1937 while ((opt = getNextOption()) != null) {
1938 if (opt.equals("--user")) {
1939 userId = UserHandle.parseUserArg(getNextArgRequired());
1940 }
1941 }
1942
1943 String pkg = getNextArg();
1944 if (pkg == null) {
1945 getErrPrintWriter().println("Error: no package specified");
1946 return 1;
1947 }
1948 String perm = getNextArg();
1949 if (perm == null) {
1950 getErrPrintWriter().println("Error: no permission specified");
1951 return 1;
1952 }
1953
1954 if (grant) {
1955 mInterface.grantRuntimePermission(pkg, perm, userId);
1956 } else {
1957 mInterface.revokeRuntimePermission(pkg, perm, userId);
1958 }
1959 return 0;
1960 }
1961
1962 private int runResetPermissions() throws RemoteException {
1963 mInterface.resetRuntimePermissions();
1964 return 0;
1965 }
1966
1967 private int runSetPermissionEnforced() throws RemoteException {
1968 final String permission = getNextArg();
1969 if (permission == null) {
1970 getErrPrintWriter().println("Error: no permission specified");
1971 return 1;
1972 }
1973 final String enforcedRaw = getNextArg();
1974 if (enforcedRaw == null) {
1975 getErrPrintWriter().println("Error: no enforcement specified");
1976 return 1;
1977 }
1978 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
1979 return 0;
1980 }
1981
Jiyong Park002fdbd2017-02-13 20:50:31 +09001982 private boolean isVendorApp(String pkg) {
1983 try {
1984 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1985 return info != null && info.applicationInfo.isVendor();
1986 } catch (RemoteException e) {
1987 return false;
1988 }
1989 }
1990
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001991 private boolean isProductApp(String pkg) {
1992 try {
1993 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1994 return info != null && info.applicationInfo.isProduct();
1995 } catch (RemoteException e) {
1996 return false;
1997 }
1998 }
1999
Dario Freni2bef1762018-06-01 14:02:08 +01002000 private boolean isProductServicesApp(String pkg) {
2001 try {
2002 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
2003 return info != null && info.applicationInfo.isProductServices();
2004 } catch (RemoteException e) {
2005 return false;
2006 }
2007 }
2008
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002009 private int runGetPrivappPermissions() {
2010 final String pkg = getNextArg();
2011 if (pkg == null) {
2012 getErrPrintWriter().println("Error: no package specified.");
2013 return 1;
2014 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002015
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002016 ArraySet<String> privAppPermissions = null;
2017 if (isVendorApp(pkg)) {
2018 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
2019 } else if (isProductApp(pkg)) {
2020 privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
Dario Freni2bef1762018-06-01 14:02:08 +01002021 } else if (isProductServicesApp(pkg)) {
2022 privAppPermissions = SystemConfig.getInstance()
2023 .getProductServicesPrivAppPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002024 } else {
2025 privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
2026 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002027
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002028 getOutPrintWriter().println(privAppPermissions == null
2029 ? "{}" : privAppPermissions.toString());
2030 return 0;
2031 }
2032
2033 private int runGetPrivappDenyPermissions() {
2034 final String pkg = getNextArg();
2035 if (pkg == null) {
2036 getErrPrintWriter().println("Error: no package specified.");
2037 return 1;
2038 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002039
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002040 ArraySet<String> privAppPermissions = null;
2041 if (isVendorApp(pkg)) {
2042 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
2043 } else if (isProductApp(pkg)) {
2044 privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
Dario Freni2bef1762018-06-01 14:02:08 +01002045 } else if (isProductServicesApp(pkg)) {
2046 privAppPermissions = SystemConfig.getInstance()
2047 .getProductServicesPrivAppDenyPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002048 } else {
2049 privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
2050 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002051
2052 getOutPrintWriter().println(privAppPermissions == null
2053 ? "{}" : privAppPermissions.toString());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002054 return 0;
2055 }
2056
2057 private int runGetOemPermissions() {
2058 final String pkg = getNextArg();
2059 if (pkg == null) {
2060 getErrPrintWriter().println("Error: no package specified.");
2061 return 1;
2062 }
2063 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
2064 .getOemPermissions(pkg);
2065 if (oemPermissions == null || oemPermissions.isEmpty()) {
2066 getOutPrintWriter().println("{}");
2067 } else {
2068 oemPermissions.forEach((permission, granted) ->
2069 getOutPrintWriter().println(permission + " granted:" + granted)
2070 );
2071 }
2072 return 0;
2073 }
2074
2075 private String linkStateToString(int state) {
2076 switch (state) {
2077 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
2078 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
2079 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
2080 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
2081 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
2082 }
2083 return "Unknown link state: " + state;
2084 }
2085
2086 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
2087 private int runSetAppLink() throws RemoteException {
2088 int userId = UserHandle.USER_SYSTEM;
2089
2090 String opt;
2091 while ((opt = getNextOption()) != null) {
2092 if (opt.equals("--user")) {
2093 userId = UserHandle.parseUserArg(getNextArgRequired());
2094 } else {
2095 getErrPrintWriter().println("Error: unknown option: " + opt);
2096 return 1;
2097 }
2098 }
2099
2100 // Package name to act on; required
2101 final String pkg = getNextArg();
2102 if (pkg == null) {
2103 getErrPrintWriter().println("Error: no package specified.");
2104 return 1;
2105 }
2106
2107 // State to apply; {always|ask|never|undefined}, required
2108 final String modeString = getNextArg();
2109 if (modeString == null) {
2110 getErrPrintWriter().println("Error: no app link state specified.");
2111 return 1;
2112 }
2113
2114 final int newMode;
2115 switch (modeString.toLowerCase()) {
2116 case "undefined":
2117 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
2118 break;
2119
2120 case "always":
2121 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
2122 break;
2123
2124 case "ask":
2125 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
2126 break;
2127
2128 case "always-ask":
2129 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
2130 break;
2131
2132 case "never":
2133 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
2134 break;
2135
2136 default:
2137 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
2138 return 1;
2139 }
2140
2141 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
2142 if (info == null) {
2143 getErrPrintWriter().println("Error: package " + pkg + " not found.");
2144 return 1;
2145 }
2146
2147 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2148 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2149 return 1;
2150 }
2151
2152 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
2153 getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
2154 return 1;
2155 }
2156
2157 return 0;
2158 }
2159
2160 // pm get-app-link [--user USER_ID] PACKAGE
2161 private int runGetAppLink() throws RemoteException {
2162 int userId = UserHandle.USER_SYSTEM;
2163
2164 String opt;
2165 while ((opt = getNextOption()) != null) {
2166 if (opt.equals("--user")) {
2167 userId = UserHandle.parseUserArg(getNextArgRequired());
2168 } else {
2169 getErrPrintWriter().println("Error: unknown option: " + opt);
2170 return 1;
2171 }
2172 }
2173
2174 // Package name to act on; required
2175 final String pkg = getNextArg();
2176 if (pkg == null) {
2177 getErrPrintWriter().println("Error: no package specified.");
2178 return 1;
2179 }
2180
2181 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
2182 if (info == null) {
2183 getErrPrintWriter().println("Error: package " + pkg + " not found.");
2184 return 1;
2185 }
2186
2187 if ((info.applicationInfo.privateFlags
2188 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2189 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2190 return 1;
2191 }
2192
2193 getOutPrintWriter().println(linkStateToString(
2194 mInterface.getIntentVerificationStatus(pkg, userId)));
2195
2196 return 0;
2197 }
2198
2199 private int runTrimCaches() throws RemoteException {
2200 String size = getNextArg();
2201 if (size == null) {
2202 getErrPrintWriter().println("Error: no size specified");
2203 return 1;
2204 }
2205 long multiplier = 1;
2206 int len = size.length();
2207 char c = size.charAt(len - 1);
2208 if (c < '0' || c > '9') {
2209 if (c == 'K' || c == 'k') {
2210 multiplier = 1024L;
2211 } else if (c == 'M' || c == 'm') {
2212 multiplier = 1024L*1024L;
2213 } else if (c == 'G' || c == 'g') {
2214 multiplier = 1024L*1024L*1024L;
2215 } else {
2216 getErrPrintWriter().println("Invalid suffix: " + c);
2217 return 1;
2218 }
2219 size = size.substring(0, len-1);
2220 }
2221 long sizeVal;
2222 try {
2223 sizeVal = Long.parseLong(size) * multiplier;
2224 } catch (NumberFormatException e) {
2225 getErrPrintWriter().println("Error: expected number at: " + size);
2226 return 1;
2227 }
2228 String volumeUuid = getNextArg();
2229 if ("internal".equals(volumeUuid)) {
2230 volumeUuid = null;
2231 }
2232 ClearDataObserver obs = new ClearDataObserver();
2233 mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
2234 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
2235 synchronized (obs) {
2236 while (!obs.finished) {
2237 try {
2238 obs.wait();
2239 } catch (InterruptedException e) {
2240 }
2241 }
2242 }
2243 return 0;
2244 }
2245
2246 private static boolean isNumber(String s) {
2247 try {
2248 Integer.parseInt(s);
2249 } catch (NumberFormatException nfe) {
2250 return false;
2251 }
2252 return true;
2253 }
2254
2255 public int runCreateUser() throws RemoteException {
2256 String name;
2257 int userId = -1;
2258 int flags = 0;
2259 String opt;
Felipe Leme7ad2f6b2019-09-11 09:23:26 -07002260 boolean preCreateOnly = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002261 while ((opt = getNextOption()) != null) {
2262 if ("--profileOf".equals(opt)) {
2263 userId = UserHandle.parseUserArg(getNextArgRequired());
2264 } else if ("--managed".equals(opt)) {
2265 flags |= UserInfo.FLAG_MANAGED_PROFILE;
2266 } else if ("--restricted".equals(opt)) {
2267 flags |= UserInfo.FLAG_RESTRICTED;
2268 } else if ("--ephemeral".equals(opt)) {
2269 flags |= UserInfo.FLAG_EPHEMERAL;
2270 } else if ("--guest".equals(opt)) {
2271 flags |= UserInfo.FLAG_GUEST;
2272 } else if ("--demo".equals(opt)) {
2273 flags |= UserInfo.FLAG_DEMO;
Felipe Leme7ad2f6b2019-09-11 09:23:26 -07002274 } else if ("--pre-create-only".equals(opt)) {
2275 preCreateOnly = true;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002276 } else {
2277 getErrPrintWriter().println("Error: unknown option " + opt);
2278 return 1;
2279 }
2280 }
2281 String arg = getNextArg();
Felipe Leme07653f02019-10-14 15:37:44 -07002282 if (arg == null && !preCreateOnly) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002283 getErrPrintWriter().println("Error: no user name specified.");
2284 return 1;
2285 }
Felipe Leme07653f02019-10-14 15:37:44 -07002286 if (arg != null && preCreateOnly) {
2287 getErrPrintWriter().println("Warning: name is ignored for pre-created users");
2288 }
2289
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002290 name = arg;
2291 UserInfo info;
2292 IUserManager um = IUserManager.Stub.asInterface(
2293 ServiceManager.getService(Context.USER_SERVICE));
2294 IAccountManager accm = IAccountManager.Stub.asInterface(
2295 ServiceManager.getService(Context.ACCOUNT_SERVICE));
2296 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
2297 // In non-split user mode, userId can only be SYSTEM
2298 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
2299 info = um.createRestrictedProfile(name, parentUserId);
2300 accm.addSharedAccountsFromParentUser(parentUserId, userId,
2301 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
2302 } else if (userId < 0) {
Felipe Leme7ad2f6b2019-09-11 09:23:26 -07002303 info = preCreateOnly ? um.preCreateUser(flags) : um.createUser(name, flags);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002304 } else {
2305 info = um.createProfileForUser(name, flags, userId, null);
2306 }
2307
2308 if (info != null) {
2309 getOutPrintWriter().println("Success: created user id " + info.id);
2310 return 0;
2311 } else {
2312 getErrPrintWriter().println("Error: couldn't create User.");
2313 return 1;
2314 }
2315 }
2316
2317 public int runRemoveUser() throws RemoteException {
2318 int userId;
2319 String arg = getNextArg();
2320 if (arg == null) {
2321 getErrPrintWriter().println("Error: no user id specified.");
2322 return 1;
2323 }
2324 userId = UserHandle.parseUserArg(arg);
2325 IUserManager um = IUserManager.Stub.asInterface(
2326 ServiceManager.getService(Context.USER_SERVICE));
2327 if (um.removeUser(userId)) {
2328 getOutPrintWriter().println("Success: removed user");
2329 return 0;
2330 } else {
2331 getErrPrintWriter().println("Error: couldn't remove user id " + userId);
2332 return 1;
2333 }
2334 }
2335
2336 public int runSetUserRestriction() throws RemoteException {
2337 int userId = UserHandle.USER_SYSTEM;
2338 String opt = getNextOption();
2339 if (opt != null && "--user".equals(opt)) {
2340 userId = UserHandle.parseUserArg(getNextArgRequired());
2341 }
2342
2343 String restriction = getNextArg();
2344 String arg = getNextArg();
2345 boolean value;
2346 if ("1".equals(arg)) {
2347 value = true;
2348 } else if ("0".equals(arg)) {
2349 value = false;
2350 } else {
2351 getErrPrintWriter().println("Error: valid value not specified");
2352 return 1;
2353 }
2354 IUserManager um = IUserManager.Stub.asInterface(
2355 ServiceManager.getService(Context.USER_SERVICE));
2356 um.setUserRestriction(restriction, value, userId);
2357 return 0;
2358 }
2359
2360 public int runGetMaxUsers() {
2361 getOutPrintWriter().println("Maximum supported users: "
2362 + UserManager.getMaxSupportedUsers());
2363 return 0;
2364 }
2365
Alex Chauc12189b2018-01-16 15:01:15 +00002366 public int runGetMaxRunningUsers() {
2367 ActivityManagerInternal activityManagerInternal =
2368 LocalServices.getService(ActivityManagerInternal.class);
2369 getOutPrintWriter().println("Maximum supported running users: "
2370 + activityManagerInternal.getMaxRunningUsers());
2371 return 0;
2372 }
2373
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002374 private static class InstallParams {
2375 SessionParams sessionParams;
2376 String installerPackageName;
2377 int userId = UserHandle.USER_ALL;
2378 }
2379
2380 private InstallParams makeInstallParams() {
2381 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
2382 final InstallParams params = new InstallParams();
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07002383
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002384 params.sessionParams = sessionParams;
Philip P. Moltmanna4bd1502019-05-13 17:10:46 -07002385 // Whitelist all permissions by default
2386 sessionParams.installFlags |= PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
2387
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002388 String opt;
Patrick Baumanna9333492017-11-28 15:23:49 -08002389 boolean replaceExisting = true;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002390 while ((opt = getNextOption()) != null) {
2391 switch (opt) {
Patrick Baumanna9333492017-11-28 15:23:49 -08002392 case "-r": // ignore
2393 break;
2394 case "-R":
2395 replaceExisting = false;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002396 break;
2397 case "-i":
2398 params.installerPackageName = getNextArg();
2399 if (params.installerPackageName == null) {
2400 throw new IllegalArgumentException("Missing installer package");
2401 }
2402 break;
2403 case "-t":
2404 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
2405 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002406 case "-f":
2407 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
2408 break;
2409 case "-d":
Nikita Ioffeb1d60f12019-03-06 18:56:49 +00002410 sessionParams.installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002411 break;
2412 case "-g":
2413 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002414 break;
2415 case "--restrict-permissions":
2416 sessionParams.installFlags &=
2417 ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002418 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002419 case "--dont-kill":
2420 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
2421 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002422 case "--originating-uri":
2423 sessionParams.originatingUri = Uri.parse(getNextArg());
2424 break;
2425 case "--referrer":
2426 sessionParams.referrerUri = Uri.parse(getNextArg());
2427 break;
2428 case "-p":
2429 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
2430 sessionParams.appPackageName = getNextArg();
2431 if (sessionParams.appPackageName == null) {
2432 throw new IllegalArgumentException("Missing inherit package name");
2433 }
2434 break;
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002435 case "--pkg":
2436 sessionParams.appPackageName = getNextArg();
2437 if (sessionParams.appPackageName == null) {
2438 throw new IllegalArgumentException("Missing package name");
2439 }
2440 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002441 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002442 final long sizeBytes = Long.parseLong(getNextArg());
2443 if (sizeBytes <= 0) {
2444 throw new IllegalArgumentException("Size must be positive");
2445 }
2446 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002447 break;
2448 case "--abi":
2449 sessionParams.abiOverride = checkAbiArgument(getNextArg());
2450 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08002451 case "--ephemeral":
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002452 case "--instant":
Todd Kennedybe0b8892017-02-15 14:13:52 -08002453 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08002454 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08002455 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08002456 case "--full":
2457 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
2458 break;
Todd Kennedy78a72502017-07-19 12:49:30 -07002459 case "--preload":
2460 sessionParams.setInstallAsVirtualPreload();
2461 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002462 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002463 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002464 break;
2465 case "--install-location":
2466 sessionParams.installLocation = Integer.parseInt(getNextArg());
2467 break;
Sunny Goyalabd4d442018-09-19 15:49:50 -07002468 case "--install-reason":
2469 sessionParams.installReason = Integer.parseInt(getNextArg());
2470 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002471 case "--force-uuid":
2472 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
2473 sessionParams.volumeUuid = getNextArg();
2474 if ("internal".equals(sessionParams.volumeUuid)) {
2475 sessionParams.volumeUuid = null;
2476 }
2477 break;
Nicholas Lativyeb23e4d2019-02-01 13:39:28 +00002478 case "--force-sdk": // ignore
Todd Kennedyb1072712016-04-26 15:41:20 -07002479 break;
Dario Frenid8bf22e2018-08-31 14:18:04 +01002480 case "--apex":
Dario Freni3fa46d82019-01-23 19:31:47 +00002481 sessionParams.setInstallAsApex();
Dario Freni505b8152019-01-08 12:30:43 +00002482 sessionParams.setStaged();
Dario Frenid8bf22e2018-08-31 14:18:04 +01002483 break;
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002484 case "--multi-package":
2485 sessionParams.setMultiPackage();
2486 break;
Dario Freniaac4ba42018-12-06 15:47:16 +00002487 case "--staged":
2488 sessionParams.setStaged();
2489 break;
Richard Uhlerb29f1452018-09-12 16:38:15 +01002490 case "--enable-rollback":
Richard Uhler88184a62019-04-16 11:30:25 +01002491 if (params.installerPackageName == null) {
2492 // com.android.shell has the TEST_MANAGE_ROLLBACKS
2493 // permission needed to enable rollback for non-module
2494 // packages, which is likely what the user wants when
2495 // enabling rollback through the shell command. Set
2496 // the installer to com.android.shell if no installer
2497 // has been provided so that the user doesn't have to
2498 // remember to set it themselves.
2499 params.installerPackageName = "com.android.shell";
2500 }
Richard Uhlerb29f1452018-09-12 16:38:15 +01002501 sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
2502 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002503 default:
2504 throw new IllegalArgumentException("Unknown option " + opt);
2505 }
Patrick Baumanndcf19162019-05-29 09:18:58 -07002506 }
2507 if (replaceExisting) {
2508 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002509 }
2510 return params;
2511 }
2512
Makoto Onuki4828a592016-03-15 18:06:57 -07002513 private int runSetHomeActivity() {
2514 final PrintWriter pw = getOutPrintWriter();
2515 int userId = UserHandle.USER_SYSTEM;
2516 String opt;
2517 while ((opt = getNextOption()) != null) {
2518 switch (opt) {
2519 case "--user":
2520 userId = UserHandle.parseUserArg(getNextArgRequired());
2521 break;
2522 default:
2523 pw.println("Error: Unknown option: " + opt);
2524 return 1;
2525 }
2526 }
2527
Bookatz2b5a6012019-04-16 19:41:28 -07002528 String pkgName;
Makoto Onuki4828a592016-03-15 18:06:57 -07002529 String component = getNextArg();
Bookatz2b5a6012019-04-16 19:41:28 -07002530 if (component.indexOf('/') < 0) {
2531 // No component specified, so assume it's just a package name.
2532 pkgName = component;
2533 } else {
2534 ComponentName componentName =
2535 component != null ? ComponentName.unflattenFromString(component) : null;
2536 if (componentName == null) {
2537 pw.println("Error: invalid component name");
2538 return 1;
2539 }
2540 pkgName = componentName.getPackageName();
Makoto Onuki4828a592016-03-15 18:06:57 -07002541 }
2542
Bookatz2b5a6012019-04-16 19:41:28 -07002543
2544 final CompletableFuture<Boolean> future = new CompletableFuture<>();
2545 final RemoteCallback callback = new RemoteCallback(res -> future.complete(res != null));
Makoto Onuki4828a592016-03-15 18:06:57 -07002546 try {
Bookatz2b5a6012019-04-16 19:41:28 -07002547 IRoleManager roleManager = android.app.role.IRoleManager.Stub.asInterface(
2548 ServiceManager.getServiceOrThrow(Context.ROLE_SERVICE));
2549 roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, pkgName,
2550 0, userId, callback);
2551 boolean success = future.get();
2552 if (success) {
2553 pw.println("Success");
2554 return 0;
2555 } else {
2556 pw.println("Error: Failed to set default home.");
2557 return 1;
2558 }
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002559 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07002560 pw.println(e.toString());
2561 return 1;
2562 }
2563 }
2564
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002565 private int runSetInstaller() throws RemoteException {
2566 final String targetPackage = getNextArg();
2567 final String installerPackageName = getNextArg();
Fyodor Kupolov51245c72016-12-01 11:34:10 -08002568
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002569 if (targetPackage == null || installerPackageName == null) {
2570 getErrPrintWriter().println("Must provide both target and installer package names");
Todd Kennedy74629e32017-08-15 14:48:07 -07002571 return 1;
2572 }
Todd Kennedy74629e32017-08-15 14:48:07 -07002573
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002574 mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2575 getOutPrintWriter().println("Success");
Svet Ganov087dce22017-09-07 15:42:16 -07002576 return 0;
2577 }
2578
Todd Kennedy0a3f0812017-05-08 14:43:15 -07002579 private int runGetInstantAppResolver() {
2580 final PrintWriter pw = getOutPrintWriter();
2581 try {
2582 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2583 if (instantAppsResolver == null) {
2584 return 1;
2585 }
2586 pw.println(instantAppsResolver.flattenToString());
2587 return 0;
2588 } catch (Exception e) {
2589 pw.println(e.toString());
2590 return 1;
2591 }
2592 }
2593
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09002594 private int runHasFeature() {
2595 final PrintWriter err = getErrPrintWriter();
2596 final String featureName = getNextArg();
2597 if (featureName == null) {
2598 err.println("Error: expected FEATURE name");
2599 return 1;
2600 }
2601 final String versionString = getNextArg();
2602 try {
2603 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2604 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2605 getOutPrintWriter().println(hasFeature);
2606 return hasFeature ? 0 : 1;
2607 } catch (NumberFormatException e) {
2608 err.println("Error: illegal version number " + versionString);
2609 return 1;
2610 } catch (RemoteException e) {
2611 err.println(e.toString());
2612 return 1;
2613 }
2614 }
2615
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002616 private int runDump() {
2617 String pkg = getNextArg();
2618 if (pkg == null) {
2619 getErrPrintWriter().println("Error: no package specified");
2620 return 1;
2621 }
2622 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2623 return 0;
2624 }
2625
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002626 private int runSetHarmfulAppWarning() throws RemoteException {
2627 int userId = UserHandle.USER_CURRENT;
2628
2629 String opt;
2630 while ((opt = getNextOption()) != null) {
2631 if (opt.equals("--user")) {
2632 userId = UserHandle.parseUserArg(getNextArgRequired());
2633 } else {
2634 getErrPrintWriter().println("Error: Unknown option: " + opt);
2635 return -1;
2636 }
2637 }
2638
2639 userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning");
2640
2641 final String packageName = getNextArgRequired();
2642 final String warning = getNextArg();
2643
2644 mInterface.setHarmfulAppWarning(packageName, warning, userId);
2645
2646 return 0;
2647 }
2648
Ben Gruver9ef60092018-01-10 11:32:30 -08002649 private int runGetHarmfulAppWarning() throws RemoteException {
2650 int userId = UserHandle.USER_CURRENT;
2651
2652 String opt;
2653 while ((opt = getNextOption()) != null) {
2654 if (opt.equals("--user")) {
2655 userId = UserHandle.parseUserArg(getNextArgRequired());
2656 } else {
2657 getErrPrintWriter().println("Error: Unknown option: " + opt);
2658 return -1;
2659 }
2660 }
2661
2662 userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning");
2663
2664 final String packageName = getNextArgRequired();
2665 final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId);
2666 if (!TextUtils.isEmpty(warning)) {
2667 getOutPrintWriter().println(warning);
2668 return 0;
2669 } else {
2670 return 1;
2671 }
2672 }
2673
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002674 private static String checkAbiArgument(String abi) {
2675 if (TextUtils.isEmpty(abi)) {
2676 throw new IllegalArgumentException("Missing ABI argument");
2677 }
2678
2679 if ("-".equals(abi)) {
2680 return abi;
2681 }
2682
2683 final String[] supportedAbis = Build.SUPPORTED_ABIS;
2684 for (String supportedAbi : supportedAbis) {
2685 if (supportedAbi.equals(abi)) {
2686 return abi;
2687 }
2688 }
2689
2690 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2691 }
2692
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002693 private int translateUserId(int userId, boolean allowAll, String logContext) {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002694 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002695 userId, allowAll, true, logContext, "pm command");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002696 }
2697
2698 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2699 throws RemoteException {
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002700 userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002701 if (userId == UserHandle.USER_ALL) {
2702 userId = UserHandle.USER_SYSTEM;
2703 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2704 }
2705
2706 final int sessionId = mInterface.getPackageInstaller()
2707 .createSession(params, installerPackageName, userId);
2708 return sessionId;
2709 }
2710
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002711 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002712 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002713 PackageInstaller.Session session = null;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002714 try {
Jeff Sharkeya651b782018-07-23 13:45:28 -06002715 final PrintWriter pw = getOutPrintWriter();
2716 final ParcelFileDescriptor fd;
2717 if (STDIN_PATH.equals(inPath)) {
2718 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2719 } else if (inPath != null) {
2720 fd = openFileForSystem(inPath, "r");
2721 if (fd == null) {
2722 return -1;
2723 }
2724 sizeBytes = fd.getStatSize();
2725 if (sizeBytes < 0) {
2726 getErrPrintWriter().println("Unable to get size of: " + inPath);
2727 return -1;
2728 }
2729 } else {
2730 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2731 }
2732 if (sizeBytes <= 0) {
2733 getErrPrintWriter().println("Error: must specify a APK size");
2734 return 1;
2735 }
2736
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002737 session = new PackageInstaller.Session(
2738 mInterface.getPackageInstaller().openSession(sessionId));
Jeff Sharkey0451de62018-02-02 11:27:21 -07002739 session.write(splitName, 0, sizeBytes, fd);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002740
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002741 if (logSuccess) {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002742 pw.println("Success: streamed " + sizeBytes + " bytes");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002743 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002744 return 0;
2745 } catch (IOException e) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002746 getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002747 return 1;
2748 } finally {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002749 IoUtils.closeQuietly(session);
2750 }
2751 }
2752
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002753 private int doInstallAddSession(int parentId, int[] sessionIds, boolean logSuccess)
2754 throws RemoteException {
2755 final PrintWriter pw = getOutPrintWriter();
2756 PackageInstaller.Session session = null;
2757 try {
2758 session = new PackageInstaller.Session(
2759 mInterface.getPackageInstaller().openSession(parentId));
2760 if (!session.isMultiPackage()) {
2761 getErrPrintWriter().println(
2762 "Error: parent session ID is not a multi-package session");
2763 return 1;
2764 }
2765 for (int i = 0; i < sessionIds.length; i++) {
2766 session.addChildSessionId(sessionIds[i]);
2767 }
2768 if (logSuccess) {
2769 pw.println("Success");
2770 }
2771 return 0;
2772 } finally {
2773 IoUtils.closeQuietly(session);
2774 }
2775 }
2776
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002777 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2778 throws RemoteException {
2779 final PrintWriter pw = getOutPrintWriter();
2780 PackageInstaller.Session session = null;
2781 try {
2782 session = new PackageInstaller.Session(
2783 mInterface.getPackageInstaller().openSession(sessionId));
2784 session.removeSplit(splitName);
2785
2786 if (logSuccess) {
2787 pw.println("Success");
2788 }
2789 return 0;
2790 } catch (IOException e) {
2791 pw.println("Error: failed to remove split; " + e.getMessage());
2792 return 1;
2793 } finally {
2794 IoUtils.closeQuietly(session);
2795 }
2796 }
2797
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002798 private int doCommitSession(int sessionId, boolean logSuccess)
2799 throws RemoteException {
2800
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002801 final PrintWriter pw = getOutPrintWriter();
2802 PackageInstaller.Session session = null;
2803 try {
2804 session = new PackageInstaller.Session(
2805 mInterface.getPackageInstaller().openSession(sessionId));
Dario Frenia8f4b132018-12-30 00:36:49 +00002806 if (!session.isMultiPackage() && !session.isStaged()) {
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002807 // Sanity check that all .dm files match an apk.
2808 // (The installer does not support standalone .dm files and will not process them.)
2809 try {
2810 DexMetadataHelper.validateDexPaths(session.getNames());
2811 } catch (IllegalStateException | IOException e) {
2812 pw.println(
2813 "Warning [Could not validate the dex paths: " + e.getMessage() + "]");
2814 }
Calin Juravle3fc56c32017-12-11 18:26:13 -08002815 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002816 final LocalIntentReceiver receiver = new LocalIntentReceiver();
2817 session.commit(receiver.getIntentSender());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002818 final Intent result = receiver.getResult();
2819 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2820 PackageInstaller.STATUS_FAILURE);
2821 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002822 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07002823 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002824 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002825 } else {
2826 pw.println("Failure ["
2827 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002828 }
2829 return status;
2830 } finally {
2831 IoUtils.closeQuietly(session);
2832 }
2833 }
2834
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002835 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002836 final PrintWriter pw = getOutPrintWriter();
2837 PackageInstaller.Session session = null;
2838 try {
2839 session = new PackageInstaller.Session(
2840 mInterface.getPackageInstaller().openSession(sessionId));
2841 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002842 if (logSuccess) {
2843 pw.println("Success");
2844 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002845 return 0;
2846 } finally {
2847 IoUtils.closeQuietly(session);
2848 }
2849 }
2850
Todd Kennedy60459ab2015-10-30 11:32:16 -07002851 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2852 boolean summary, int startProtectionLevel, int endProtectionLevel)
2853 throws RemoteException {
2854 final PrintWriter pw = getOutPrintWriter();
2855 final int groupCount = groupList.size();
2856 for (int i = 0; i < groupCount; i++) {
2857 String groupName = groupList.get(i);
2858 String prefix = "";
2859 if (groups) {
2860 if (i > 0) {
2861 pw.println("");
2862 }
2863 if (groupName != null) {
2864 PermissionGroupInfo pgi =
2865 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2866 if (summary) {
2867 Resources res = getResources(pgi);
2868 if (res != null) {
2869 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2870 } else {
2871 pw.print(pgi.name + ": ");
2872
2873 }
2874 } else {
2875 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2876 if (labels) {
2877 pw.println(" package:" + pgi.packageName);
2878 Resources res = getResources(pgi);
2879 if (res != null) {
2880 pw.println(" label:"
2881 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
2882 pw.println(" description:"
2883 + loadText(pgi, pgi.descriptionRes,
2884 pgi.nonLocalizedDescription));
2885 }
2886 }
2887 }
2888 } else {
2889 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
2890 }
2891 prefix = " ";
2892 }
2893 List<PermissionInfo> ps =
Jeff Sharkeyd5896632016-03-04 16:16:00 -07002894 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07002895 final int count = ps.size();
2896 boolean first = true;
2897 for (int p = 0 ; p < count ; p++) {
2898 PermissionInfo pi = ps.get(p);
2899 if (groups && groupName == null && pi.group != null) {
2900 continue;
2901 }
2902 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
2903 if (base < startProtectionLevel
2904 || base > endProtectionLevel) {
2905 continue;
2906 }
2907 if (summary) {
2908 if (first) {
2909 first = false;
2910 } else {
2911 pw.print(", ");
2912 }
2913 Resources res = getResources(pi);
2914 if (res != null) {
2915 pw.print(loadText(pi, pi.labelRes,
2916 pi.nonLocalizedLabel));
2917 } else {
2918 pw.print(pi.name);
2919 }
2920 } else {
2921 pw.println(prefix + (labels ? "+ " : "")
2922 + "permission:" + pi.name);
2923 if (labels) {
2924 pw.println(prefix + " package:" + pi.packageName);
2925 Resources res = getResources(pi);
2926 if (res != null) {
2927 pw.println(prefix + " label:"
2928 + loadText(pi, pi.labelRes,
2929 pi.nonLocalizedLabel));
2930 pw.println(prefix + " description:"
2931 + loadText(pi, pi.descriptionRes,
2932 pi.nonLocalizedDescription));
2933 }
2934 pw.println(prefix + " protectionLevel:"
2935 + PermissionInfo.protectionToString(pi.protectionLevel));
2936 }
2937 }
2938 }
2939
2940 if (summary) {
2941 pw.println("");
2942 }
2943 }
2944 }
2945
2946 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
2947 throws RemoteException {
2948 if (nonLocalized != null) {
2949 return nonLocalized.toString();
2950 }
2951 if (res != 0) {
2952 Resources r = getResources(pii);
2953 if (r != null) {
2954 try {
2955 return r.getString(res);
2956 } catch (Resources.NotFoundException e) {
2957 }
2958 }
2959 }
2960 return null;
2961 }
2962
2963 private Resources getResources(PackageItemInfo pii) throws RemoteException {
2964 Resources res = mResourceCache.get(pii.packageName);
2965 if (res != null) return res;
2966
2967 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
2968 AssetManager am = new AssetManager();
2969 am.addAssetPath(ai.publicSourceDir);
2970 res = new Resources(am, null, null);
2971 mResourceCache.put(pii.packageName, res);
2972 return res;
2973 }
2974
2975 @Override
2976 public void onHelp() {
2977 final PrintWriter pw = getOutPrintWriter();
2978 pw.println("Package manager (package) commands:");
2979 pw.println(" help");
2980 pw.println(" Print this help text.");
2981 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002982 pw.println(" path [--user USER_ID] PACKAGE");
2983 pw.println(" Print the path to the .apk of the given PACKAGE.");
2984 pw.println("");
2985 pw.println(" dump PACKAGE");
2986 pw.println(" Print various system state associated with the given PACKAGE.");
2987 pw.println("");
2988 pw.println(" list features");
2989 pw.println(" Prints all features of the system.");
2990 pw.println("");
2991 pw.println(" has-feature FEATURE_NAME [version]");
2992 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,");
2993 pw.println(" otherwise prints false and returns exit status 1");
2994 pw.println("");
2995 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
2996 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
2997 pw.println(" Options:");
2998 pw.println(" -f: dump the name of the .apk file containing the test package");
2999 pw.println("");
3000 pw.println(" list libraries");
3001 pw.println(" Prints all system libraries.");
3002 pw.println("");
3003 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
Jiyong Parkf50a2932018-12-17 13:54:40 +09003004 pw.println(" [--show-versioncode] [--apex-only] [--uid UID] [--user USER_ID] [FILTER]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003005 pw.println(" Prints all packages; optionally only those whose name contains");
3006 pw.println(" the text in FILTER. Options are:");
3007 pw.println(" -f: see their associated file");
Jiyong Park4f49abe2018-12-11 13:37:17 +09003008 pw.println(" -a: all known packages (but excluding APEXes)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003009 pw.println(" -d: filter to only show disabled packages");
3010 pw.println(" -e: filter to only show enabled packages");
3011 pw.println(" -s: filter to only show system packages");
3012 pw.println(" -3: filter to only show third party packages");
3013 pw.println(" -i: see the installer for the packages");
3014 pw.println(" -l: ignored (used for compatibility with older releases)");
3015 pw.println(" -U: also show the package UID");
3016 pw.println(" -u: also include uninstalled packages");
Jiyong Parkf50a2932018-12-17 13:54:40 +09003017 pw.println(" --show-versioncode: also show the version code");
Jiyong Park4f49abe2018-12-11 13:37:17 +09003018 pw.println(" --apex-only: only show APEX packages");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003019 pw.println(" --uid UID: filter to only show packages with the given UID");
3020 pw.println(" --user USER_ID: only list packages belonging to the given user");
3021 pw.println("");
3022 pw.println(" list permission-groups");
3023 pw.println(" Prints all known permission groups.");
3024 pw.println("");
3025 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
3026 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:");
3027 pw.println(" -g: organize by group");
3028 pw.println(" -f: print all information");
3029 pw.println(" -s: short summary");
3030 pw.println(" -d: only list dangerous permissions");
3031 pw.println(" -u: list only the permissions users will see");
3032 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003033 pw.println(" resolve-activity [--brief] [--components] [--query-flags FLAGS]");
3034 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003035 pw.println(" Prints the activity that resolves to the given INTENT.");
3036 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003037 pw.println(" query-activities [--brief] [--components] [--query-flags FLAGS]");
3038 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003039 pw.println(" Prints all activities that can handle the given INTENT.");
3040 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003041 pw.println(" query-services [--brief] [--components] [--query-flags FLAGS]");
3042 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003043 pw.println(" Prints all services that can handle the given INTENT.");
3044 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003045 pw.println(" query-receivers [--brief] [--components] [--query-flags FLAGS]");
3046 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003047 pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
3048 pw.println("");
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003049 pw.println(" install [-lrtsfdgw] [-i PACKAGE] [--user USER_ID|all|current]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003050 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003051 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
3052 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003053 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
Richard Uhlerb29f1452018-09-12 16:38:15 +01003054 pw.println(" [--enable-rollback]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003055 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [--apex]");
3056 pw.println(" [PATH|-]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003057 pw.println(" Install an application. Must provide the apk data to install, either as a");
3058 pw.println(" file path or '-' to read from stdin. Options are:");
3059 pw.println(" -l: forward lock application");
Patrick Baumanna9333492017-11-28 15:23:49 -08003060 pw.println(" -R: disallow replacement of existing application");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003061 pw.println(" -t: allow test packages");
3062 pw.println(" -i: specify package name of installer owning the app");
3063 pw.println(" -s: install application on sdcard");
3064 pw.println(" -f: install application on internal flash");
3065 pw.println(" -d: allow version code downgrade (debuggable packages only)");
3066 pw.println(" -p: partial application install (new split on top of existing pkg)");
3067 pw.println(" -g: grant all runtime permissions");
3068 pw.println(" -S: size in bytes of package, required for stdin");
3069 pw.println(" --user: install under the given user.");
3070 pw.println(" --dont-kill: installing a new feature split, don't kill running app");
Svet Ganov83a3a4a2019-05-03 18:50:43 -07003071 pw.println(" --restrict-permissions: don't whitelist restricted permissions at install");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003072 pw.println(" --originating-uri: set URI where app was downloaded from");
3073 pw.println(" --referrer: set URI that instigated the install of the app");
3074 pw.println(" --pkg: specify expected package name of app being installed");
3075 pw.println(" --abi: override the default ABI of the platform");
3076 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app");
3077 pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
3078 pw.println(" --install-location: force the install location:");
3079 pw.println(" 0=auto, 1=internal only, 2=prefer external");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003080 pw.println(" --install-reason: indicates why the app is being installed:");
3081 pw.println(" 0=unknown, 1=admin policy, 2=device restore,");
3082 pw.println(" 3=device setup, 4=user request");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003083 pw.println(" --force-uuid: force install on to disk volume with given UUID");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003084 pw.println(" --apex: install an .apex file, not an .apk");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003085 pw.println("");
3086 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
3087 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003088 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
3089 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003090 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003091 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [--apex] [-S BYTES]");
Dario Freniaac4ba42018-12-06 15:47:16 +00003092 pw.println(" [--multi-package] [--staged]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003093 pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
3094 pw.println(" to push data into the session, and \"install-commit\" to finish.");
3095 pw.println("");
3096 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
3097 pw.println(" Write an apk into the given install session. If the path is '-', data");
3098 pw.println(" will be read from stdin. Options are:");
3099 pw.println(" -S: size in bytes of package, required for stdin");
3100 pw.println("");
Patrick Baumann0aff9b12018-11-08 14:05:08 +00003101 pw.println(" install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs");
3102 pw.println(" Add one or more session IDs to a multi-package session.");
3103 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003104 pw.println(" install-commit SESSION_ID");
3105 pw.println(" Commit the given active install session, installing the app.");
3106 pw.println("");
3107 pw.println(" install-abandon SESSION_ID");
3108 pw.println(" Delete the given active install session.");
3109 pw.println("");
3110 pw.println(" set-install-location LOCATION");
3111 pw.println(" Changes the default install location. NOTE this is only intended for debugging;");
3112 pw.println(" using this can cause applications to break and other undersireable behavior.");
3113 pw.println(" LOCATION is one of:");
3114 pw.println(" 0 [auto]: Let system decide the best location");
3115 pw.println(" 1 [internal]: Install on internal device storage");
3116 pw.println(" 2 [external]: Install on external media");
3117 pw.println("");
3118 pw.println(" get-install-location");
3119 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location.");
3120 pw.println("");
3121 pw.println(" move-package PACKAGE [internal|UUID]");
3122 pw.println("");
3123 pw.println(" move-primary-storage [internal|UUID]");
3124 pw.println("");
3125 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
3126 pw.println(" Remove the given package name from the system. May remove an entire app");
3127 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
3128 pw.println(" given app. Options are:");
3129 pw.println(" -k: keep the data and cache directories around after package removal.");
3130 pw.println(" --user: remove the app from the given user.");
3131 pw.println(" --versionCode: only uninstall if the app has the given version code.");
3132 pw.println("");
3133 pw.println(" clear [--user USER_ID] PACKAGE");
3134 pw.println(" Deletes all data associated with a package.");
3135 pw.println("");
3136 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT");
3137 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT");
3138 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
3139 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
3140 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
3141 pw.println(" These commands change the enabled state of a given package or");
3142 pw.println(" component (written as \"package/class\").");
3143 pw.println("");
3144 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT");
3145 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
3146 pw.println("");
3147 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
3148 pw.println(" Suspends the specified package (as user).");
3149 pw.println("");
3150 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
3151 pw.println(" Unsuspends the specified package (as user).");
3152 pw.println("");
3153 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
3154 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
3155 pw.println(" These commands either grant or revoke permissions to apps. The permissions");
3156 pw.println(" must be declared as used in the app's manifest, be runtime permissions");
3157 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
3158 pw.println("");
3159 pw.println(" reset-permissions");
3160 pw.println(" Revert all runtime permissions to their default state.");
3161 pw.println("");
3162 pw.println(" set-permission-enforced PERMISSION [true|false]");
3163 pw.println("");
3164 pw.println(" get-privapp-permissions TARGET-PACKAGE");
3165 pw.println(" Prints all privileged permissions for a package.");
3166 pw.println("");
3167 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE");
3168 pw.println(" Prints all privileged permissions that are denied for a package.");
3169 pw.println("");
3170 pw.println(" get-oem-permissions TARGET-PACKAGE");
3171 pw.println(" Prints all OEM permissions for a package.");
3172 pw.println("");
3173 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
3174 pw.println(" get-app-link [--user USER_ID] PACKAGE");
3175 pw.println("");
3176 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
3177 pw.println(" Trim cache files to reach the given free space.");
3178 pw.println("");
Felipe Leme7ad2f6b2019-09-11 09:23:26 -07003179 pw.println(" list users");
3180 pw.println(" Lists the current users.");
3181 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003182 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
Felipe Leme7ad2f6b2019-09-11 09:23:26 -07003183 pw.println(" [--guest] [--pre-create-only] USER_NAME");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003184 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
3185 pw.println(" of the user.");
3186 pw.println("");
3187 pw.println(" remove-user USER_ID");
3188 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data");
3189 pw.println(" associated with that user");
3190 pw.println("");
3191 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE");
3192 pw.println("");
3193 pw.println(" get-max-users");
3194 pw.println("");
Alex Chauc12189b2018-01-16 15:01:15 +00003195 pw.println(" get-max-running-users");
3196 pw.println("");
Calin Juravleb6f844d2017-07-17 15:23:21 -07003197 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
Richard Uhler568a9692016-05-03 16:02:52 -07003198 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003199 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
David Brazdil990fb6b2016-03-01 10:02:27 +00003200 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00003201 pw.println(" -c: clear profile data before compiling");
3202 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00003203 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07003204 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01003205 pw.println(" assume-verified");
3206 pw.println(" extract");
3207 pw.println(" verify");
3208 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07003209 pw.println(" space-profile");
3210 pw.println(" space");
3211 pw.println(" speed-profile");
3212 pw.println(" speed");
3213 pw.println(" everything");
3214 pw.println(" -r: select compilation reason");
3215 pw.println(" REASON is one of:");
3216 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
3217 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
3218 }
David Brazdilcf046952016-03-08 16:40:20 +00003219 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07003220 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08003221 pw.println(" --secondary-dex: compile app secondary dex files");
Calin Juravleb6f844d2017-07-17 15:23:21 -07003222 pw.println(" --split SPLIT: compile only the given split name");
Eric Holka1485f62019-01-07 13:58:25 -08003223 pw.println(" --compile-layouts: compile layout resources for faster inflation");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003224 pw.println("");
3225 pw.println(" force-dex-opt PACKAGE");
3226 pw.println(" Force immediate execution of dex opt for the given PACKAGE.");
3227 pw.println("");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08003228 pw.println(" bg-dexopt-job");
3229 pw.println(" Execute the background optimizations immediately.");
3230 pw.println(" Note that the command only runs the background optimizer logic. It may");
3231 pw.println(" overlap with the actual job but the job scheduler will not be able to");
3232 pw.println(" cancel it. It will also run even if the device is not in the idle");
3233 pw.println(" maintenance mode.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003234 pw.println("");
Calin Juravle1aa5f882017-01-25 01:05:50 -08003235 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
3236 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003237 pw.println("");
David Sehrcae13b02016-06-07 09:11:27 -07003238 pw.println(" dump-profiles TARGET-PACKAGE");
3239 pw.println(" Dumps method/class profile files to");
Calin Juravle21216c62018-05-04 17:35:29 -07003240 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt");
3241 pw.println("");
3242 pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]");
3243 pw.println(" Take a snapshot of the package profiles to");
3244 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
3245 + "TARGET-PACKAGE[-code-path].prof");
3246 pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003247 pw.println("");
Makoto Onuki4828a592016-03-15 18:06:57 -07003248 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003249 pw.println(" Set the default home activity (aka launcher).");
Bookatz2b5a6012019-04-16 19:41:28 -07003250 pw.println(" TARGET-COMPONENT can be a package name (com.package.my) or a full");
3251 pw.println(" component (com.package.my/component.name). However, only the package name");
3252 pw.println(" matters: the actual component used will be determined automatically from");
3253 pw.println(" the package.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003254 pw.println("");
3255 pw.println(" set-installer PACKAGE INSTALLER");
3256 pw.println(" Set installer package name");
3257 pw.println("");
3258 pw.println(" get-instantapp-resolver");
3259 pw.println(" Return the name of the component that is the current instant app installer.");
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08003260 pw.println("");
3261 pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
3262 pw.println(" Mark the app as harmful with the given warning message.");
Ben Gruver9ef60092018-01-10 11:32:30 -08003263 pw.println("");
3264 pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
3265 pw.println(" Return the harmful app warning message for the given app, if present");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003266 pw.println();
Patrick Baumanna980e142018-02-12 11:45:23 -08003267 pw.println(" uninstall-system-updates");
3268 pw.println(" Remove updates to all system applications and fall back to their /system " +
3269 "version.");
3270 pw.println();
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +01003271 pw.println(" get-moduleinfo [--all | --installed] [module-name]");
3272 pw.println(" Displays module info. If module-name is specified only that info is shown");
3273 pw.println(" By default, without any argument only installed modules are shown.");
3274 pw.println(" --all: show all module info");
3275 pw.println(" --installed: show only installed modules");
3276 pw.println("");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003277 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07003278 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003279
3280 private static class LocalIntentReceiver {
wangmingming155414292018-04-10 09:35:25 +08003281 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003282
3283 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
3284 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07003285 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003286 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
3287 try {
3288 mResult.offer(intent, 5, TimeUnit.SECONDS);
3289 } catch (InterruptedException e) {
3290 throw new RuntimeException(e);
3291 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003292 }
3293 };
3294
3295 public IntentSender getIntentSender() {
3296 return new IntentSender((IIntentSender) mLocalSender);
3297 }
3298
3299 public Intent getResult() {
3300 try {
3301 return mResult.take();
3302 } catch (InterruptedException e) {
3303 throw new RuntimeException(e);
3304 }
3305 }
3306 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07003307}