blob: e8090e356bf76c66bfb324d0cef9cda895b360a6 [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;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070090import android.permission.IPermissionManager;
Calin Juravlebdd94d92018-05-17 01:23:15 -070091import android.system.ErrnoException;
92import android.system.Os;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080093import android.text.TextUtils;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070094import android.text.format.DateUtils;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080095import android.util.ArraySet;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080096import android.util.PrintWriterPrinter;
Dario Freni2bef1762018-06-01 14:02:08 +010097
Shunta Sato4f26cb52016-06-28 09:29:19 +090098import com.android.internal.content.PackageHelper;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070099import com.android.internal.util.ArrayUtils;
Alex Chauc12189b2018-01-16 15:01:15 +0000100import com.android.server.LocalServices;
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800101import com.android.server.SystemConfig;
Dario Freni2bef1762018-06-01 14:02:08 +0100102
Andreas Gampebdd30d82016-03-20 11:32:11 -0700103import dalvik.system.DexFile;
Dario Freni2bef1762018-06-01 14:02:08 +0100104
105import libcore.io.IoUtils;
106import libcore.io.Streams;
107
Calin Juravle21216c62018-05-04 17:35:29 -0700108import java.io.File;
109import java.io.FileOutputStream;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800110import java.io.IOException;
Calin Juravle21216c62018-05-04 17:35:29 -0700111import java.io.InputStream;
112import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700113import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800114import java.net.URISyntaxException;
Calin Juravle21216c62018-05-04 17:35:29 -0700115import java.util.ArrayList;
116import java.util.Collections;
117import java.util.Comparator;
118import java.util.LinkedList;
119import java.util.List;
120import java.util.Map;
121import java.util.Objects;
122import java.util.WeakHashMap;
Bookatz2b5a6012019-04-16 19:41:28 -0700123import java.util.concurrent.CompletableFuture;
Calin Juravle21216c62018-05-04 17:35:29 -0700124import java.util.concurrent.CountDownLatch;
wangmingming155414292018-04-10 09:35:25 +0800125import java.util.concurrent.LinkedBlockingQueue;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800126import java.util.concurrent.TimeUnit;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700127
128class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700129 /** Path for streaming APK content */
130 private static final String STDIN_PATH = "-";
Calin Juravle21216c62018-05-04 17:35:29 -0700131 /** Path where ART profiles snapshots are dumped for the shell user */
132 private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
Mohammad Samiul Islambd02f422019-05-17 18:02:12 +0100133 private static final int DEFAULT_WAIT_MS = 60 * 1000;
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700134
Todd Kennedy60459ab2015-10-30 11:32:16 -0700135 final IPackageManager mInterface;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700136 final IPermissionManager mPermissionManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700137 final private WeakHashMap<String, Resources> mResourceCache =
138 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800139 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700140 boolean mBrief;
141 boolean mComponents;
Ng Zhi An73971312018-09-11 21:39:14 -0700142 int mQueryFlags;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700143
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700144 PackageManagerShellCommand(
145 PackageManagerService service, IPermissionManager permissionManager) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700146 mInterface = service;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700147 mPermissionManager = permissionManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700148 }
149
150 @Override
151 public int onCommand(String cmd) {
152 if (cmd == null) {
153 return handleDefaultCommands(cmd);
154 }
155
156 final PrintWriter pw = getOutPrintWriter();
157 try {
158 switch(cmd) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700159 case "path":
160 return runPath();
161 case "dump":
162 return runDump();
163 case "list":
164 return runList();
165 case "resolve-activity":
166 return runResolveActivity();
167 case "query-activities":
168 return runQueryIntentActivities();
169 case "query-services":
170 return runQueryIntentServices();
171 case "query-receivers":
172 return runQueryIntentReceivers();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800173 case "install":
174 return runInstall();
175 case "install-abandon":
176 case "install-destroy":
177 return runInstallAbandon();
178 case "install-commit":
179 return runInstallCommit();
180 case "install-create":
181 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800182 case "install-remove":
183 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800184 case "install-write":
185 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800186 case "install-existing":
187 return runInstallExisting();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700188 case "set-install-location":
189 return runSetInstallLocation();
190 case "get-install-location":
191 return runGetInstallLocation();
Patrick Baumann0aff9b12018-11-08 14:05:08 +0000192 case "install-add-session":
193 return runInstallAddSession();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700194 case "move-package":
195 return runMovePackage();
196 case "move-primary-storage":
197 return runMovePrimaryStorage();
David Brazdil493411a2016-02-01 13:48:46 +0000198 case "compile":
199 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800200 case "reconcile-secondary-dex-files":
201 return runreconcileSecondaryDexFiles();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700202 case "force-dex-opt":
203 return runForceDexOpt();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800204 case "bg-dexopt-job":
205 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700206 case "dump-profiles":
207 return runDumpProfiles();
Calin Juravle21216c62018-05-04 17:35:29 -0700208 case "snapshot-profile":
209 return runSnapshotProfile();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800210 case "uninstall":
211 return runUninstall();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700212 case "clear":
213 return runClear();
214 case "enable":
215 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
216 case "disable":
217 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
218 case "disable-user":
219 return runSetEnabledSetting(
220 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
221 case "disable-until-used":
222 return runSetEnabledSetting(
223 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
224 case "default-state":
225 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
226 case "hide":
227 return runSetHiddenSetting(true);
228 case "unhide":
229 return runSetHiddenSetting(false);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000230 case "suspend":
231 return runSuspend(true);
232 case "unsuspend":
233 return runSuspend(false);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700234 case "grant":
235 return runGrantRevokePermission(true);
236 case "revoke":
237 return runGrantRevokePermission(false);
238 case "reset-permissions":
239 return runResetPermissions();
240 case "set-permission-enforced":
241 return runSetPermissionEnforced();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800242 case "get-privapp-permissions":
243 return runGetPrivappPermissions();
Todd Kennedy74629e32017-08-15 14:48:07 -0700244 case "get-privapp-deny-permissions":
245 return runGetPrivappDenyPermissions();
Svet Ganov087dce22017-09-07 15:42:16 -0700246 case "get-oem-permissions":
247 return runGetOemPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700248 case "set-app-link":
249 return runSetAppLink();
250 case "get-app-link":
251 return runGetAppLink();
252 case "trim-caches":
253 return runTrimCaches();
254 case "create-user":
255 return runCreateUser();
256 case "remove-user":
257 return runRemoveUser();
258 case "set-user-restriction":
259 return runSetUserRestriction();
260 case "get-max-users":
261 return runGetMaxUsers();
Alex Chauc12189b2018-01-16 15:01:15 +0000262 case "get-max-running-users":
263 return runGetMaxRunningUsers();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700264 case "set-home-activity":
265 return runSetHomeActivity();
266 case "set-installer":
267 return runSetInstaller();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700268 case "get-instantapp-resolver":
269 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900270 case "has-feature":
271 return runHasFeature();
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800272 case "set-harmful-app-warning":
273 return runSetHarmfulAppWarning();
Ben Gruver9ef60092018-01-10 11:32:30 -0800274 case "get-harmful-app-warning":
275 return runGetHarmfulAppWarning();
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000276 case "get-stagedsessions":
277 return getStagedSessions();
Patrick Baumanna980e142018-02-12 11:45:23 -0800278 case "uninstall-system-updates":
279 return uninstallSystemUpdates();
Narayan Kamathc5d752e2019-01-23 14:06:35 +0000280 case "rollback-app":
281 return runRollbackApp();
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +0100282 case "get-moduleinfo":
283 return runGetModuleInfo();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700284 default: {
285 String nextArg = getNextArg();
286 if (nextArg == null) {
287 if (cmd.equalsIgnoreCase("-l")) {
288 return runListPackages(false);
289 } else if (cmd.equalsIgnoreCase("-lf")) {
290 return runListPackages(true);
291 }
292 } else if (getNextArg() == null) {
293 if (cmd.equalsIgnoreCase("-p")) {
294 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
295 }
296 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700297 return handleDefaultCommands(cmd);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700298 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700299 }
300 } catch (RemoteException e) {
301 pw.println("Remote exception: " + e);
302 }
303 return -1;
304 }
305
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +0100306 /**
307 * Shows module info
308 *
309 * Usage: get-moduleinfo [--all | --installed] [module-name]
310 * Example: get-moduleinfo, get-moduleinfo --all, get-moduleinfo xyz
311 */
312 private int runGetModuleInfo() {
313 final PrintWriter pw = getOutPrintWriter();
314 int flags = 0;
315
316 String opt;
317 while ((opt = getNextOption()) != null) {
318 switch (opt) {
319 case "--all":
320 flags |= PackageManager.MATCH_ALL;
321 break;
322 case "--installed":
323 break;
324 default:
325 pw.println("Error: Unknown option: " + opt);
326 return -1;
327 }
328 }
329
330 String moduleName = getNextArg();
331 try {
332 if (moduleName != null) {
333 ModuleInfo m = mInterface.getModuleInfo(moduleName, flags);
334 pw.println(m.toString() + " packageName: " + m.getPackageName());
335
336 } else {
337 List<ModuleInfo> modules = mInterface.getInstalledModules(flags);
338 for (ModuleInfo m: modules) {
339 pw.println(m.toString() + " packageName: " + m.getPackageName());
340 }
341 }
342 } catch (RemoteException e) {
343 pw.println("Failure [" + e.getClass().getName() + " - " + e.getMessage() + "]");
344 return -1;
345 }
346 return 1;
347 }
348
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000349 private int getStagedSessions() {
350 final PrintWriter pw = getOutPrintWriter();
351 try {
352 List<SessionInfo> stagedSessionsList =
353 mInterface.getPackageInstaller().getStagedSessions().getList();
354 for (SessionInfo session: stagedSessionsList) {
355 pw.println("appPackageName = " + session.getAppPackageName()
356 + "; sessionId = " + session.getSessionId()
357 + "; isStaged = " + session.isStaged()
Dario Freni60a96c12019-02-24 21:01:29 +0000358 + "; isStagedSessionReady = " + session.isStagedSessionReady()
359 + "; isStagedSessionApplied = " + session.isStagedSessionApplied()
360 + "; isStagedSessionFailed = " + session.isStagedSessionFailed() + ";");
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000361 }
362 } catch (RemoteException e) {
363 pw.println("Failure ["
364 + e.getClass().getName() + " - "
365 + e.getMessage() + "]");
366 return 0;
367 }
368 return 1;
369 }
370
Patrick Baumanna980e142018-02-12 11:45:23 -0800371 private int uninstallSystemUpdates() {
372 final PrintWriter pw = getOutPrintWriter();
373 List<String> failedUninstalls = new LinkedList<>();
374 try {
375 final ParceledListSlice<ApplicationInfo> packages =
376 mInterface.getInstalledApplications(
377 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
378 final IPackageInstaller installer = mInterface.getPackageInstaller();
379 List<ApplicationInfo> list = packages.getList();
380 for (ApplicationInfo info : list) {
381 if (info.isUpdatedSystemApp()) {
382 pw.println("Uninstalling updates to " + info.packageName + "...");
383 final LocalIntentReceiver receiver = new LocalIntentReceiver();
384 installer.uninstall(new VersionedPackage(info.packageName,
385 info.versionCode), null /*callerPackageName*/, 0 /* flags */,
386 receiver.getIntentSender(), 0);
387
388 final Intent result = receiver.getResult();
389 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
390 PackageInstaller.STATUS_FAILURE);
391 if (status != PackageInstaller.STATUS_SUCCESS) {
392 failedUninstalls.add(info.packageName);
393 }
394 }
395 }
396 } catch (RemoteException e) {
397 pw.println("Failure ["
398 + e.getClass().getName() + " - "
399 + e.getMessage() + "]");
400 return 0;
401 }
402 if (!failedUninstalls.isEmpty()) {
403 pw.println("Failure [Couldn't uninstall packages: "
404 + TextUtils.join(", ", failedUninstalls)
405 + "]");
406 return 0;
407 }
408 pw.println("Success");
409 return 1;
410 }
411
Narayan Kamathc5d752e2019-01-23 14:06:35 +0000412 private int runRollbackApp() {
413 final PrintWriter pw = getOutPrintWriter();
414
415 final String packageName = getNextArgRequired();
416 if (packageName == null) {
417 pw.println("Error: package name not specified");
418 return 1;
419 }
420
421 final LocalIntentReceiver receiver = new LocalIntentReceiver();
422 try {
423 IRollbackManager rm = IRollbackManager.Stub.asInterface(
424 ServiceManager.getService(Context.ROLLBACK_SERVICE));
425
426 RollbackInfo rollback = null;
427 for (RollbackInfo r : (List<RollbackInfo>) rm.getAvailableRollbacks().getList()) {
428 for (PackageRollbackInfo info : r.getPackages()) {
429 if (packageName.equals(info.getPackageName())) {
430 rollback = r;
431 break;
432 }
433 }
434 }
435
436 if (rollback == null) {
437 pw.println("No available rollbacks for: " + packageName);
438 return 1;
439 }
440
441 rm.commitRollback(rollback.getRollbackId(),
442 ParceledListSlice.<VersionedPackage>emptyList(),
443 "com.android.shell", receiver.getIntentSender());
444 } catch (RemoteException re) {
445 // Cannot happen.
446 }
447
448 final Intent result = receiver.getResult();
449 final int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
450 RollbackManager.STATUS_FAILURE);
451 if (status == RollbackManager.STATUS_SUCCESS) {
452 pw.println("Success");
453 return 0;
454 } else {
455 pw.println("Failure ["
456 + result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE) + "]");
457 return 1;
458 }
459 }
460
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700461 private void setParamsSize(InstallParams params, String inPath) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700462 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700463 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
464 if (fd == null) {
465 getErrPrintWriter().println("Error: Can't open file: " + inPath);
466 throw new IllegalArgumentException("Error: Can't open file: " + inPath);
467 }
468 try {
469 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
470 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
471 null, null);
472 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
Dianne Hackborn1704e3c2017-10-31 19:55:42 +0000473 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700474 } catch (PackageParserException | IOException e) {
475 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
476 throw new IllegalArgumentException(
477 "Error: Failed to parse APK file: " + inPath, e);
478 } finally {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900479 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700480 fd.close();
481 } catch (IOException e) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900482 }
483 }
484 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700485 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700486 /**
487 * Displays the package file for a package.
488 * @param pckg
489 */
490 private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
491 PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId);
492 if (info != null && info.applicationInfo != null) {
493 final PrintWriter pw = getOutPrintWriter();
494 pw.print("package:");
495 pw.println(info.applicationInfo.sourceDir);
496 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
497 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
498 pw.print("package:");
499 pw.println(splitSourceDir);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800500 }
501 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700502 return 0;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800503 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700504 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800505 }
506
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700507 private int runPath() throws RemoteException {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000508 int userId = UserHandle.USER_SYSTEM;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700509 String option = getNextOption();
510 if (option != null && option.equals("--user")) {
511 userId = UserHandle.parseUserArg(getNextArgRequired());
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000512 }
513
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700514 String pkg = getNextArgRequired();
515 if (pkg == null) {
516 getErrPrintWriter().println("Error: no package specified");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000517 return 1;
518 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700519 return displayPackageFilePath(pkg, userId);
David Sehra8777082016-05-24 15:25:23 -0700520 }
521
Todd Kennedy60459ab2015-10-30 11:32:16 -0700522 private int runList() throws RemoteException {
523 final PrintWriter pw = getOutPrintWriter();
524 final String type = getNextArg();
525 if (type == null) {
526 pw.println("Error: didn't specify type of data to list");
527 return -1;
528 }
529 switch(type) {
530 case "features":
531 return runListFeatures();
532 case "instrumentation":
533 return runListInstrumentation();
534 case "libraries":
535 return runListLibraries();
536 case "package":
537 case "packages":
538 return runListPackages(false /*showSourceDir*/);
539 case "permission-groups":
540 return runListPermissionGroups();
541 case "permissions":
542 return runListPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700543 case "users":
544 ServiceManager.getService("user").shellCommand(
545 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
546 new String[] { "list" }, getShellCallback(), adoptResultReceiver());
547 return 0;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700548 }
549 pw.println("Error: unknown list type '" + type + "'");
550 return -1;
551 }
552
553 private int runListFeatures() throws RemoteException {
554 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700555 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700556
557 // sort by name
558 Collections.sort(list, new Comparator<FeatureInfo>() {
559 public int compare(FeatureInfo o1, FeatureInfo o2) {
560 if (o1.name == o2.name) return 0;
561 if (o1.name == null) return -1;
562 if (o2.name == null) return 1;
563 return o1.name.compareTo(o2.name);
564 }
565 });
566
567 final int count = (list != null) ? list.size() : 0;
568 for (int p = 0; p < count; p++) {
569 FeatureInfo fi = list.get(p);
570 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700571 if (fi.name != null) {
572 pw.print(fi.name);
573 if (fi.version > 0) {
574 pw.print("=");
575 pw.print(fi.version);
576 }
577 pw.println();
578 } else {
579 pw.println("reqGlEsVersion=0x"
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700580 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700581 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700582 }
583 return 0;
584 }
585
586 private int runListInstrumentation() throws RemoteException {
587 final PrintWriter pw = getOutPrintWriter();
588 boolean showSourceDir = false;
589 String targetPackage = null;
590
591 try {
592 String opt;
593 while ((opt = getNextArg()) != null) {
594 switch (opt) {
595 case "-f":
596 showSourceDir = true;
597 break;
598 default:
599 if (opt.charAt(0) != '-') {
600 targetPackage = opt;
601 } else {
602 pw.println("Error: Unknown option: " + opt);
603 return -1;
604 }
605 break;
606 }
607 }
608 } catch (RuntimeException ex) {
609 pw.println("Error: " + ex.toString());
610 return -1;
611 }
612
613 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700614 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700615
616 // sort by target package
617 Collections.sort(list, new Comparator<InstrumentationInfo>() {
618 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
619 return o1.targetPackage.compareTo(o2.targetPackage);
620 }
621 });
622
623 final int count = (list != null) ? list.size() : 0;
624 for (int p = 0; p < count; p++) {
625 final InstrumentationInfo ii = list.get(p);
626 pw.print("instrumentation:");
627 if (showSourceDir) {
628 pw.print(ii.sourceDir);
629 pw.print("=");
630 }
631 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
632 pw.print(cn.flattenToShortString());
633 pw.print(" (target=");
634 pw.print(ii.targetPackage);
635 pw.println(")");
636 }
637 return 0;
638 }
639
640 private int runListLibraries() throws RemoteException {
641 final PrintWriter pw = getOutPrintWriter();
642 final List<String> list = new ArrayList<String>();
643 final String[] rawList = mInterface.getSystemSharedLibraryNames();
644 for (int i = 0; i < rawList.length; i++) {
645 list.add(rawList[i]);
646 }
647
648 // sort by name
649 Collections.sort(list, new Comparator<String>() {
650 public int compare(String o1, String o2) {
651 if (o1 == o2) return 0;
652 if (o1 == null) return -1;
653 if (o2 == null) return 1;
654 return o1.compareTo(o2);
655 }
656 });
657
658 final int count = (list != null) ? list.size() : 0;
659 for (int p = 0; p < count; p++) {
660 String lib = list.get(p);
661 pw.print("library:");
662 pw.println(lib);
663 }
664 return 0;
665 }
666
667 private int runListPackages(boolean showSourceDir) throws RemoteException {
668 final PrintWriter pw = getOutPrintWriter();
669 int getFlags = 0;
670 boolean listDisabled = false, listEnabled = false;
671 boolean listSystem = false, listThirdParty = false;
672 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700673 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800674 boolean showVersionCode = false;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900675 boolean listApexOnly = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700676 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700677 int userId = UserHandle.USER_SYSTEM;
678 try {
679 String opt;
680 while ((opt = getNextOption()) != null) {
681 switch (opt) {
682 case "-d":
683 listDisabled = true;
684 break;
685 case "-e":
686 listEnabled = true;
687 break;
Andreas Gampe1f110452018-06-04 11:47:48 -0700688 case "-a":
689 getFlags |= PackageManager.MATCH_KNOWN_PACKAGES;
690 getFlags |= PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
691 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700692 case "-f":
693 showSourceDir = true;
694 break;
695 case "-i":
696 listInstaller = true;
697 break;
698 case "-l":
699 // old compat
700 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700701 case "-s":
702 listSystem = true;
703 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700704 case "-U":
705 showUid = true;
706 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700707 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700708 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700709 break;
710 case "-3":
711 listThirdParty = true;
712 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800713 case "--show-versioncode":
714 showVersionCode = true;
715 break;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900716 case "--apex-only":
717 getFlags |= PackageManager.MATCH_APEX;
718 listApexOnly = true;
719 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700720 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800721 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700722 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700723 case "--uid":
724 showUid = true;
725 uid = Integer.parseInt(getNextArgRequired());
726 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700727 default:
728 pw.println("Error: Unknown option: " + opt);
729 return -1;
730 }
731 }
732 } catch (RuntimeException ex) {
733 pw.println("Error: " + ex.toString());
734 return -1;
735 }
736
737 final String filter = getNextArg();
738
739 @SuppressWarnings("unchecked")
740 final ParceledListSlice<PackageInfo> slice =
741 mInterface.getInstalledPackages(getFlags, userId);
742 final List<PackageInfo> packages = slice.getList();
743
744 final int count = packages.size();
745 for (int p = 0; p < count; p++) {
746 final PackageInfo info = packages.get(p);
747 if (filter != null && !info.packageName.contains(filter)) {
748 continue;
749 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900750 final boolean isApex = info.isApex;
751 if (uid != -1 && !isApex && info.applicationInfo.uid != uid) {
Felipe Lemeeece9862016-06-29 11:45:03 -0700752 continue;
753 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900754
755 final boolean isSystem = !isApex &&
Todd Kennedy60459ab2015-10-30 11:32:16 -0700756 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900757 final boolean isEnabled = !isApex && info.applicationInfo.enabled;
758 if ((!listDisabled || !isEnabled) &&
759 (!listEnabled || isEnabled) &&
Todd Kennedy60459ab2015-10-30 11:32:16 -0700760 (!listSystem || isSystem) &&
Jiyong Park4f49abe2018-12-11 13:37:17 +0900761 (!listThirdParty || !isSystem) &&
762 (!listApexOnly || isApex)) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700763 pw.print("package:");
Jiyong Park4f49abe2018-12-11 13:37:17 +0900764 if (showSourceDir && !isApex) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700765 pw.print(info.applicationInfo.sourceDir);
766 pw.print("=");
767 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800768 pw.print(info.packageName);
Jiyong Parkf50a2932018-12-17 13:54:40 +0900769 if (showVersionCode) {
Todd Kennedybadc69a2017-01-24 11:05:47 -0800770 pw.print(" versionCode:");
Jiyong Parkf50a2932018-12-17 13:54:40 +0900771 if (info.applicationInfo != null) {
Dario Freni788ecb12019-01-23 18:49:32 +0000772 pw.print(info.applicationInfo.longVersionCode);
Jiyong Parkf50a2932018-12-17 13:54:40 +0900773 } else {
Dario Freni788ecb12019-01-23 18:49:32 +0000774 pw.print(info.getLongVersionCode());
Jiyong Parkf50a2932018-12-17 13:54:40 +0900775 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800776 }
Mohammad Samiul Islam6b7ad942019-05-07 20:28:00 +0100777 if (listInstaller) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700778 pw.print(" installer=");
779 pw.print(mInterface.getInstallerPackageName(info.packageName));
780 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900781 if (showUid && !isApex) {
Felipe Lemeeece9862016-06-29 11:45:03 -0700782 pw.print(" uid:");
783 pw.print(info.applicationInfo.uid);
784 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700785 pw.println();
786 }
787 }
788 return 0;
789 }
790
791 private int runListPermissionGroups() throws RemoteException {
792 final PrintWriter pw = getOutPrintWriter();
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700793 final List<PermissionGroupInfo> pgs =
794 mPermissionManager.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700795
796 final int count = pgs.size();
797 for (int p = 0; p < count ; p++) {
798 final PermissionGroupInfo pgi = pgs.get(p);
799 pw.print("permission group:");
800 pw.println(pgi.name);
801 }
802 return 0;
803 }
804
805 private int runListPermissions() throws RemoteException {
806 final PrintWriter pw = getOutPrintWriter();
807 boolean labels = false;
808 boolean groups = false;
809 boolean userOnly = false;
810 boolean summary = false;
811 boolean dangerousOnly = false;
812 String opt;
813 while ((opt = getNextOption()) != null) {
814 switch (opt) {
815 case "-d":
816 dangerousOnly = true;
817 break;
818 case "-f":
819 labels = true;
820 break;
821 case "-g":
822 groups = true;
823 break;
824 case "-s":
825 groups = true;
826 labels = true;
827 summary = true;
828 break;
829 case "-u":
830 userOnly = true;
831 break;
832 default:
833 pw.println("Error: Unknown option: " + opt);
834 return 1;
835 }
836 }
837
838 final ArrayList<String> groupList = new ArrayList<String>();
839 if (groups) {
840 final List<PermissionGroupInfo> infos =
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700841 mPermissionManager.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700842 final int count = infos.size();
843 for (int i = 0; i < count; i++) {
844 groupList.add(infos.get(i).name);
845 }
846 groupList.add(null);
847 } else {
848 final String grp = getNextArg();
849 groupList.add(grp);
850 }
851
852 if (dangerousOnly) {
853 pw.println("Dangerous Permissions:");
854 pw.println("");
855 doListPermissions(groupList, groups, labels, summary,
856 PermissionInfo.PROTECTION_DANGEROUS,
857 PermissionInfo.PROTECTION_DANGEROUS);
858 if (userOnly) {
859 pw.println("Normal Permissions:");
860 pw.println("");
861 doListPermissions(groupList, groups, labels, summary,
862 PermissionInfo.PROTECTION_NORMAL,
863 PermissionInfo.PROTECTION_NORMAL);
864 }
865 } else if (userOnly) {
866 pw.println("Dangerous and Normal Permissions:");
867 pw.println("");
868 doListPermissions(groupList, groups, labels, summary,
869 PermissionInfo.PROTECTION_NORMAL,
870 PermissionInfo.PROTECTION_DANGEROUS);
871 } else {
872 pw.println("All Permissions:");
873 pw.println("");
874 doListPermissions(groupList, groups, labels, summary,
875 -10000, 10000);
876 }
877 return 0;
878 }
879
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800880 private Intent parseIntentAndUser() throws URISyntaxException {
881 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700882 mBrief = false;
883 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800884 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
885 @Override
886 public boolean handleOption(String opt, ShellCommand cmd) {
887 if ("--user".equals(opt)) {
888 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
889 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700890 } else if ("--brief".equals(opt)) {
891 mBrief = true;
892 return true;
893 } else if ("--components".equals(opt)) {
894 mComponents = true;
895 return true;
Ng Zhi An73971312018-09-11 21:39:14 -0700896 } else if ("--query-flags".equals(opt)) {
897 mQueryFlags = Integer.decode(cmd.getNextArgRequired());
898 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800899 }
900 return false;
901 }
902 });
903 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
904 Binder.getCallingUid(), mTargetUser, false, false, null, null);
905 return intent;
906 }
907
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700908 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
909 boolean brief, boolean components) {
910 if (brief || components) {
911 final ComponentName comp;
912 if (ri.activityInfo != null) {
913 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
914 } else if (ri.serviceInfo != null) {
915 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
916 } else if (ri.providerInfo != null) {
917 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
918 } else {
919 comp = null;
920 }
921 if (comp != null) {
922 if (!components) {
923 pr.println(prefix + "priority=" + ri.priority
924 + " preferredOrder=" + ri.preferredOrder
925 + " match=0x" + Integer.toHexString(ri.match)
926 + " specificIndex=" + ri.specificIndex
927 + " isDefault=" + ri.isDefault);
928 }
929 pr.println(prefix + comp.flattenToShortString());
930 return;
931 }
932 }
933 ri.dump(pr, prefix);
934 }
935
Dianne Hackborn99878e92015-12-02 16:27:41 -0800936 private int runResolveActivity() {
937 Intent intent;
938 try {
939 intent = parseIntentAndUser();
940 } catch (URISyntaxException e) {
941 throw new RuntimeException(e.getMessage(), e);
942 }
943 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700944 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), mQueryFlags,
945 mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800946 PrintWriter pw = getOutPrintWriter();
947 if (ri == null) {
948 pw.println("No activity found");
949 } else {
950 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700951 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800952 }
953 } catch (RemoteException e) {
954 throw new RuntimeException("Failed calling service", e);
955 }
956 return 0;
957 }
958
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800959 private int runQueryIntentActivities() {
960 Intent intent;
961 try {
962 intent = parseIntentAndUser();
963 } catch (URISyntaxException e) {
964 throw new RuntimeException(e.getMessage(), e);
965 }
966 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700967 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(),
968 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800969 PrintWriter pw = getOutPrintWriter();
970 if (result == null || result.size() <= 0) {
971 pw.println("No activities found");
972 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700973 if (!mComponents) {
974 pw.print(result.size()); pw.println(" activities found:");
975 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
976 for (int i = 0; i < result.size(); i++) {
977 pw.print(" Activity #"); pw.print(i); pw.println(":");
978 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
979 }
980 } else {
981 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
982 for (int i = 0; i < result.size(); i++) {
983 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
984 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800985 }
986 }
987 } catch (RemoteException e) {
988 throw new RuntimeException("Failed calling service", e);
989 }
990 return 0;
991 }
992
993 private int runQueryIntentServices() {
994 Intent intent;
995 try {
996 intent = parseIntentAndUser();
997 } catch (URISyntaxException e) {
998 throw new RuntimeException(e.getMessage(), e);
999 }
1000 try {
Ng Zhi An73971312018-09-11 21:39:14 -07001001 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(),
1002 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001003 PrintWriter pw = getOutPrintWriter();
1004 if (result == null || result.size() <= 0) {
1005 pw.println("No services found");
1006 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001007 if (!mComponents) {
1008 pw.print(result.size()); pw.println(" services found:");
1009 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1010 for (int i = 0; i < result.size(); i++) {
1011 pw.print(" Service #"); pw.print(i); pw.println(":");
1012 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1013 }
1014 } else {
1015 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1016 for (int i = 0; i < result.size(); i++) {
1017 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1018 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001019 }
1020 }
1021 } catch (RemoteException e) {
1022 throw new RuntimeException("Failed calling service", e);
1023 }
1024 return 0;
1025 }
1026
1027 private int runQueryIntentReceivers() {
1028 Intent intent;
1029 try {
1030 intent = parseIntentAndUser();
1031 } catch (URISyntaxException e) {
1032 throw new RuntimeException(e.getMessage(), e);
1033 }
1034 try {
Ng Zhi An73971312018-09-11 21:39:14 -07001035 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(),
1036 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001037 PrintWriter pw = getOutPrintWriter();
1038 if (result == null || result.size() <= 0) {
1039 pw.println("No receivers found");
1040 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -07001041 if (!mComponents) {
1042 pw.print(result.size()); pw.println(" receivers found:");
1043 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1044 for (int i = 0; i < result.size(); i++) {
1045 pw.print(" Receiver #"); pw.print(i); pw.println(":");
1046 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
1047 }
1048 } else {
1049 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
1050 for (int i = 0; i < result.size(); i++) {
1051 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
1052 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001053 }
1054 }
1055 } catch (RemoteException e) {
1056 throw new RuntimeException("Failed calling service", e);
1057 }
1058 return 0;
1059 }
1060
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001061 private int runInstall() throws RemoteException {
1062 final PrintWriter pw = getOutPrintWriter();
1063 final InstallParams params = makeInstallParams();
1064 final String inPath = getNextArg();
1065
1066 setParamsSize(params, inPath);
1067 final int sessionId = doCreateSession(params.sessionParams,
1068 params.installerPackageName, params.userId);
1069 boolean abandonSession = true;
1070 try {
1071 if (inPath == null && params.sessionParams.sizeBytes == -1) {
1072 pw.println("Error: must either specify a package size or an APK file");
1073 return 1;
1074 }
Dario Frenid8bf22e2018-08-31 14:18:04 +01001075 final boolean isApex =
1076 (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
1077 String splitName = "base." + (isApex ? "apex" : "apk");
1078 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001079 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
1080 return 1;
1081 }
1082 if (doCommitSession(sessionId, false /*logSuccess*/)
1083 != PackageInstaller.STATUS_SUCCESS) {
1084 return 1;
1085 }
1086 abandonSession = false;
Mohammad Samiul Islambd02f422019-05-17 18:02:12 +01001087
1088 if (!params.sessionParams.isStaged || !params.waitForStagedSessionReady) {
1089 pw.println("Success");
1090 return 0;
1091 }
1092
1093 long timeoutMs = params.timeoutMs <= 0
1094 ? DEFAULT_WAIT_MS
1095 : params.timeoutMs;
1096 PackageInstaller.SessionInfo si = mInterface.getPackageInstaller()
1097 .getSessionInfo(sessionId);
1098 long currentTime = System.currentTimeMillis();
1099 long endTime = currentTime + timeoutMs;
1100 // Using a loop instead of BroadcastReceiver since we can receive session update
1101 // broadcast only if packageInstallerName is "android". We can't always force
1102 // "android" as packageIntallerName, e.g, rollback auto implies
1103 // "-i com.android.shell".
1104 while (currentTime < endTime) {
1105 if (si != null
1106 && (si.isStagedSessionReady() || si.isStagedSessionFailed())) {
1107 break;
1108 }
1109 SystemClock.sleep(Math.min(endTime - currentTime, 100));
1110 currentTime = System.currentTimeMillis();
1111 si = mInterface.getPackageInstaller().getSessionInfo(sessionId);
1112 }
1113 if (si == null) {
1114 pw.println("Failure [failed to retrieve SessionInfo]");
1115 return 1;
1116 }
1117 if (!si.isStagedSessionReady() && !si.isStagedSessionFailed()) {
1118 pw.println("Failure [timed out after " + timeoutMs + " ms]");
1119 return 1;
1120 }
1121 if (!si.isStagedSessionReady()) {
1122 pw.println("Error [" + si.getStagedSessionErrorCode() + "] ["
1123 + si.getStagedSessionErrorMessage() + "]");
1124 return 1;
1125 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001126 pw.println("Success");
1127 return 0;
1128 } finally {
1129 if (abandonSession) {
1130 try {
1131 doAbandonSession(sessionId, false /*logSuccess*/);
1132 } catch (Exception ignore) {
1133 }
1134 }
1135 }
1136 }
1137
1138 private int runInstallAbandon() throws RemoteException {
1139 final int sessionId = Integer.parseInt(getNextArg());
1140 return doAbandonSession(sessionId, true /*logSuccess*/);
1141 }
1142
1143 private int runInstallCommit() throws RemoteException {
1144 final int sessionId = Integer.parseInt(getNextArg());
1145 return doCommitSession(sessionId, true /*logSuccess*/);
1146 }
1147
1148 private int runInstallCreate() throws RemoteException {
1149 final PrintWriter pw = getOutPrintWriter();
1150 final InstallParams installParams = makeInstallParams();
1151 final int sessionId = doCreateSession(installParams.sessionParams,
1152 installParams.installerPackageName, installParams.userId);
1153
1154 // NOTE: adb depends on parsing this string
1155 pw.println("Success: created install session [" + sessionId + "]");
1156 return 0;
1157 }
1158
1159 private int runInstallWrite() throws RemoteException {
1160 long sizeBytes = -1;
1161
1162 String opt;
1163 while ((opt = getNextOption()) != null) {
1164 if (opt.equals("-S")) {
1165 sizeBytes = Long.parseLong(getNextArg());
1166 } else {
1167 throw new IllegalArgumentException("Unknown option: " + opt);
1168 }
1169 }
1170
1171 final int sessionId = Integer.parseInt(getNextArg());
1172 final String splitName = getNextArg();
1173 final String path = getNextArg();
1174 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
1175 }
1176
Patrick Baumann0aff9b12018-11-08 14:05:08 +00001177 private int runInstallAddSession() throws RemoteException {
1178 final PrintWriter pw = getOutPrintWriter();
1179 final int parentSessionId = Integer.parseInt(getNextArg());
1180
1181 List<Integer> otherSessionIds = new ArrayList<>();
1182 String opt;
1183 while ((opt = getNextArg()) != null) {
1184 otherSessionIds.add(Integer.parseInt(opt));
1185 }
1186 if (otherSessionIds.size() == 0) {
1187 pw.println("Error: At least two sessions are required.");
1188 return 1;
1189 }
1190 return doInstallAddSession(parentSessionId, ArrayUtils.convertToIntArray(otherSessionIds),
1191 true /*logSuccess*/);
1192 }
1193
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001194 private int runInstallRemove() throws RemoteException {
1195 final PrintWriter pw = getOutPrintWriter();
1196
1197 final int sessionId = Integer.parseInt(getNextArg());
1198
1199 final String splitName = getNextArg();
1200 if (splitName == null) {
1201 pw.println("Error: split name not specified");
1202 return 1;
1203 }
1204 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
1205 }
1206
1207 private int runInstallExisting() throws RemoteException {
1208 final PrintWriter pw = getOutPrintWriter();
1209 int userId = UserHandle.USER_SYSTEM;
Philip P. Moltmannbfcffa02019-05-13 17:10:46 -07001210 int installFlags = PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001211 String opt;
Chandan Nathe8e463b2019-01-28 15:23:38 +00001212 boolean waitTillComplete = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001213 while ((opt = getNextOption()) != null) {
1214 switch (opt) {
1215 case "--user":
1216 userId = UserHandle.parseUserArg(getNextArgRequired());
1217 break;
1218 case "--ephemeral":
1219 case "--instant":
1220 installFlags |= PackageManager.INSTALL_INSTANT_APP;
1221 installFlags &= ~PackageManager.INSTALL_FULL_APP;
1222 break;
1223 case "--full":
1224 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1225 installFlags |= PackageManager.INSTALL_FULL_APP;
1226 break;
Chandan Nathe8e463b2019-01-28 15:23:38 +00001227 case "--wait":
1228 waitTillComplete = true;
1229 break;
Philip P. Moltmannbfcffa02019-05-13 17:10:46 -07001230 case "--restrict-permissions":
1231 installFlags &= ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
1232 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001233 default:
1234 pw.println("Error: Unknown option: " + opt);
1235 return 1;
1236 }
1237 }
1238
1239 final String packageName = getNextArg();
1240 if (packageName == null) {
1241 pw.println("Error: package name not specified");
1242 return 1;
1243 }
1244
Chandan Nathe8e463b2019-01-28 15:23:38 +00001245 int installReason = PackageManager.INSTALL_REASON_UNKNOWN;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001246 try {
Chandan Nathe8e463b2019-01-28 15:23:38 +00001247 if (waitTillComplete) {
1248 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1249 final IPackageInstaller installer = mInterface.getPackageInstaller();
1250 pw.println("Installing package " + packageName + " for user: " + userId);
1251 installer.installExistingPackage(packageName, installFlags, installReason,
Philip P. Moltmannbfcffa02019-05-13 17:10:46 -07001252 receiver.getIntentSender(), userId, null);
Chandan Nathe8e463b2019-01-28 15:23:38 +00001253 final Intent result = receiver.getResult();
1254 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1255 PackageInstaller.STATUS_FAILURE);
1256 pw.println("Received intent for package install");
1257 return status == PackageInstaller.STATUS_SUCCESS ? 0 : 1;
1258 }
1259
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001260 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
Philip P. Moltmannbfcffa02019-05-13 17:10:46 -07001261 installFlags, installReason, null);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001262 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
1263 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1264 }
1265 pw.println("Package " + packageName + " installed for user: " + userId);
1266 return 0;
1267 } catch (RemoteException | NameNotFoundException e) {
1268 pw.println(e.toString());
1269 return 1;
1270 }
1271 }
1272
1273 private int runSetInstallLocation() throws RemoteException {
1274 int loc;
1275
1276 String arg = getNextArg();
1277 if (arg == null) {
1278 getErrPrintWriter().println("Error: no install location specified.");
1279 return 1;
1280 }
1281 try {
1282 loc = Integer.parseInt(arg);
1283 } catch (NumberFormatException e) {
1284 getErrPrintWriter().println("Error: install location has to be a number.");
1285 return 1;
1286 }
1287 if (!mInterface.setInstallLocation(loc)) {
1288 getErrPrintWriter().println("Error: install location has to be a number.");
1289 return 1;
1290 }
1291 return 0;
1292 }
1293
1294 private int runGetInstallLocation() throws RemoteException {
1295 int loc = mInterface.getInstallLocation();
1296 String locStr = "invalid";
1297 if (loc == PackageHelper.APP_INSTALL_AUTO) {
1298 locStr = "auto";
1299 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
1300 locStr = "internal";
1301 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
1302 locStr = "external";
1303 }
1304 getOutPrintWriter().println(loc + "[" + locStr + "]");
1305 return 0;
1306 }
1307
1308 public int runMovePackage() throws RemoteException {
1309 final String packageName = getNextArg();
1310 if (packageName == null) {
1311 getErrPrintWriter().println("Error: package name not specified");
1312 return 1;
1313 }
1314 String volumeUuid = getNextArg();
1315 if ("internal".equals(volumeUuid)) {
1316 volumeUuid = null;
1317 }
1318
1319 final int moveId = mInterface.movePackage(packageName, volumeUuid);
1320
1321 int status = mInterface.getMoveStatus(moveId);
1322 while (!PackageManager.isMoveStatusFinished(status)) {
1323 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1324 status = mInterface.getMoveStatus(moveId);
1325 }
1326
1327 if (status == PackageManager.MOVE_SUCCEEDED) {
1328 getOutPrintWriter().println("Success");
1329 return 0;
1330 } else {
1331 getErrPrintWriter().println("Failure [" + status + "]");
1332 return 1;
1333 }
1334 }
1335
1336 public int runMovePrimaryStorage() throws RemoteException {
1337 String volumeUuid = getNextArg();
1338 if ("internal".equals(volumeUuid)) {
1339 volumeUuid = null;
1340 }
1341
1342 final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1343
1344 int status = mInterface.getMoveStatus(moveId);
1345 while (!PackageManager.isMoveStatusFinished(status)) {
1346 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1347 status = mInterface.getMoveStatus(moveId);
1348 }
1349
1350 if (status == PackageManager.MOVE_SUCCEEDED) {
1351 getOutPrintWriter().println("Success");
1352 return 0;
1353 } else {
1354 getErrPrintWriter().println("Failure [" + status + "]");
1355 return 1;
1356 }
1357 }
1358
1359 private int runCompile() throws RemoteException {
1360 final PrintWriter pw = getOutPrintWriter();
1361 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1362 boolean forceCompilation = false;
1363 boolean allPackages = false;
1364 boolean clearProfileData = false;
1365 String compilerFilter = null;
1366 String compilationReason = null;
1367 String checkProfilesRaw = null;
1368 boolean secondaryDex = false;
1369 String split = null;
Eric Holka1485f62019-01-07 13:58:25 -08001370 boolean compileLayouts = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001371
1372 String opt;
1373 while ((opt = getNextOption()) != null) {
1374 switch (opt) {
1375 case "-a":
1376 allPackages = true;
1377 break;
1378 case "-c":
1379 clearProfileData = true;
1380 break;
1381 case "-f":
1382 forceCompilation = true;
1383 break;
1384 case "-m":
1385 compilerFilter = getNextArgRequired();
1386 break;
1387 case "-r":
1388 compilationReason = getNextArgRequired();
1389 break;
Eric Holka1485f62019-01-07 13:58:25 -08001390 case "--compile-layouts":
1391 compileLayouts = true;
1392 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001393 case "--check-prof":
1394 checkProfilesRaw = getNextArgRequired();
1395 break;
1396 case "--reset":
1397 forceCompilation = true;
1398 clearProfileData = true;
1399 compilationReason = "install";
1400 break;
1401 case "--secondary-dex":
1402 secondaryDex = true;
1403 break;
1404 case "--split":
1405 split = getNextArgRequired();
1406 break;
1407 default:
1408 pw.println("Error: Unknown option: " + opt);
1409 return 1;
1410 }
1411 }
1412
1413 if (checkProfilesRaw != null) {
1414 if ("true".equals(checkProfilesRaw)) {
1415 checkProfiles = true;
1416 } else if ("false".equals(checkProfilesRaw)) {
1417 checkProfiles = false;
1418 } else {
1419 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1420 return 1;
1421 }
1422 }
1423
Eric Holka1485f62019-01-07 13:58:25 -08001424 final boolean compilerFilterGiven = compilerFilter != null;
1425 final boolean compilationReasonGiven = compilationReason != null;
1426 // Make sure exactly one of -m, -r, or --compile-layouts is given.
1427 if ((!compilerFilterGiven && !compilationReasonGiven && !compileLayouts)
1428 || (!compilerFilterGiven && compilationReasonGiven && compileLayouts)
1429 || (compilerFilterGiven && !compilationReasonGiven && compileLayouts)
1430 || (compilerFilterGiven && compilationReasonGiven && !compileLayouts)
1431 || (compilerFilterGiven && compilationReasonGiven && compileLayouts)) {
1432 pw.println("Must specify exactly one of compilation filter (\"-m\"), compilation " +
1433 "reason (\"-r\"), or compile layouts (\"--compile-layouts\")");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001434 return 1;
1435 }
1436
1437 if (allPackages && split != null) {
1438 pw.println("-a cannot be specified together with --split");
1439 return 1;
1440 }
1441
1442 if (secondaryDex && split != null) {
1443 pw.println("--secondary-dex cannot be specified together with --split");
1444 return 1;
1445 }
1446
Eric Holka1485f62019-01-07 13:58:25 -08001447 String targetCompilerFilter = null;
1448 if (compilerFilterGiven) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001449 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1450 pw.println("Error: \"" + compilerFilter +
1451 "\" is not a valid compilation filter.");
1452 return 1;
1453 }
1454 targetCompilerFilter = compilerFilter;
Eric Holka1485f62019-01-07 13:58:25 -08001455 }
1456 if (compilationReasonGiven) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001457 int reason = -1;
1458 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1459 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1460 compilationReason)) {
1461 reason = i;
1462 break;
1463 }
1464 }
1465 if (reason == -1) {
1466 pw.println("Error: Unknown compilation reason: " + compilationReason);
1467 return 1;
1468 }
1469 targetCompilerFilter =
1470 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1471 }
1472
1473
1474 List<String> packageNames = null;
1475 if (allPackages) {
1476 packageNames = mInterface.getAllPackages();
1477 } else {
1478 String packageName = getNextArg();
1479 if (packageName == null) {
1480 pw.println("Error: package name not specified");
1481 return 1;
1482 }
1483 packageNames = Collections.singletonList(packageName);
1484 }
1485
1486 List<String> failedPackages = new ArrayList<>();
Andreas Gampecbd08d42017-11-20 17:03:17 -08001487 int index = 0;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001488 for (String packageName : packageNames) {
1489 if (clearProfileData) {
1490 mInterface.clearApplicationProfileData(packageName);
1491 }
1492
Andreas Gampecbd08d42017-11-20 17:03:17 -08001493 if (allPackages) {
1494 pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1495 pw.flush();
1496 }
1497
Eric Holka1485f62019-01-07 13:58:25 -08001498 boolean result = true;
1499 if (compileLayouts) {
1500 PackageManagerInternal internal = LocalServices.getService(
1501 PackageManagerInternal.class);
1502 result = internal.compileLayouts(packageName);
1503 } else {
1504 result = secondaryDex
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001505 ? mInterface.performDexOptSecondary(packageName,
1506 targetCompilerFilter, forceCompilation)
1507 : mInterface.performDexOptMode(packageName,
1508 checkProfiles, targetCompilerFilter, forceCompilation,
1509 true /* bootComplete */, split);
Eric Holka1485f62019-01-07 13:58:25 -08001510 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001511 if (!result) {
1512 failedPackages.add(packageName);
1513 }
1514 }
1515
1516 if (failedPackages.isEmpty()) {
1517 pw.println("Success");
1518 return 0;
1519 } else if (failedPackages.size() == 1) {
1520 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1521 return 1;
1522 } else {
1523 pw.print("Failure: the following packages could not be compiled: ");
1524 boolean is_first = true;
1525 for (String packageName : failedPackages) {
1526 if (is_first) {
1527 is_first = false;
1528 } else {
1529 pw.print(", ");
1530 }
1531 pw.print(packageName);
1532 }
1533 pw.println();
1534 return 1;
1535 }
1536 }
1537
1538 private int runreconcileSecondaryDexFiles() throws RemoteException {
1539 String packageName = getNextArg();
1540 mInterface.reconcileSecondaryDexFiles(packageName);
1541 return 0;
1542 }
1543
1544 public int runForceDexOpt() throws RemoteException {
1545 mInterface.forceDexOpt(getNextArgRequired());
1546 return 0;
1547 }
1548
1549 private int runDexoptJob() throws RemoteException {
Arthur Eubanks09dd1ec2017-09-15 09:28:51 -07001550 String arg;
1551 List<String> packageNames = new ArrayList<>();
1552 while ((arg = getNextArg()) != null) {
1553 packageNames.add(arg);
1554 }
1555 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1556 packageNames);
Andreas Gampefa8b57d2018-08-31 15:47:01 -07001557 getOutPrintWriter().println(result ? "Success" : "Failure");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001558 return result ? 0 : -1;
1559 }
1560
1561 private int runDumpProfiles() throws RemoteException {
1562 String packageName = getNextArg();
1563 mInterface.dumpProfiles(packageName);
1564 return 0;
1565 }
1566
Calin Juravle21216c62018-05-04 17:35:29 -07001567 private int runSnapshotProfile() throws RemoteException {
1568 PrintWriter pw = getOutPrintWriter();
1569
1570 // Parse the arguments
1571 final String packageName = getNextArg();
1572 final boolean isBootImage = "android".equals(packageName);
1573
1574 String codePath = null;
1575 String opt;
1576 while ((opt = getNextArg()) != null) {
1577 switch (opt) {
1578 case "--code-path":
1579 if (isBootImage) {
1580 pw.write("--code-path cannot be used for the boot image.");
1581 return -1;
1582 }
1583 codePath = getNextArg();
1584 break;
1585 default:
1586 pw.write("Unknown arg: " + opt);
1587 return -1;
1588 }
1589 }
1590
1591 // If no code path was explicitly requested, select the base code path.
1592 String baseCodePath = null;
1593 if (!isBootImage) {
1594 PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
1595 /* userId */0);
1596 if (packageInfo == null) {
1597 pw.write("Package not found " + packageName);
1598 return -1;
1599 }
1600 baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
1601 if (codePath == null) {
1602 codePath = baseCodePath;
1603 }
1604 }
1605
1606 // Create the profile snapshot.
1607 final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
1608 // The calling package is needed to debug permission access.
1609 final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
1610 ? "root" : "com.android.shell";
1611 final int profileType = isBootImage
1612 ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
1613 if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
1614 pw.println("Error: Runtime profiling is not enabled");
1615 return -1;
1616 }
1617 mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
1618 codePath, callback, callingPackage);
1619 if (!callback.waitTillDone()) {
1620 pw.println("Error: callback not called");
1621 return callback.mErrCode;
1622 }
1623
1624 // Copy the snapshot profile to the output profile file.
1625 try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
1626 final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
1627 ? "" : ("-" + new File(codePath).getName());
1628 final String outputProfilePath =
1629 ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
1630 try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
1631 Streams.copy(inStream, outStream);
1632 }
Calin Juravlebdd94d92018-05-17 01:23:15 -07001633 // Give read permissions to the other group.
1634 Os.chmod(outputProfilePath, /*mode*/ 0644 );
1635 } catch (IOException | ErrnoException e) {
Calin Juravle21216c62018-05-04 17:35:29 -07001636 pw.println("Error when reading the profile fd: " + e.getMessage());
1637 e.printStackTrace(pw);
1638 return -1;
1639 }
1640 return 0;
1641 }
1642
1643 private static class SnapshotRuntimeProfileCallback
1644 extends ISnapshotRuntimeProfileCallback.Stub {
1645 private boolean mSuccess = false;
1646 private int mErrCode = -1;
1647 private ParcelFileDescriptor mProfileReadFd = null;
1648 private CountDownLatch mDoneSignal = new CountDownLatch(1);
1649
1650 @Override
1651 public void onSuccess(ParcelFileDescriptor profileReadFd) {
1652 mSuccess = true;
1653 try {
1654 // We need to dup the descriptor. We are in the same process as system server
1655 // and we will be receiving the same object (which will be closed on the
1656 // server side).
1657 mProfileReadFd = profileReadFd.dup();
1658 } catch (IOException e) {
1659 e.printStackTrace();
1660 }
1661 mDoneSignal.countDown();
1662 }
1663
1664 @Override
1665 public void onError(int errCode) {
1666 mSuccess = false;
1667 mErrCode = errCode;
1668 mDoneSignal.countDown();
1669 }
1670
1671 boolean waitTillDone() {
1672 boolean done = false;
1673 try {
1674 // The time-out is an arbitrary large value. Since this is a local call the result
1675 // will come very fast.
1676 done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS);
1677 } catch (InterruptedException ignored) {
1678 }
1679 return done && mSuccess;
1680 }
1681 }
1682
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001683 private int runUninstall() throws RemoteException {
1684 final PrintWriter pw = getOutPrintWriter();
1685 int flags = 0;
1686 int userId = UserHandle.USER_ALL;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001687 long versionCode = PackageManager.VERSION_CODE_HIGHEST;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001688
1689 String opt;
1690 while ((opt = getNextOption()) != null) {
1691 switch (opt) {
1692 case "-k":
1693 flags |= PackageManager.DELETE_KEEP_DATA;
1694 break;
1695 case "--user":
1696 userId = UserHandle.parseUserArg(getNextArgRequired());
1697 break;
1698 case "--versionCode":
Dianne Hackborn3accca02013-09-20 09:32:11 -07001699 versionCode = Long.parseLong(getNextArgRequired());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001700 break;
1701 default:
1702 pw.println("Error: Unknown option: " + opt);
1703 return 1;
1704 }
1705 }
1706
1707 final String packageName = getNextArg();
1708 if (packageName == null) {
1709 pw.println("Error: package name not specified");
1710 return 1;
1711 }
1712
1713 // if a split is specified, just remove it and not the whole package
1714 final String splitName = getNextArg();
1715 if (splitName != null) {
1716 return runRemoveSplit(packageName, splitName);
1717 }
1718
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08001719 userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001720 final LocalIntentReceiver receiver = new LocalIntentReceiver();
Nikita Ioffef012a222019-03-05 22:37:55 +00001721 PackageManagerInternal internal = LocalServices.getService(PackageManagerInternal.class);
1722
1723 if (internal.isApexPackage(packageName)) {
1724 internal.uninstallApex(packageName, versionCode, userId, receiver.getIntentSender());
1725 } else {
1726 if (userId == UserHandle.USER_ALL) {
1727 userId = UserHandle.USER_SYSTEM;
1728 flags |= PackageManager.DELETE_ALL_USERS;
1729 } else {
1730 final PackageInfo info = mInterface.getPackageInfo(packageName,
1731 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1732 if (info == null) {
1733 pw.println("Failure [not installed for " + userId + "]");
1734 return 1;
1735 }
1736 final boolean isSystem =
1737 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1738 // If we are being asked to delete a system app for just one
1739 // user set flag so it disables rather than reverting to system
1740 // version of the app.
1741 if (isSystem) {
1742 flags |= PackageManager.DELETE_SYSTEM_APP;
1743 }
1744 }
1745
1746 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1747 versionCode), null /*callerPackageName*/, flags,
1748 receiver.getIntentSender(), userId);
1749 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001750
1751 final Intent result = receiver.getResult();
1752 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1753 PackageInstaller.STATUS_FAILURE);
1754 if (status == PackageInstaller.STATUS_SUCCESS) {
1755 pw.println("Success");
1756 return 0;
1757 } else {
1758 pw.println("Failure ["
1759 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1760 return 1;
1761 }
1762 }
1763
1764 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1765 final PrintWriter pw = getOutPrintWriter();
1766 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1767 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1768 sessionParams.appPackageName = packageName;
1769 final int sessionId =
1770 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1771 boolean abandonSession = true;
1772 try {
1773 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1774 != PackageInstaller.STATUS_SUCCESS) {
1775 return 1;
1776 }
1777 if (doCommitSession(sessionId, false /*logSuccess*/)
1778 != PackageInstaller.STATUS_SUCCESS) {
1779 return 1;
1780 }
1781 abandonSession = false;
1782 pw.println("Success");
1783 return 0;
1784 } finally {
1785 if (abandonSession) {
1786 try {
1787 doAbandonSession(sessionId, false /*logSuccess*/);
1788 } catch (Exception ignore) {
1789 }
1790 }
1791 }
1792 }
1793
1794 static class ClearDataObserver extends IPackageDataObserver.Stub {
1795 boolean finished;
1796 boolean result;
1797
1798 @Override
1799 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1800 synchronized (this) {
1801 finished = true;
1802 result = succeeded;
1803 notifyAll();
1804 }
1805 }
1806 }
1807
1808 private int runClear() throws RemoteException {
1809 int userId = UserHandle.USER_SYSTEM;
1810 String option = getNextOption();
1811 if (option != null && option.equals("--user")) {
1812 userId = UserHandle.parseUserArg(getNextArgRequired());
1813 }
1814
1815 String pkg = getNextArg();
1816 if (pkg == null) {
1817 getErrPrintWriter().println("Error: no package specified");
1818 return 1;
1819 }
1820
1821 ClearDataObserver obs = new ClearDataObserver();
Christopher Tate1d99c392017-12-07 16:54:04 -08001822 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001823 synchronized (obs) {
1824 while (!obs.finished) {
1825 try {
1826 obs.wait();
1827 } catch (InterruptedException e) {
1828 }
1829 }
1830 }
1831
1832 if (obs.result) {
1833 getOutPrintWriter().println("Success");
1834 return 0;
1835 } else {
1836 getErrPrintWriter().println("Failed");
1837 return 1;
1838 }
1839 }
1840
1841 private static String enabledSettingToString(int state) {
1842 switch (state) {
1843 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1844 return "default";
1845 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1846 return "enabled";
1847 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1848 return "disabled";
1849 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1850 return "disabled-user";
1851 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1852 return "disabled-until-used";
1853 }
1854 return "unknown";
1855 }
1856
1857 private int runSetEnabledSetting(int state) throws RemoteException {
1858 int userId = UserHandle.USER_SYSTEM;
1859 String option = getNextOption();
1860 if (option != null && option.equals("--user")) {
1861 userId = UserHandle.parseUserArg(getNextArgRequired());
1862 }
1863
1864 String pkg = getNextArg();
1865 if (pkg == null) {
1866 getErrPrintWriter().println("Error: no package or component specified");
1867 return 1;
1868 }
1869 ComponentName cn = ComponentName.unflattenFromString(pkg);
1870 if (cn == null) {
1871 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1872 "shell:" + android.os.Process.myUid());
1873 getOutPrintWriter().println("Package " + pkg + " new state: "
1874 + enabledSettingToString(
1875 mInterface.getApplicationEnabledSetting(pkg, userId)));
1876 return 0;
1877 } else {
1878 mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1879 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1880 + enabledSettingToString(
1881 mInterface.getComponentEnabledSetting(cn, userId)));
1882 return 0;
1883 }
1884 }
1885
1886 private int runSetHiddenSetting(boolean state) throws RemoteException {
1887 int userId = UserHandle.USER_SYSTEM;
1888 String option = getNextOption();
1889 if (option != null && option.equals("--user")) {
1890 userId = UserHandle.parseUserArg(getNextArgRequired());
1891 }
1892
1893 String pkg = getNextArg();
1894 if (pkg == null) {
1895 getErrPrintWriter().println("Error: no package or component specified");
1896 return 1;
1897 }
1898 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1899 getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1900 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1901 return 0;
1902 }
1903
1904 private int runSuspend(boolean suspendedState) {
1905 final PrintWriter pw = getOutPrintWriter();
1906 int userId = UserHandle.USER_SYSTEM;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001907 String dialogMessage = null;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001908 final PersistableBundle appExtras = new PersistableBundle();
1909 final PersistableBundle launcherExtras = new PersistableBundle();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001910 String opt;
1911 while ((opt = getNextOption()) != null) {
1912 switch (opt) {
1913 case "--user":
1914 userId = UserHandle.parseUserArg(getNextArgRequired());
1915 break;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001916 case "--dialogMessage":
1917 dialogMessage = getNextArgRequired();
1918 break;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001919 case "--ael":
1920 case "--aes":
1921 case "--aed":
1922 case "--lel":
1923 case "--les":
1924 case "--led":
1925 final String key = getNextArgRequired();
1926 final String val = getNextArgRequired();
1927 if (!suspendedState) {
1928 break;
1929 }
1930 final PersistableBundle bundleToInsert =
1931 opt.startsWith("--a") ? appExtras : launcherExtras;
1932 switch (opt.charAt(4)) {
1933 case 'l':
1934 bundleToInsert.putLong(key, Long.valueOf(val));
1935 break;
1936 case 'd':
1937 bundleToInsert.putDouble(key, Double.valueOf(val));
1938 break;
1939 case 's':
1940 bundleToInsert.putString(key, val);
1941 break;
1942 }
1943 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001944 default:
1945 pw.println("Error: Unknown option: " + opt);
1946 return 1;
1947 }
1948 }
1949
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001950 final String packageName = getNextArg();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001951 if (packageName == null) {
1952 pw.println("Error: package name not specified");
1953 return 1;
1954 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001955 final String callingPackage =
1956 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07001957
1958 final SuspendDialogInfo info;
1959 if (!TextUtils.isEmpty(dialogMessage)) {
1960 info = new SuspendDialogInfo.Builder()
1961 .setMessage(dialogMessage)
1962 .build();
1963 } else {
1964 info = null;
1965 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001966 try {
1967 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07001968 appExtras, launcherExtras, info, callingPackage, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001969 pw.println("Package " + packageName + " new suspended state: "
1970 + mInterface.isPackageSuspendedForUser(packageName, userId));
1971 return 0;
1972 } catch (RemoteException | IllegalArgumentException e) {
1973 pw.println(e.toString());
1974 return 1;
1975 }
1976 }
1977
1978 private int runGrantRevokePermission(boolean grant) throws RemoteException {
1979 int userId = UserHandle.USER_SYSTEM;
1980
1981 String opt = null;
1982 while ((opt = getNextOption()) != null) {
1983 if (opt.equals("--user")) {
1984 userId = UserHandle.parseUserArg(getNextArgRequired());
1985 }
1986 }
1987
1988 String pkg = getNextArg();
1989 if (pkg == null) {
1990 getErrPrintWriter().println("Error: no package specified");
1991 return 1;
1992 }
1993 String perm = getNextArg();
1994 if (perm == null) {
1995 getErrPrintWriter().println("Error: no permission specified");
1996 return 1;
1997 }
1998
1999 if (grant) {
Todd Kennedyc971a452019-07-08 16:04:52 -07002000 mPermissionManager.grantRuntimePermission(pkg, perm, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002001 } else {
Todd Kennedyc971a452019-07-08 16:04:52 -07002002 mPermissionManager.revokeRuntimePermission(pkg, perm, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002003 }
2004 return 0;
2005 }
2006
2007 private int runResetPermissions() throws RemoteException {
Todd Kennedyc971a452019-07-08 16:04:52 -07002008 mPermissionManager.resetRuntimePermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002009 return 0;
2010 }
2011
2012 private int runSetPermissionEnforced() throws RemoteException {
2013 final String permission = getNextArg();
2014 if (permission == null) {
2015 getErrPrintWriter().println("Error: no permission specified");
2016 return 1;
2017 }
2018 final String enforcedRaw = getNextArg();
2019 if (enforcedRaw == null) {
2020 getErrPrintWriter().println("Error: no enforcement specified");
2021 return 1;
2022 }
Todd Kennedyc5b0e862019-07-16 09:47:58 -07002023 mPermissionManager.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002024 return 0;
2025 }
2026
Jiyong Park002fdbd2017-02-13 20:50:31 +09002027 private boolean isVendorApp(String pkg) {
2028 try {
2029 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
2030 return info != null && info.applicationInfo.isVendor();
2031 } catch (RemoteException e) {
2032 return false;
2033 }
2034 }
2035
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002036 private boolean isProductApp(String pkg) {
2037 try {
2038 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
2039 return info != null && info.applicationInfo.isProduct();
2040 } catch (RemoteException e) {
2041 return false;
2042 }
2043 }
2044
Jeongik Cha9ec059a2019-07-04 21:12:06 +09002045 private boolean isSystemExtApp(String pkg) {
Dario Freni2bef1762018-06-01 14:02:08 +01002046 try {
2047 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
Jeongik Cha9ec059a2019-07-04 21:12:06 +09002048 return info != null && info.applicationInfo.isSystemExt();
Dario Freni2bef1762018-06-01 14:02:08 +01002049 } catch (RemoteException e) {
2050 return false;
2051 }
2052 }
2053
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002054 private int runGetPrivappPermissions() {
2055 final String pkg = getNextArg();
2056 if (pkg == null) {
2057 getErrPrintWriter().println("Error: no package specified.");
2058 return 1;
2059 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002060
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002061 ArraySet<String> privAppPermissions = null;
2062 if (isVendorApp(pkg)) {
2063 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
2064 } else if (isProductApp(pkg)) {
2065 privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
Jeongik Cha9ec059a2019-07-04 21:12:06 +09002066 } else if (isSystemExtApp(pkg)) {
Dario Freni2bef1762018-06-01 14:02:08 +01002067 privAppPermissions = SystemConfig.getInstance()
Jeongik Cha9ec059a2019-07-04 21:12:06 +09002068 .getSystemExtPrivAppPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002069 } else {
2070 privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
2071 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002072
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002073 getOutPrintWriter().println(privAppPermissions == null
2074 ? "{}" : privAppPermissions.toString());
2075 return 0;
2076 }
2077
2078 private int runGetPrivappDenyPermissions() {
2079 final String pkg = getNextArg();
2080 if (pkg == null) {
2081 getErrPrintWriter().println("Error: no package specified.");
2082 return 1;
2083 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002084
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002085 ArraySet<String> privAppPermissions = null;
2086 if (isVendorApp(pkg)) {
2087 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
2088 } else if (isProductApp(pkg)) {
2089 privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
Jeongik Cha9ec059a2019-07-04 21:12:06 +09002090 } else if (isSystemExtApp(pkg)) {
Dario Freni2bef1762018-06-01 14:02:08 +01002091 privAppPermissions = SystemConfig.getInstance()
Jeongik Cha9ec059a2019-07-04 21:12:06 +09002092 .getSystemExtPrivAppDenyPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09002093 } else {
2094 privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
2095 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09002096
2097 getOutPrintWriter().println(privAppPermissions == null
2098 ? "{}" : privAppPermissions.toString());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002099 return 0;
2100 }
2101
2102 private int runGetOemPermissions() {
2103 final String pkg = getNextArg();
2104 if (pkg == null) {
2105 getErrPrintWriter().println("Error: no package specified.");
2106 return 1;
2107 }
2108 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
2109 .getOemPermissions(pkg);
2110 if (oemPermissions == null || oemPermissions.isEmpty()) {
2111 getOutPrintWriter().println("{}");
2112 } else {
2113 oemPermissions.forEach((permission, granted) ->
2114 getOutPrintWriter().println(permission + " granted:" + granted)
2115 );
2116 }
2117 return 0;
2118 }
2119
2120 private String linkStateToString(int state) {
2121 switch (state) {
2122 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
2123 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
2124 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
2125 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
2126 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
2127 }
2128 return "Unknown link state: " + state;
2129 }
2130
2131 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
2132 private int runSetAppLink() throws RemoteException {
2133 int userId = UserHandle.USER_SYSTEM;
2134
2135 String opt;
2136 while ((opt = getNextOption()) != null) {
2137 if (opt.equals("--user")) {
2138 userId = UserHandle.parseUserArg(getNextArgRequired());
2139 } else {
2140 getErrPrintWriter().println("Error: unknown option: " + opt);
2141 return 1;
2142 }
2143 }
2144
2145 // Package name to act on; required
2146 final String pkg = getNextArg();
2147 if (pkg == null) {
2148 getErrPrintWriter().println("Error: no package specified.");
2149 return 1;
2150 }
2151
2152 // State to apply; {always|ask|never|undefined}, required
2153 final String modeString = getNextArg();
2154 if (modeString == null) {
2155 getErrPrintWriter().println("Error: no app link state specified.");
2156 return 1;
2157 }
2158
2159 final int newMode;
2160 switch (modeString.toLowerCase()) {
2161 case "undefined":
2162 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
2163 break;
2164
2165 case "always":
2166 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
2167 break;
2168
2169 case "ask":
2170 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
2171 break;
2172
2173 case "always-ask":
2174 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
2175 break;
2176
2177 case "never":
2178 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
2179 break;
2180
2181 default:
2182 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
2183 return 1;
2184 }
2185
2186 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
2187 if (info == null) {
2188 getErrPrintWriter().println("Error: package " + pkg + " not found.");
2189 return 1;
2190 }
2191
2192 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2193 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2194 return 1;
2195 }
2196
2197 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
2198 getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
2199 return 1;
2200 }
2201
2202 return 0;
2203 }
2204
2205 // pm get-app-link [--user USER_ID] PACKAGE
2206 private int runGetAppLink() throws RemoteException {
2207 int userId = UserHandle.USER_SYSTEM;
2208
2209 String opt;
2210 while ((opt = getNextOption()) != null) {
2211 if (opt.equals("--user")) {
2212 userId = UserHandle.parseUserArg(getNextArgRequired());
2213 } else {
2214 getErrPrintWriter().println("Error: unknown option: " + opt);
2215 return 1;
2216 }
2217 }
2218
2219 // Package name to act on; required
2220 final String pkg = getNextArg();
2221 if (pkg == null) {
2222 getErrPrintWriter().println("Error: no package specified.");
2223 return 1;
2224 }
2225
2226 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
2227 if (info == null) {
2228 getErrPrintWriter().println("Error: package " + pkg + " not found.");
2229 return 1;
2230 }
2231
2232 if ((info.applicationInfo.privateFlags
2233 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2234 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2235 return 1;
2236 }
2237
2238 getOutPrintWriter().println(linkStateToString(
2239 mInterface.getIntentVerificationStatus(pkg, userId)));
2240
2241 return 0;
2242 }
2243
2244 private int runTrimCaches() throws RemoteException {
2245 String size = getNextArg();
2246 if (size == null) {
2247 getErrPrintWriter().println("Error: no size specified");
2248 return 1;
2249 }
2250 long multiplier = 1;
2251 int len = size.length();
2252 char c = size.charAt(len - 1);
2253 if (c < '0' || c > '9') {
2254 if (c == 'K' || c == 'k') {
2255 multiplier = 1024L;
2256 } else if (c == 'M' || c == 'm') {
2257 multiplier = 1024L*1024L;
2258 } else if (c == 'G' || c == 'g') {
2259 multiplier = 1024L*1024L*1024L;
2260 } else {
2261 getErrPrintWriter().println("Invalid suffix: " + c);
2262 return 1;
2263 }
2264 size = size.substring(0, len-1);
2265 }
2266 long sizeVal;
2267 try {
2268 sizeVal = Long.parseLong(size) * multiplier;
2269 } catch (NumberFormatException e) {
2270 getErrPrintWriter().println("Error: expected number at: " + size);
2271 return 1;
2272 }
2273 String volumeUuid = getNextArg();
2274 if ("internal".equals(volumeUuid)) {
2275 volumeUuid = null;
2276 }
2277 ClearDataObserver obs = new ClearDataObserver();
2278 mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
2279 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
2280 synchronized (obs) {
2281 while (!obs.finished) {
2282 try {
2283 obs.wait();
2284 } catch (InterruptedException e) {
2285 }
2286 }
2287 }
2288 return 0;
2289 }
2290
2291 private static boolean isNumber(String s) {
2292 try {
2293 Integer.parseInt(s);
2294 } catch (NumberFormatException nfe) {
2295 return false;
2296 }
2297 return true;
2298 }
2299
2300 public int runCreateUser() throws RemoteException {
2301 String name;
2302 int userId = -1;
2303 int flags = 0;
2304 String opt;
2305 while ((opt = getNextOption()) != null) {
2306 if ("--profileOf".equals(opt)) {
2307 userId = UserHandle.parseUserArg(getNextArgRequired());
2308 } else if ("--managed".equals(opt)) {
2309 flags |= UserInfo.FLAG_MANAGED_PROFILE;
2310 } else if ("--restricted".equals(opt)) {
2311 flags |= UserInfo.FLAG_RESTRICTED;
2312 } else if ("--ephemeral".equals(opt)) {
2313 flags |= UserInfo.FLAG_EPHEMERAL;
2314 } else if ("--guest".equals(opt)) {
2315 flags |= UserInfo.FLAG_GUEST;
2316 } else if ("--demo".equals(opt)) {
2317 flags |= UserInfo.FLAG_DEMO;
2318 } else {
2319 getErrPrintWriter().println("Error: unknown option " + opt);
2320 return 1;
2321 }
2322 }
2323 String arg = getNextArg();
2324 if (arg == null) {
2325 getErrPrintWriter().println("Error: no user name specified.");
2326 return 1;
2327 }
2328 name = arg;
2329 UserInfo info;
2330 IUserManager um = IUserManager.Stub.asInterface(
2331 ServiceManager.getService(Context.USER_SERVICE));
2332 IAccountManager accm = IAccountManager.Stub.asInterface(
2333 ServiceManager.getService(Context.ACCOUNT_SERVICE));
2334 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
2335 // In non-split user mode, userId can only be SYSTEM
2336 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
2337 info = um.createRestrictedProfile(name, parentUserId);
2338 accm.addSharedAccountsFromParentUser(parentUserId, userId,
2339 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
2340 } else if (userId < 0) {
2341 info = um.createUser(name, flags);
2342 } else {
2343 info = um.createProfileForUser(name, flags, userId, null);
2344 }
2345
2346 if (info != null) {
2347 getOutPrintWriter().println("Success: created user id " + info.id);
2348 return 0;
2349 } else {
2350 getErrPrintWriter().println("Error: couldn't create User.");
2351 return 1;
2352 }
2353 }
2354
2355 public int runRemoveUser() throws RemoteException {
2356 int userId;
2357 String arg = getNextArg();
2358 if (arg == null) {
2359 getErrPrintWriter().println("Error: no user id specified.");
2360 return 1;
2361 }
2362 userId = UserHandle.parseUserArg(arg);
2363 IUserManager um = IUserManager.Stub.asInterface(
2364 ServiceManager.getService(Context.USER_SERVICE));
2365 if (um.removeUser(userId)) {
2366 getOutPrintWriter().println("Success: removed user");
2367 return 0;
2368 } else {
2369 getErrPrintWriter().println("Error: couldn't remove user id " + userId);
2370 return 1;
2371 }
2372 }
2373
2374 public int runSetUserRestriction() throws RemoteException {
2375 int userId = UserHandle.USER_SYSTEM;
2376 String opt = getNextOption();
2377 if (opt != null && "--user".equals(opt)) {
2378 userId = UserHandle.parseUserArg(getNextArgRequired());
2379 }
2380
2381 String restriction = getNextArg();
2382 String arg = getNextArg();
2383 boolean value;
2384 if ("1".equals(arg)) {
2385 value = true;
2386 } else if ("0".equals(arg)) {
2387 value = false;
2388 } else {
2389 getErrPrintWriter().println("Error: valid value not specified");
2390 return 1;
2391 }
2392 IUserManager um = IUserManager.Stub.asInterface(
2393 ServiceManager.getService(Context.USER_SERVICE));
2394 um.setUserRestriction(restriction, value, userId);
2395 return 0;
2396 }
2397
2398 public int runGetMaxUsers() {
2399 getOutPrintWriter().println("Maximum supported users: "
2400 + UserManager.getMaxSupportedUsers());
2401 return 0;
2402 }
2403
Alex Chauc12189b2018-01-16 15:01:15 +00002404 public int runGetMaxRunningUsers() {
2405 ActivityManagerInternal activityManagerInternal =
2406 LocalServices.getService(ActivityManagerInternal.class);
2407 getOutPrintWriter().println("Maximum supported running users: "
2408 + activityManagerInternal.getMaxRunningUsers());
2409 return 0;
2410 }
2411
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002412 private static class InstallParams {
2413 SessionParams sessionParams;
2414 String installerPackageName;
2415 int userId = UserHandle.USER_ALL;
Mohammad Samiul Islambd02f422019-05-17 18:02:12 +01002416 boolean waitForStagedSessionReady = false;
2417 long timeoutMs = DEFAULT_WAIT_MS;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002418 }
2419
2420 private InstallParams makeInstallParams() {
2421 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
2422 final InstallParams params = new InstallParams();
Philip P. Moltmannbfcffa02019-05-13 17:10:46 -07002423
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002424 params.sessionParams = sessionParams;
Philip P. Moltmannbfcffa02019-05-13 17:10:46 -07002425 // Whitelist all permissions by default
2426 sessionParams.installFlags |= PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
2427
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002428 String opt;
Patrick Baumanna9333492017-11-28 15:23:49 -08002429 boolean replaceExisting = true;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002430 while ((opt = getNextOption()) != null) {
2431 switch (opt) {
Patrick Baumanna9333492017-11-28 15:23:49 -08002432 case "-r": // ignore
2433 break;
2434 case "-R":
2435 replaceExisting = false;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002436 break;
2437 case "-i":
2438 params.installerPackageName = getNextArg();
2439 if (params.installerPackageName == null) {
2440 throw new IllegalArgumentException("Missing installer package");
2441 }
2442 break;
2443 case "-t":
2444 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
2445 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002446 case "-f":
2447 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
2448 break;
2449 case "-d":
Nikita Ioffeb1d60f12019-03-06 18:56:49 +00002450 sessionParams.installFlags |= PackageManager.INSTALL_REQUEST_DOWNGRADE;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002451 break;
2452 case "-g":
2453 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002454 break;
2455 case "--restrict-permissions":
2456 sessionParams.installFlags &=
2457 ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002458 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002459 case "--dont-kill":
2460 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
2461 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002462 case "--originating-uri":
2463 sessionParams.originatingUri = Uri.parse(getNextArg());
2464 break;
2465 case "--referrer":
2466 sessionParams.referrerUri = Uri.parse(getNextArg());
2467 break;
2468 case "-p":
2469 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
2470 sessionParams.appPackageName = getNextArg();
2471 if (sessionParams.appPackageName == null) {
2472 throw new IllegalArgumentException("Missing inherit package name");
2473 }
2474 break;
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002475 case "--pkg":
2476 sessionParams.appPackageName = getNextArg();
2477 if (sessionParams.appPackageName == null) {
2478 throw new IllegalArgumentException("Missing package name");
2479 }
2480 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002481 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002482 final long sizeBytes = Long.parseLong(getNextArg());
2483 if (sizeBytes <= 0) {
2484 throw new IllegalArgumentException("Size must be positive");
2485 }
2486 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002487 break;
2488 case "--abi":
2489 sessionParams.abiOverride = checkAbiArgument(getNextArg());
2490 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08002491 case "--ephemeral":
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002492 case "--instant":
Todd Kennedybe0b8892017-02-15 14:13:52 -08002493 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08002494 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08002495 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08002496 case "--full":
2497 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
2498 break;
Todd Kennedy78a72502017-07-19 12:49:30 -07002499 case "--preload":
2500 sessionParams.setInstallAsVirtualPreload();
2501 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002502 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002503 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002504 break;
2505 case "--install-location":
2506 sessionParams.installLocation = Integer.parseInt(getNextArg());
2507 break;
Sunny Goyalabd4d442018-09-19 15:49:50 -07002508 case "--install-reason":
2509 sessionParams.installReason = Integer.parseInt(getNextArg());
2510 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002511 case "--force-uuid":
2512 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
2513 sessionParams.volumeUuid = getNextArg();
2514 if ("internal".equals(sessionParams.volumeUuid)) {
2515 sessionParams.volumeUuid = null;
2516 }
2517 break;
Nicholas Lativyeb23e4d2019-02-01 13:39:28 +00002518 case "--force-sdk": // ignore
Todd Kennedyb1072712016-04-26 15:41:20 -07002519 break;
Dario Frenid8bf22e2018-08-31 14:18:04 +01002520 case "--apex":
Dario Freni3fa46d82019-01-23 19:31:47 +00002521 sessionParams.setInstallAsApex();
Dario Freni505b8152019-01-08 12:30:43 +00002522 sessionParams.setStaged();
Dario Frenid8bf22e2018-08-31 14:18:04 +01002523 break;
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002524 case "--multi-package":
2525 sessionParams.setMultiPackage();
2526 break;
Dario Freniaac4ba42018-12-06 15:47:16 +00002527 case "--staged":
2528 sessionParams.setStaged();
2529 break;
Richard Uhlerb29f1452018-09-12 16:38:15 +01002530 case "--enable-rollback":
Richard Uhler88184a62019-04-16 11:30:25 +01002531 if (params.installerPackageName == null) {
2532 // com.android.shell has the TEST_MANAGE_ROLLBACKS
2533 // permission needed to enable rollback for non-module
2534 // packages, which is likely what the user wants when
2535 // enabling rollback through the shell command. Set
2536 // the installer to com.android.shell if no installer
2537 // has been provided so that the user doesn't have to
2538 // remember to set it themselves.
2539 params.installerPackageName = "com.android.shell";
2540 }
Richard Uhlerb29f1452018-09-12 16:38:15 +01002541 sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
2542 break;
Mohammad Samiul Islambd02f422019-05-17 18:02:12 +01002543 case "--wait":
2544 params.waitForStagedSessionReady = true;
2545 try {
2546 params.timeoutMs = Long.parseLong(peekNextArg());
2547 getNextArg();
2548 } catch (NumberFormatException ignore) {
2549 }
2550 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002551 default:
2552 throw new IllegalArgumentException("Unknown option " + opt);
2553 }
Patrick Baumanndcf19162019-05-29 09:18:58 -07002554 }
2555 if (replaceExisting) {
2556 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002557 }
2558 return params;
2559 }
2560
Makoto Onuki4828a592016-03-15 18:06:57 -07002561 private int runSetHomeActivity() {
2562 final PrintWriter pw = getOutPrintWriter();
2563 int userId = UserHandle.USER_SYSTEM;
2564 String opt;
2565 while ((opt = getNextOption()) != null) {
2566 switch (opt) {
2567 case "--user":
2568 userId = UserHandle.parseUserArg(getNextArgRequired());
2569 break;
2570 default:
2571 pw.println("Error: Unknown option: " + opt);
2572 return 1;
2573 }
2574 }
2575
Bookatz2b5a6012019-04-16 19:41:28 -07002576 String pkgName;
Makoto Onuki4828a592016-03-15 18:06:57 -07002577 String component = getNextArg();
Bookatz2b5a6012019-04-16 19:41:28 -07002578 if (component.indexOf('/') < 0) {
2579 // No component specified, so assume it's just a package name.
2580 pkgName = component;
2581 } else {
2582 ComponentName componentName =
2583 component != null ? ComponentName.unflattenFromString(component) : null;
2584 if (componentName == null) {
2585 pw.println("Error: invalid component name");
2586 return 1;
2587 }
2588 pkgName = componentName.getPackageName();
Makoto Onuki4828a592016-03-15 18:06:57 -07002589 }
2590
Bookatz2b5a6012019-04-16 19:41:28 -07002591
2592 final CompletableFuture<Boolean> future = new CompletableFuture<>();
2593 final RemoteCallback callback = new RemoteCallback(res -> future.complete(res != null));
Makoto Onuki4828a592016-03-15 18:06:57 -07002594 try {
Bookatz2b5a6012019-04-16 19:41:28 -07002595 IRoleManager roleManager = android.app.role.IRoleManager.Stub.asInterface(
2596 ServiceManager.getServiceOrThrow(Context.ROLE_SERVICE));
2597 roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, pkgName,
2598 0, userId, callback);
2599 boolean success = future.get();
2600 if (success) {
2601 pw.println("Success");
2602 return 0;
2603 } else {
2604 pw.println("Error: Failed to set default home.");
2605 return 1;
2606 }
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002607 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07002608 pw.println(e.toString());
2609 return 1;
2610 }
2611 }
2612
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002613 private int runSetInstaller() throws RemoteException {
2614 final String targetPackage = getNextArg();
2615 final String installerPackageName = getNextArg();
Fyodor Kupolov51245c72016-12-01 11:34:10 -08002616
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002617 if (targetPackage == null || installerPackageName == null) {
2618 getErrPrintWriter().println("Must provide both target and installer package names");
Todd Kennedy74629e32017-08-15 14:48:07 -07002619 return 1;
2620 }
Todd Kennedy74629e32017-08-15 14:48:07 -07002621
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002622 mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2623 getOutPrintWriter().println("Success");
Svet Ganov087dce22017-09-07 15:42:16 -07002624 return 0;
2625 }
2626
Todd Kennedy0a3f0812017-05-08 14:43:15 -07002627 private int runGetInstantAppResolver() {
2628 final PrintWriter pw = getOutPrintWriter();
2629 try {
2630 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2631 if (instantAppsResolver == null) {
2632 return 1;
2633 }
2634 pw.println(instantAppsResolver.flattenToString());
2635 return 0;
2636 } catch (Exception e) {
2637 pw.println(e.toString());
2638 return 1;
2639 }
2640 }
2641
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09002642 private int runHasFeature() {
2643 final PrintWriter err = getErrPrintWriter();
2644 final String featureName = getNextArg();
2645 if (featureName == null) {
2646 err.println("Error: expected FEATURE name");
2647 return 1;
2648 }
2649 final String versionString = getNextArg();
2650 try {
2651 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2652 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2653 getOutPrintWriter().println(hasFeature);
2654 return hasFeature ? 0 : 1;
2655 } catch (NumberFormatException e) {
2656 err.println("Error: illegal version number " + versionString);
2657 return 1;
2658 } catch (RemoteException e) {
2659 err.println(e.toString());
2660 return 1;
2661 }
2662 }
2663
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002664 private int runDump() {
2665 String pkg = getNextArg();
2666 if (pkg == null) {
2667 getErrPrintWriter().println("Error: no package specified");
2668 return 1;
2669 }
2670 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2671 return 0;
2672 }
2673
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002674 private int runSetHarmfulAppWarning() throws RemoteException {
2675 int userId = UserHandle.USER_CURRENT;
2676
2677 String opt;
2678 while ((opt = getNextOption()) != null) {
2679 if (opt.equals("--user")) {
2680 userId = UserHandle.parseUserArg(getNextArgRequired());
2681 } else {
2682 getErrPrintWriter().println("Error: Unknown option: " + opt);
2683 return -1;
2684 }
2685 }
2686
2687 userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning");
2688
2689 final String packageName = getNextArgRequired();
2690 final String warning = getNextArg();
2691
2692 mInterface.setHarmfulAppWarning(packageName, warning, userId);
2693
2694 return 0;
2695 }
2696
Ben Gruver9ef60092018-01-10 11:32:30 -08002697 private int runGetHarmfulAppWarning() throws RemoteException {
2698 int userId = UserHandle.USER_CURRENT;
2699
2700 String opt;
2701 while ((opt = getNextOption()) != null) {
2702 if (opt.equals("--user")) {
2703 userId = UserHandle.parseUserArg(getNextArgRequired());
2704 } else {
2705 getErrPrintWriter().println("Error: Unknown option: " + opt);
2706 return -1;
2707 }
2708 }
2709
2710 userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning");
2711
2712 final String packageName = getNextArgRequired();
2713 final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId);
2714 if (!TextUtils.isEmpty(warning)) {
2715 getOutPrintWriter().println(warning);
2716 return 0;
2717 } else {
2718 return 1;
2719 }
2720 }
2721
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002722 private static String checkAbiArgument(String abi) {
2723 if (TextUtils.isEmpty(abi)) {
2724 throw new IllegalArgumentException("Missing ABI argument");
2725 }
2726
2727 if ("-".equals(abi)) {
2728 return abi;
2729 }
2730
2731 final String[] supportedAbis = Build.SUPPORTED_ABIS;
2732 for (String supportedAbi : supportedAbis) {
2733 if (supportedAbi.equals(abi)) {
2734 return abi;
2735 }
2736 }
2737
2738 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2739 }
2740
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002741 private int translateUserId(int userId, boolean allowAll, String logContext) {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002742 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002743 userId, allowAll, true, logContext, "pm command");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002744 }
2745
2746 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2747 throws RemoteException {
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002748 userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002749 if (userId == UserHandle.USER_ALL) {
2750 userId = UserHandle.USER_SYSTEM;
2751 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2752 }
2753
2754 final int sessionId = mInterface.getPackageInstaller()
2755 .createSession(params, installerPackageName, userId);
2756 return sessionId;
2757 }
2758
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002759 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002760 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002761 PackageInstaller.Session session = null;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002762 try {
Jeff Sharkeya651b782018-07-23 13:45:28 -06002763 final PrintWriter pw = getOutPrintWriter();
2764 final ParcelFileDescriptor fd;
2765 if (STDIN_PATH.equals(inPath)) {
2766 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2767 } else if (inPath != null) {
2768 fd = openFileForSystem(inPath, "r");
2769 if (fd == null) {
2770 return -1;
2771 }
2772 sizeBytes = fd.getStatSize();
2773 if (sizeBytes < 0) {
2774 getErrPrintWriter().println("Unable to get size of: " + inPath);
2775 return -1;
2776 }
2777 } else {
2778 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2779 }
2780 if (sizeBytes <= 0) {
2781 getErrPrintWriter().println("Error: must specify a APK size");
2782 return 1;
2783 }
2784
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002785 session = new PackageInstaller.Session(
2786 mInterface.getPackageInstaller().openSession(sessionId));
Jeff Sharkey0451de62018-02-02 11:27:21 -07002787 session.write(splitName, 0, sizeBytes, fd);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002788
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002789 if (logSuccess) {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002790 pw.println("Success: streamed " + sizeBytes + " bytes");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002791 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002792 return 0;
2793 } catch (IOException e) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002794 getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002795 return 1;
2796 } finally {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002797 IoUtils.closeQuietly(session);
2798 }
2799 }
2800
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002801 private int doInstallAddSession(int parentId, int[] sessionIds, boolean logSuccess)
2802 throws RemoteException {
2803 final PrintWriter pw = getOutPrintWriter();
2804 PackageInstaller.Session session = null;
2805 try {
2806 session = new PackageInstaller.Session(
2807 mInterface.getPackageInstaller().openSession(parentId));
2808 if (!session.isMultiPackage()) {
2809 getErrPrintWriter().println(
2810 "Error: parent session ID is not a multi-package session");
2811 return 1;
2812 }
2813 for (int i = 0; i < sessionIds.length; i++) {
2814 session.addChildSessionId(sessionIds[i]);
2815 }
2816 if (logSuccess) {
2817 pw.println("Success");
2818 }
2819 return 0;
2820 } finally {
2821 IoUtils.closeQuietly(session);
2822 }
2823 }
2824
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002825 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2826 throws RemoteException {
2827 final PrintWriter pw = getOutPrintWriter();
2828 PackageInstaller.Session session = null;
2829 try {
2830 session = new PackageInstaller.Session(
2831 mInterface.getPackageInstaller().openSession(sessionId));
2832 session.removeSplit(splitName);
2833
2834 if (logSuccess) {
2835 pw.println("Success");
2836 }
2837 return 0;
2838 } catch (IOException e) {
2839 pw.println("Error: failed to remove split; " + e.getMessage());
2840 return 1;
2841 } finally {
2842 IoUtils.closeQuietly(session);
2843 }
2844 }
2845
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002846 private int doCommitSession(int sessionId, boolean logSuccess)
2847 throws RemoteException {
2848
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002849 final PrintWriter pw = getOutPrintWriter();
2850 PackageInstaller.Session session = null;
2851 try {
2852 session = new PackageInstaller.Session(
2853 mInterface.getPackageInstaller().openSession(sessionId));
Dario Frenia8f4b132018-12-30 00:36:49 +00002854 if (!session.isMultiPackage() && !session.isStaged()) {
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002855 // Sanity check that all .dm files match an apk.
2856 // (The installer does not support standalone .dm files and will not process them.)
2857 try {
2858 DexMetadataHelper.validateDexPaths(session.getNames());
2859 } catch (IllegalStateException | IOException e) {
2860 pw.println(
2861 "Warning [Could not validate the dex paths: " + e.getMessage() + "]");
2862 }
Calin Juravle3fc56c32017-12-11 18:26:13 -08002863 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002864 final LocalIntentReceiver receiver = new LocalIntentReceiver();
2865 session.commit(receiver.getIntentSender());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002866 final Intent result = receiver.getResult();
2867 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2868 PackageInstaller.STATUS_FAILURE);
2869 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002870 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07002871 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002872 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002873 } else {
2874 pw.println("Failure ["
2875 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002876 }
2877 return status;
2878 } finally {
2879 IoUtils.closeQuietly(session);
2880 }
2881 }
2882
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002883 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002884 final PrintWriter pw = getOutPrintWriter();
2885 PackageInstaller.Session session = null;
2886 try {
2887 session = new PackageInstaller.Session(
2888 mInterface.getPackageInstaller().openSession(sessionId));
2889 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002890 if (logSuccess) {
2891 pw.println("Success");
2892 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002893 return 0;
2894 } finally {
2895 IoUtils.closeQuietly(session);
2896 }
2897 }
2898
Todd Kennedy60459ab2015-10-30 11:32:16 -07002899 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2900 boolean summary, int startProtectionLevel, int endProtectionLevel)
2901 throws RemoteException {
2902 final PrintWriter pw = getOutPrintWriter();
2903 final int groupCount = groupList.size();
2904 for (int i = 0; i < groupCount; i++) {
2905 String groupName = groupList.get(i);
2906 String prefix = "";
2907 if (groups) {
2908 if (i > 0) {
2909 pw.println("");
2910 }
2911 if (groupName != null) {
2912 PermissionGroupInfo pgi =
2913 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2914 if (summary) {
2915 Resources res = getResources(pgi);
2916 if (res != null) {
2917 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2918 } else {
2919 pw.print(pgi.name + ": ");
2920
2921 }
2922 } else {
2923 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2924 if (labels) {
2925 pw.println(" package:" + pgi.packageName);
2926 Resources res = getResources(pgi);
2927 if (res != null) {
2928 pw.println(" label:"
2929 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
2930 pw.println(" description:"
2931 + loadText(pgi, pgi.descriptionRes,
2932 pgi.nonLocalizedDescription));
2933 }
2934 }
2935 }
2936 } else {
2937 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
2938 }
2939 prefix = " ";
2940 }
Todd Kennedy1d29b4a2019-07-02 14:49:28 -07002941 List<PermissionInfo> ps = mPermissionManager
2942 .queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07002943 final int count = ps.size();
2944 boolean first = true;
2945 for (int p = 0 ; p < count ; p++) {
2946 PermissionInfo pi = ps.get(p);
2947 if (groups && groupName == null && pi.group != null) {
2948 continue;
2949 }
2950 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
2951 if (base < startProtectionLevel
2952 || base > endProtectionLevel) {
2953 continue;
2954 }
2955 if (summary) {
2956 if (first) {
2957 first = false;
2958 } else {
2959 pw.print(", ");
2960 }
2961 Resources res = getResources(pi);
2962 if (res != null) {
2963 pw.print(loadText(pi, pi.labelRes,
2964 pi.nonLocalizedLabel));
2965 } else {
2966 pw.print(pi.name);
2967 }
2968 } else {
2969 pw.println(prefix + (labels ? "+ " : "")
2970 + "permission:" + pi.name);
2971 if (labels) {
2972 pw.println(prefix + " package:" + pi.packageName);
2973 Resources res = getResources(pi);
2974 if (res != null) {
2975 pw.println(prefix + " label:"
2976 + loadText(pi, pi.labelRes,
2977 pi.nonLocalizedLabel));
2978 pw.println(prefix + " description:"
2979 + loadText(pi, pi.descriptionRes,
2980 pi.nonLocalizedDescription));
2981 }
2982 pw.println(prefix + " protectionLevel:"
2983 + PermissionInfo.protectionToString(pi.protectionLevel));
2984 }
2985 }
2986 }
2987
2988 if (summary) {
2989 pw.println("");
2990 }
2991 }
2992 }
2993
2994 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
2995 throws RemoteException {
2996 if (nonLocalized != null) {
2997 return nonLocalized.toString();
2998 }
2999 if (res != 0) {
3000 Resources r = getResources(pii);
3001 if (r != null) {
3002 try {
3003 return r.getString(res);
3004 } catch (Resources.NotFoundException e) {
3005 }
3006 }
3007 }
3008 return null;
3009 }
3010
3011 private Resources getResources(PackageItemInfo pii) throws RemoteException {
3012 Resources res = mResourceCache.get(pii.packageName);
3013 if (res != null) return res;
3014
Patrick Baumannbc883f62019-05-21 11:20:11 -07003015 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName,
3016 PackageManager.MATCH_DISABLED_COMPONENTS
3017 | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
3018 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, 0);
Todd Kennedy60459ab2015-10-30 11:32:16 -07003019 AssetManager am = new AssetManager();
3020 am.addAssetPath(ai.publicSourceDir);
3021 res = new Resources(am, null, null);
3022 mResourceCache.put(pii.packageName, res);
3023 return res;
3024 }
3025
3026 @Override
3027 public void onHelp() {
3028 final PrintWriter pw = getOutPrintWriter();
3029 pw.println("Package manager (package) commands:");
3030 pw.println(" help");
3031 pw.println(" Print this help text.");
3032 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003033 pw.println(" path [--user USER_ID] PACKAGE");
3034 pw.println(" Print the path to the .apk of the given PACKAGE.");
3035 pw.println("");
3036 pw.println(" dump PACKAGE");
3037 pw.println(" Print various system state associated with the given PACKAGE.");
3038 pw.println("");
3039 pw.println(" list features");
3040 pw.println(" Prints all features of the system.");
3041 pw.println("");
3042 pw.println(" has-feature FEATURE_NAME [version]");
3043 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,");
3044 pw.println(" otherwise prints false and returns exit status 1");
3045 pw.println("");
3046 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
3047 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
3048 pw.println(" Options:");
3049 pw.println(" -f: dump the name of the .apk file containing the test package");
3050 pw.println("");
3051 pw.println(" list libraries");
3052 pw.println(" Prints all system libraries.");
3053 pw.println("");
3054 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
Jiyong Parkf50a2932018-12-17 13:54:40 +09003055 pw.println(" [--show-versioncode] [--apex-only] [--uid UID] [--user USER_ID] [FILTER]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003056 pw.println(" Prints all packages; optionally only those whose name contains");
3057 pw.println(" the text in FILTER. Options are:");
3058 pw.println(" -f: see their associated file");
Jiyong Park4f49abe2018-12-11 13:37:17 +09003059 pw.println(" -a: all known packages (but excluding APEXes)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003060 pw.println(" -d: filter to only show disabled packages");
3061 pw.println(" -e: filter to only show enabled packages");
3062 pw.println(" -s: filter to only show system packages");
3063 pw.println(" -3: filter to only show third party packages");
3064 pw.println(" -i: see the installer for the packages");
3065 pw.println(" -l: ignored (used for compatibility with older releases)");
3066 pw.println(" -U: also show the package UID");
3067 pw.println(" -u: also include uninstalled packages");
Jiyong Parkf50a2932018-12-17 13:54:40 +09003068 pw.println(" --show-versioncode: also show the version code");
Jiyong Park4f49abe2018-12-11 13:37:17 +09003069 pw.println(" --apex-only: only show APEX packages");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003070 pw.println(" --uid UID: filter to only show packages with the given UID");
3071 pw.println(" --user USER_ID: only list packages belonging to the given user");
3072 pw.println("");
3073 pw.println(" list permission-groups");
3074 pw.println(" Prints all known permission groups.");
3075 pw.println("");
3076 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
3077 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:");
3078 pw.println(" -g: organize by group");
3079 pw.println(" -f: print all information");
3080 pw.println(" -s: short summary");
3081 pw.println(" -d: only list dangerous permissions");
3082 pw.println(" -u: list only the permissions users will see");
3083 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003084 pw.println(" resolve-activity [--brief] [--components] [--query-flags FLAGS]");
3085 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003086 pw.println(" Prints the activity that resolves to the given INTENT.");
3087 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003088 pw.println(" query-activities [--brief] [--components] [--query-flags FLAGS]");
3089 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003090 pw.println(" Prints all activities that can handle the given INTENT.");
3091 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003092 pw.println(" query-services [--brief] [--components] [--query-flags FLAGS]");
3093 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003094 pw.println(" Prints all services that can handle the given INTENT.");
3095 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07003096 pw.println(" query-receivers [--brief] [--components] [--query-flags FLAGS]");
3097 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003098 pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
3099 pw.println("");
Todd Kennedyc76161702019-08-26 10:10:59 -07003100 pw.println(" install [-rtsfdgw] [-i PACKAGE] [--user USER_ID|all|current]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003101 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003102 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
3103 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003104 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
Richard Uhlerb29f1452018-09-12 16:38:15 +01003105 pw.println(" [--enable-rollback]");
Mohammad Samiul Islambd02f422019-05-17 18:02:12 +01003106 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
3107 pw.println(" [--apex] [--wait TIMEOUT]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003108 pw.println(" [PATH|-]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003109 pw.println(" Install an application. Must provide the apk data to install, either as a");
3110 pw.println(" file path or '-' to read from stdin. Options are:");
Patrick Baumanna9333492017-11-28 15:23:49 -08003111 pw.println(" -R: disallow replacement of existing application");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003112 pw.println(" -t: allow test packages");
3113 pw.println(" -i: specify package name of installer owning the app");
3114 pw.println(" -s: install application on sdcard");
3115 pw.println(" -f: install application on internal flash");
3116 pw.println(" -d: allow version code downgrade (debuggable packages only)");
3117 pw.println(" -p: partial application install (new split on top of existing pkg)");
3118 pw.println(" -g: grant all runtime permissions");
3119 pw.println(" -S: size in bytes of package, required for stdin");
3120 pw.println(" --user: install under the given user.");
3121 pw.println(" --dont-kill: installing a new feature split, don't kill running app");
Svet Ganov83a3a4a2019-05-03 18:50:43 -07003122 pw.println(" --restrict-permissions: don't whitelist restricted permissions at install");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003123 pw.println(" --originating-uri: set URI where app was downloaded from");
3124 pw.println(" --referrer: set URI that instigated the install of the app");
3125 pw.println(" --pkg: specify expected package name of app being installed");
3126 pw.println(" --abi: override the default ABI of the platform");
3127 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app");
3128 pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
3129 pw.println(" --install-location: force the install location:");
3130 pw.println(" 0=auto, 1=internal only, 2=prefer external");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003131 pw.println(" --install-reason: indicates why the app is being installed:");
3132 pw.println(" 0=unknown, 1=admin policy, 2=device restore,");
3133 pw.println(" 3=device setup, 4=user request");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003134 pw.println(" --force-uuid: force install on to disk volume with given UUID");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003135 pw.println(" --apex: install an .apex file, not an .apk");
Mohammad Samiul Islambd02f422019-05-17 18:02:12 +01003136 pw.println(" --wait: when performing staged install, wait TIMEOUT milliseconds");
3137 pw.println(" for pre-reboot verification to complete. If TIMEOUT is not");
3138 pw.println(" specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003139 pw.println("");
3140 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
3141 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07003142 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
3143 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003144 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01003145 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [--apex] [-S BYTES]");
Dario Freniaac4ba42018-12-06 15:47:16 +00003146 pw.println(" [--multi-package] [--staged]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003147 pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
3148 pw.println(" to push data into the session, and \"install-commit\" to finish.");
3149 pw.println("");
3150 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
3151 pw.println(" Write an apk into the given install session. If the path is '-', data");
3152 pw.println(" will be read from stdin. Options are:");
3153 pw.println(" -S: size in bytes of package, required for stdin");
3154 pw.println("");
Patrick Baumann0aff9b12018-11-08 14:05:08 +00003155 pw.println(" install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs");
3156 pw.println(" Add one or more session IDs to a multi-package session.");
3157 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003158 pw.println(" install-commit SESSION_ID");
3159 pw.println(" Commit the given active install session, installing the app.");
3160 pw.println("");
3161 pw.println(" install-abandon SESSION_ID");
3162 pw.println(" Delete the given active install session.");
3163 pw.println("");
3164 pw.println(" set-install-location LOCATION");
3165 pw.println(" Changes the default install location. NOTE this is only intended for debugging;");
3166 pw.println(" using this can cause applications to break and other undersireable behavior.");
3167 pw.println(" LOCATION is one of:");
3168 pw.println(" 0 [auto]: Let system decide the best location");
3169 pw.println(" 1 [internal]: Install on internal device storage");
3170 pw.println(" 2 [external]: Install on external media");
3171 pw.println("");
3172 pw.println(" get-install-location");
3173 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location.");
3174 pw.println("");
3175 pw.println(" move-package PACKAGE [internal|UUID]");
3176 pw.println("");
3177 pw.println(" move-primary-storage [internal|UUID]");
3178 pw.println("");
3179 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
3180 pw.println(" Remove the given package name from the system. May remove an entire app");
3181 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
3182 pw.println(" given app. Options are:");
3183 pw.println(" -k: keep the data and cache directories around after package removal.");
3184 pw.println(" --user: remove the app from the given user.");
3185 pw.println(" --versionCode: only uninstall if the app has the given version code.");
3186 pw.println("");
3187 pw.println(" clear [--user USER_ID] PACKAGE");
3188 pw.println(" Deletes all data associated with a package.");
3189 pw.println("");
3190 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT");
3191 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT");
3192 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
3193 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
3194 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
3195 pw.println(" These commands change the enabled state of a given package or");
3196 pw.println(" component (written as \"package/class\").");
3197 pw.println("");
3198 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT");
3199 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
3200 pw.println("");
3201 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
3202 pw.println(" Suspends the specified package (as user).");
3203 pw.println("");
3204 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
3205 pw.println(" Unsuspends the specified package (as user).");
3206 pw.println("");
3207 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
3208 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
3209 pw.println(" These commands either grant or revoke permissions to apps. The permissions");
3210 pw.println(" must be declared as used in the app's manifest, be runtime permissions");
3211 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
3212 pw.println("");
3213 pw.println(" reset-permissions");
3214 pw.println(" Revert all runtime permissions to their default state.");
3215 pw.println("");
3216 pw.println(" set-permission-enforced PERMISSION [true|false]");
3217 pw.println("");
3218 pw.println(" get-privapp-permissions TARGET-PACKAGE");
3219 pw.println(" Prints all privileged permissions for a package.");
3220 pw.println("");
3221 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE");
3222 pw.println(" Prints all privileged permissions that are denied for a package.");
3223 pw.println("");
3224 pw.println(" get-oem-permissions TARGET-PACKAGE");
3225 pw.println(" Prints all OEM permissions for a package.");
3226 pw.println("");
3227 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
3228 pw.println(" get-app-link [--user USER_ID] PACKAGE");
3229 pw.println("");
3230 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
3231 pw.println(" Trim cache files to reach the given free space.");
3232 pw.println("");
3233 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
3234 pw.println(" [--guest] USER_NAME");
3235 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
3236 pw.println(" of the user.");
3237 pw.println("");
3238 pw.println(" remove-user USER_ID");
3239 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data");
3240 pw.println(" associated with that user");
3241 pw.println("");
3242 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE");
3243 pw.println("");
3244 pw.println(" get-max-users");
3245 pw.println("");
Alex Chauc12189b2018-01-16 15:01:15 +00003246 pw.println(" get-max-running-users");
3247 pw.println("");
Calin Juravleb6f844d2017-07-17 15:23:21 -07003248 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
Richard Uhler568a9692016-05-03 16:02:52 -07003249 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003250 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
David Brazdil990fb6b2016-03-01 10:02:27 +00003251 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00003252 pw.println(" -c: clear profile data before compiling");
3253 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00003254 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07003255 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01003256 pw.println(" assume-verified");
3257 pw.println(" extract");
3258 pw.println(" verify");
3259 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07003260 pw.println(" space-profile");
3261 pw.println(" space");
3262 pw.println(" speed-profile");
3263 pw.println(" speed");
3264 pw.println(" everything");
3265 pw.println(" -r: select compilation reason");
3266 pw.println(" REASON is one of:");
3267 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
3268 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
3269 }
David Brazdilcf046952016-03-08 16:40:20 +00003270 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07003271 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08003272 pw.println(" --secondary-dex: compile app secondary dex files");
Calin Juravleb6f844d2017-07-17 15:23:21 -07003273 pw.println(" --split SPLIT: compile only the given split name");
Eric Holka1485f62019-01-07 13:58:25 -08003274 pw.println(" --compile-layouts: compile layout resources for faster inflation");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003275 pw.println("");
3276 pw.println(" force-dex-opt PACKAGE");
3277 pw.println(" Force immediate execution of dex opt for the given PACKAGE.");
3278 pw.println("");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08003279 pw.println(" bg-dexopt-job");
3280 pw.println(" Execute the background optimizations immediately.");
3281 pw.println(" Note that the command only runs the background optimizer logic. It may");
3282 pw.println(" overlap with the actual job but the job scheduler will not be able to");
3283 pw.println(" cancel it. It will also run even if the device is not in the idle");
3284 pw.println(" maintenance mode.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003285 pw.println("");
Calin Juravle1aa5f882017-01-25 01:05:50 -08003286 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
3287 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003288 pw.println("");
David Sehrcae13b02016-06-07 09:11:27 -07003289 pw.println(" dump-profiles TARGET-PACKAGE");
3290 pw.println(" Dumps method/class profile files to");
Calin Juravle21216c62018-05-04 17:35:29 -07003291 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt");
3292 pw.println("");
3293 pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]");
3294 pw.println(" Take a snapshot of the package profiles to");
3295 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
3296 + "TARGET-PACKAGE[-code-path].prof");
3297 pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003298 pw.println("");
Makoto Onuki4828a592016-03-15 18:06:57 -07003299 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003300 pw.println(" Set the default home activity (aka launcher).");
Bookatz2b5a6012019-04-16 19:41:28 -07003301 pw.println(" TARGET-COMPONENT can be a package name (com.package.my) or a full");
3302 pw.println(" component (com.package.my/component.name). However, only the package name");
3303 pw.println(" matters: the actual component used will be determined automatically from");
3304 pw.println(" the package.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003305 pw.println("");
3306 pw.println(" set-installer PACKAGE INSTALLER");
3307 pw.println(" Set installer package name");
3308 pw.println("");
3309 pw.println(" get-instantapp-resolver");
3310 pw.println(" Return the name of the component that is the current instant app installer.");
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08003311 pw.println("");
3312 pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
3313 pw.println(" Mark the app as harmful with the given warning message.");
Ben Gruver9ef60092018-01-10 11:32:30 -08003314 pw.println("");
3315 pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
3316 pw.println(" Return the harmful app warning message for the given app, if present");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003317 pw.println();
Patrick Baumanna980e142018-02-12 11:45:23 -08003318 pw.println(" uninstall-system-updates");
3319 pw.println(" Remove updates to all system applications and fall back to their /system " +
3320 "version.");
3321 pw.println();
Mohammad Samiul Islamc46ff382019-05-09 15:36:21 +01003322 pw.println(" get-moduleinfo [--all | --installed] [module-name]");
3323 pw.println(" Displays module info. If module-name is specified only that info is shown");
3324 pw.println(" By default, without any argument only installed modules are shown.");
3325 pw.println(" --all: show all module info");
3326 pw.println(" --installed: show only installed modules");
3327 pw.println("");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003328 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07003329 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003330
3331 private static class LocalIntentReceiver {
wangmingming155414292018-04-10 09:35:25 +08003332 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003333
3334 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
3335 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07003336 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003337 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
3338 try {
3339 mResult.offer(intent, 5, TimeUnit.SECONDS);
3340 } catch (InterruptedException e) {
3341 throw new RuntimeException(e);
3342 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003343 }
3344 };
3345
3346 public IntentSender getIntentSender() {
3347 return new IntentSender((IIntentSender) mLocalSender);
3348 }
3349
3350 public Intent getResult() {
3351 try {
3352 return mResult.take();
3353 } catch (InterruptedException e) {
3354 throw new RuntimeException(e);
3355 }
3356 }
3357 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07003358}