blob: 114810d9127bc3878fcee0cece5d6291eea80eb6 [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;
Todd Kennedy60459ab2015-10-30 11:32:16 -070028import android.content.ComponentName;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070029import android.content.Context;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080030import android.content.IIntentReceiver;
31import android.content.IIntentSender;
32import android.content.Intent;
33import android.content.IntentSender;
Todd Kennedy60459ab2015-10-30 11:32:16 -070034import android.content.pm.ApplicationInfo;
35import android.content.pm.FeatureInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070036import android.content.pm.IPackageDataObserver;
Patrick Baumanna980e142018-02-12 11:45:23 -080037import android.content.pm.IPackageInstaller;
Todd Kennedy60459ab2015-10-30 11:32:16 -070038import android.content.pm.IPackageManager;
39import android.content.pm.InstrumentationInfo;
40import android.content.pm.PackageInfo;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080041import android.content.pm.PackageInstaller;
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +000042import android.content.pm.PackageInstaller.SessionInfo;
Jeff Sharkey0451de62018-02-02 11:27:21 -070043import android.content.pm.PackageInstaller.SessionParams;
Todd Kennedy60459ab2015-10-30 11:32:16 -070044import android.content.pm.PackageItemInfo;
45import android.content.pm.PackageManager;
Jeff Sharkey0451de62018-02-02 11:27:21 -070046import android.content.pm.PackageManager.NameNotFoundException;
Dario Freni788ecb12019-01-23 18:49:32 +000047import android.content.pm.PackageManagerInternal;
Shunta Sato4f26cb52016-06-28 09:29:19 +090048import android.content.pm.PackageParser;
49import android.content.pm.PackageParser.ApkLite;
50import android.content.pm.PackageParser.PackageLite;
51import android.content.pm.PackageParser.PackageParserException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070052import android.content.pm.ParceledListSlice;
53import android.content.pm.PermissionGroupInfo;
54import android.content.pm.PermissionInfo;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080055import android.content.pm.ResolveInfo;
Suprabh Shukla389cb6f2018-10-01 18:20:39 -070056import android.content.pm.SuspendDialogInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070057import android.content.pm.UserInfo;
Svet Ganov67882122016-12-11 16:36:34 -080058import android.content.pm.VersionedPackage;
Calin Juravle21216c62018-05-04 17:35:29 -070059import android.content.pm.dex.ArtManager;
Calin Juravle3fc56c32017-12-11 18:26:13 -080060import android.content.pm.dex.DexMetadataHelper;
Calin Juravle21216c62018-05-04 17:35:29 -070061import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
Todd Kennedy60459ab2015-10-30 11:32:16 -070062import android.content.res.AssetManager;
63import android.content.res.Resources;
Narayan Kamathc5d752e2019-01-23 14:06:35 +000064import android.content.rollback.IRollbackManager;
65import android.content.rollback.PackageRollbackInfo;
66import android.content.rollback.RollbackInfo;
67import android.content.rollback.RollbackManager;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080068import android.net.Uri;
69import android.os.Binder;
70import android.os.Build;
71import android.os.Bundle;
Dianne Hackborn98305522017-05-05 17:53:53 -070072import android.os.IBinder;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070073import android.os.IUserManager;
Dianne Hackbornca3872c2017-10-30 14:19:32 -070074import android.os.ParcelFileDescriptor;
Calin Juravle21216c62018-05-04 17:35:29 -070075import android.os.ParcelFileDescriptor.AutoCloseInputStream;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080076import android.os.PersistableBundle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070077import android.os.Process;
Todd Kennedy60459ab2015-10-30 11:32:16 -070078import android.os.RemoteException;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070079import android.os.ServiceManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070080import android.os.ShellCommand;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070081import android.os.SystemClock;
Calin Juravle8bc758b2016-03-28 12:31:52 +010082import android.os.SystemProperties;
Todd Kennedy60459ab2015-10-30 11:32:16 -070083import android.os.UserHandle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070084import android.os.UserManager;
85import android.os.storage.StorageManager;
Calin Juravlebdd94d92018-05-17 01:23:15 -070086import android.system.ErrnoException;
87import android.system.Os;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080088import android.text.TextUtils;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070089import android.text.format.DateUtils;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080090import android.util.ArraySet;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080091import android.util.PrintWriterPrinter;
Dario Freni2bef1762018-06-01 14:02:08 +010092
Shunta Sato4f26cb52016-06-28 09:29:19 +090093import com.android.internal.content.PackageHelper;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070094import com.android.internal.util.ArrayUtils;
Alex Chauc12189b2018-01-16 15:01:15 +000095import com.android.server.LocalServices;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080096import com.android.server.SystemConfig;
Dario Freni2bef1762018-06-01 14:02:08 +010097
Andreas Gampebdd30d82016-03-20 11:32:11 -070098import dalvik.system.DexFile;
Dario Freni2bef1762018-06-01 14:02:08 +010099
100import libcore.io.IoUtils;
101import libcore.io.Streams;
102
Calin Juravle21216c62018-05-04 17:35:29 -0700103import java.io.File;
104import java.io.FileOutputStream;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800105import java.io.IOException;
Calin Juravle21216c62018-05-04 17:35:29 -0700106import java.io.InputStream;
107import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700108import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800109import java.net.URISyntaxException;
Calin Juravle21216c62018-05-04 17:35:29 -0700110import java.util.ArrayList;
111import java.util.Collections;
112import java.util.Comparator;
113import java.util.LinkedList;
114import java.util.List;
115import java.util.Map;
116import java.util.Objects;
117import java.util.WeakHashMap;
118import java.util.concurrent.CountDownLatch;
wangmingming155414292018-04-10 09:35:25 +0800119import java.util.concurrent.LinkedBlockingQueue;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800120import java.util.concurrent.TimeUnit;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700121
122class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700123 /** Path for streaming APK content */
124 private static final String STDIN_PATH = "-";
Calin Juravle21216c62018-05-04 17:35:29 -0700125 /** Path where ART profiles snapshots are dumped for the shell user */
126 private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700127
Todd Kennedy60459ab2015-10-30 11:32:16 -0700128 final IPackageManager mInterface;
129 final private WeakHashMap<String, Resources> mResourceCache =
130 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800131 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700132 boolean mBrief;
133 boolean mComponents;
Ng Zhi An73971312018-09-11 21:39:14 -0700134 int mQueryFlags;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700135
136 PackageManagerShellCommand(PackageManagerService service) {
137 mInterface = service;
138 }
139
140 @Override
141 public int onCommand(String cmd) {
142 if (cmd == null) {
143 return handleDefaultCommands(cmd);
144 }
145
146 final PrintWriter pw = getOutPrintWriter();
147 try {
148 switch(cmd) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700149 case "path":
150 return runPath();
151 case "dump":
152 return runDump();
153 case "list":
154 return runList();
155 case "resolve-activity":
156 return runResolveActivity();
157 case "query-activities":
158 return runQueryIntentActivities();
159 case "query-services":
160 return runQueryIntentServices();
161 case "query-receivers":
162 return runQueryIntentReceivers();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800163 case "install":
164 return runInstall();
165 case "install-abandon":
166 case "install-destroy":
167 return runInstallAbandon();
168 case "install-commit":
169 return runInstallCommit();
170 case "install-create":
171 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800172 case "install-remove":
173 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800174 case "install-write":
175 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800176 case "install-existing":
177 return runInstallExisting();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700178 case "set-install-location":
179 return runSetInstallLocation();
180 case "get-install-location":
181 return runGetInstallLocation();
Patrick Baumann0aff9b12018-11-08 14:05:08 +0000182 case "install-add-session":
183 return runInstallAddSession();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700184 case "move-package":
185 return runMovePackage();
186 case "move-primary-storage":
187 return runMovePrimaryStorage();
David Brazdil493411a2016-02-01 13:48:46 +0000188 case "compile":
189 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800190 case "reconcile-secondary-dex-files":
191 return runreconcileSecondaryDexFiles();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700192 case "force-dex-opt":
193 return runForceDexOpt();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800194 case "bg-dexopt-job":
195 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700196 case "dump-profiles":
197 return runDumpProfiles();
Calin Juravle21216c62018-05-04 17:35:29 -0700198 case "snapshot-profile":
199 return runSnapshotProfile();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800200 case "uninstall":
201 return runUninstall();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700202 case "clear":
203 return runClear();
204 case "enable":
205 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
206 case "disable":
207 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
208 case "disable-user":
209 return runSetEnabledSetting(
210 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
211 case "disable-until-used":
212 return runSetEnabledSetting(
213 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
214 case "default-state":
215 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
216 case "hide":
217 return runSetHiddenSetting(true);
218 case "unhide":
219 return runSetHiddenSetting(false);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000220 case "suspend":
221 return runSuspend(true);
222 case "unsuspend":
223 return runSuspend(false);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700224 case "grant":
225 return runGrantRevokePermission(true);
226 case "revoke":
227 return runGrantRevokePermission(false);
228 case "reset-permissions":
229 return runResetPermissions();
230 case "set-permission-enforced":
231 return runSetPermissionEnforced();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800232 case "get-privapp-permissions":
233 return runGetPrivappPermissions();
Todd Kennedy74629e32017-08-15 14:48:07 -0700234 case "get-privapp-deny-permissions":
235 return runGetPrivappDenyPermissions();
Svet Ganov087dce22017-09-07 15:42:16 -0700236 case "get-oem-permissions":
237 return runGetOemPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700238 case "set-app-link":
239 return runSetAppLink();
240 case "get-app-link":
241 return runGetAppLink();
242 case "trim-caches":
243 return runTrimCaches();
244 case "create-user":
245 return runCreateUser();
246 case "remove-user":
247 return runRemoveUser();
248 case "set-user-restriction":
249 return runSetUserRestriction();
250 case "get-max-users":
251 return runGetMaxUsers();
Alex Chauc12189b2018-01-16 15:01:15 +0000252 case "get-max-running-users":
253 return runGetMaxRunningUsers();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700254 case "set-home-activity":
255 return runSetHomeActivity();
256 case "set-installer":
257 return runSetInstaller();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700258 case "get-instantapp-resolver":
259 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900260 case "has-feature":
261 return runHasFeature();
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800262 case "set-harmful-app-warning":
263 return runSetHarmfulAppWarning();
Ben Gruver9ef60092018-01-10 11:32:30 -0800264 case "get-harmful-app-warning":
265 return runGetHarmfulAppWarning();
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000266 case "get-stagedsessions":
267 return getStagedSessions();
Patrick Baumanna980e142018-02-12 11:45:23 -0800268 case "uninstall-system-updates":
269 return uninstallSystemUpdates();
Narayan Kamathc5d752e2019-01-23 14:06:35 +0000270 case "rollback-app":
271 return runRollbackApp();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700272 default: {
273 String nextArg = getNextArg();
274 if (nextArg == null) {
275 if (cmd.equalsIgnoreCase("-l")) {
276 return runListPackages(false);
277 } else if (cmd.equalsIgnoreCase("-lf")) {
278 return runListPackages(true);
279 }
280 } else if (getNextArg() == null) {
281 if (cmd.equalsIgnoreCase("-p")) {
282 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
283 }
284 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700285 return handleDefaultCommands(cmd);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700286 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700287 }
288 } catch (RemoteException e) {
289 pw.println("Remote exception: " + e);
290 }
291 return -1;
292 }
293
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000294 private int getStagedSessions() {
295 final PrintWriter pw = getOutPrintWriter();
296 try {
297 List<SessionInfo> stagedSessionsList =
298 mInterface.getPackageInstaller().getStagedSessions().getList();
299 for (SessionInfo session: stagedSessionsList) {
300 pw.println("appPackageName = " + session.getAppPackageName()
301 + "; sessionId = " + session.getSessionId()
302 + "; isStaged = " + session.isStaged()
Dario Freni60a96c12019-02-24 21:01:29 +0000303 + "; isStagedSessionReady = " + session.isStagedSessionReady()
304 + "; isStagedSessionApplied = " + session.isStagedSessionApplied()
305 + "; isStagedSessionFailed = " + session.isStagedSessionFailed() + ";");
Abhijeet Kaur84b1f5d2019-01-21 17:18:03 +0000306 }
307 } catch (RemoteException e) {
308 pw.println("Failure ["
309 + e.getClass().getName() + " - "
310 + e.getMessage() + "]");
311 return 0;
312 }
313 return 1;
314 }
315
Patrick Baumanna980e142018-02-12 11:45:23 -0800316 private int uninstallSystemUpdates() {
317 final PrintWriter pw = getOutPrintWriter();
318 List<String> failedUninstalls = new LinkedList<>();
319 try {
320 final ParceledListSlice<ApplicationInfo> packages =
321 mInterface.getInstalledApplications(
322 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
323 final IPackageInstaller installer = mInterface.getPackageInstaller();
324 List<ApplicationInfo> list = packages.getList();
325 for (ApplicationInfo info : list) {
326 if (info.isUpdatedSystemApp()) {
327 pw.println("Uninstalling updates to " + info.packageName + "...");
328 final LocalIntentReceiver receiver = new LocalIntentReceiver();
329 installer.uninstall(new VersionedPackage(info.packageName,
330 info.versionCode), null /*callerPackageName*/, 0 /* flags */,
331 receiver.getIntentSender(), 0);
332
333 final Intent result = receiver.getResult();
334 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
335 PackageInstaller.STATUS_FAILURE);
336 if (status != PackageInstaller.STATUS_SUCCESS) {
337 failedUninstalls.add(info.packageName);
338 }
339 }
340 }
341 } catch (RemoteException e) {
342 pw.println("Failure ["
343 + e.getClass().getName() + " - "
344 + e.getMessage() + "]");
345 return 0;
346 }
347 if (!failedUninstalls.isEmpty()) {
348 pw.println("Failure [Couldn't uninstall packages: "
349 + TextUtils.join(", ", failedUninstalls)
350 + "]");
351 return 0;
352 }
353 pw.println("Success");
354 return 1;
355 }
356
Narayan Kamathc5d752e2019-01-23 14:06:35 +0000357 private int runRollbackApp() {
358 final PrintWriter pw = getOutPrintWriter();
359
360 final String packageName = getNextArgRequired();
361 if (packageName == null) {
362 pw.println("Error: package name not specified");
363 return 1;
364 }
365
366 final LocalIntentReceiver receiver = new LocalIntentReceiver();
367 try {
368 IRollbackManager rm = IRollbackManager.Stub.asInterface(
369 ServiceManager.getService(Context.ROLLBACK_SERVICE));
370
371 RollbackInfo rollback = null;
372 for (RollbackInfo r : (List<RollbackInfo>) rm.getAvailableRollbacks().getList()) {
373 for (PackageRollbackInfo info : r.getPackages()) {
374 if (packageName.equals(info.getPackageName())) {
375 rollback = r;
376 break;
377 }
378 }
379 }
380
381 if (rollback == null) {
382 pw.println("No available rollbacks for: " + packageName);
383 return 1;
384 }
385
386 rm.commitRollback(rollback.getRollbackId(),
387 ParceledListSlice.<VersionedPackage>emptyList(),
388 "com.android.shell", receiver.getIntentSender());
389 } catch (RemoteException re) {
390 // Cannot happen.
391 }
392
393 final Intent result = receiver.getResult();
394 final int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
395 RollbackManager.STATUS_FAILURE);
396 if (status == RollbackManager.STATUS_SUCCESS) {
397 pw.println("Success");
398 return 0;
399 } else {
400 pw.println("Failure ["
401 + result.getStringExtra(RollbackManager.EXTRA_STATUS_MESSAGE) + "]");
402 return 1;
403 }
404 }
405
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700406 private void setParamsSize(InstallParams params, String inPath) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700407 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700408 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
409 if (fd == null) {
410 getErrPrintWriter().println("Error: Can't open file: " + inPath);
411 throw new IllegalArgumentException("Error: Can't open file: " + inPath);
412 }
413 try {
414 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
415 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
416 null, null);
417 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
Dianne Hackborn1704e3c2017-10-31 19:55:42 +0000418 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700419 } catch (PackageParserException | IOException e) {
420 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
421 throw new IllegalArgumentException(
422 "Error: Failed to parse APK file: " + inPath, e);
423 } finally {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900424 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700425 fd.close();
426 } catch (IOException e) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900427 }
428 }
429 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700430 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700431 /**
432 * Displays the package file for a package.
433 * @param pckg
434 */
435 private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
436 PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId);
437 if (info != null && info.applicationInfo != null) {
438 final PrintWriter pw = getOutPrintWriter();
439 pw.print("package:");
440 pw.println(info.applicationInfo.sourceDir);
441 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
442 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
443 pw.print("package:");
444 pw.println(splitSourceDir);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800445 }
446 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700447 return 0;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800448 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700449 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800450 }
451
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700452 private int runPath() throws RemoteException {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000453 int userId = UserHandle.USER_SYSTEM;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700454 String option = getNextOption();
455 if (option != null && option.equals("--user")) {
456 userId = UserHandle.parseUserArg(getNextArgRequired());
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000457 }
458
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700459 String pkg = getNextArgRequired();
460 if (pkg == null) {
461 getErrPrintWriter().println("Error: no package specified");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000462 return 1;
463 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700464 return displayPackageFilePath(pkg, userId);
David Sehra8777082016-05-24 15:25:23 -0700465 }
466
Todd Kennedy60459ab2015-10-30 11:32:16 -0700467 private int runList() throws RemoteException {
468 final PrintWriter pw = getOutPrintWriter();
469 final String type = getNextArg();
470 if (type == null) {
471 pw.println("Error: didn't specify type of data to list");
472 return -1;
473 }
474 switch(type) {
475 case "features":
476 return runListFeatures();
477 case "instrumentation":
478 return runListInstrumentation();
479 case "libraries":
480 return runListLibraries();
481 case "package":
482 case "packages":
483 return runListPackages(false /*showSourceDir*/);
484 case "permission-groups":
485 return runListPermissionGroups();
486 case "permissions":
487 return runListPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700488 case "users":
489 ServiceManager.getService("user").shellCommand(
490 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
491 new String[] { "list" }, getShellCallback(), adoptResultReceiver());
492 return 0;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700493 }
494 pw.println("Error: unknown list type '" + type + "'");
495 return -1;
496 }
497
498 private int runListFeatures() throws RemoteException {
499 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700500 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700501
502 // sort by name
503 Collections.sort(list, new Comparator<FeatureInfo>() {
504 public int compare(FeatureInfo o1, FeatureInfo o2) {
505 if (o1.name == o2.name) return 0;
506 if (o1.name == null) return -1;
507 if (o2.name == null) return 1;
508 return o1.name.compareTo(o2.name);
509 }
510 });
511
512 final int count = (list != null) ? list.size() : 0;
513 for (int p = 0; p < count; p++) {
514 FeatureInfo fi = list.get(p);
515 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700516 if (fi.name != null) {
517 pw.print(fi.name);
518 if (fi.version > 0) {
519 pw.print("=");
520 pw.print(fi.version);
521 }
522 pw.println();
523 } else {
524 pw.println("reqGlEsVersion=0x"
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700525 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700526 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700527 }
528 return 0;
529 }
530
531 private int runListInstrumentation() throws RemoteException {
532 final PrintWriter pw = getOutPrintWriter();
533 boolean showSourceDir = false;
534 String targetPackage = null;
535
536 try {
537 String opt;
538 while ((opt = getNextArg()) != null) {
539 switch (opt) {
540 case "-f":
541 showSourceDir = true;
542 break;
543 default:
544 if (opt.charAt(0) != '-') {
545 targetPackage = opt;
546 } else {
547 pw.println("Error: Unknown option: " + opt);
548 return -1;
549 }
550 break;
551 }
552 }
553 } catch (RuntimeException ex) {
554 pw.println("Error: " + ex.toString());
555 return -1;
556 }
557
558 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700559 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700560
561 // sort by target package
562 Collections.sort(list, new Comparator<InstrumentationInfo>() {
563 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
564 return o1.targetPackage.compareTo(o2.targetPackage);
565 }
566 });
567
568 final int count = (list != null) ? list.size() : 0;
569 for (int p = 0; p < count; p++) {
570 final InstrumentationInfo ii = list.get(p);
571 pw.print("instrumentation:");
572 if (showSourceDir) {
573 pw.print(ii.sourceDir);
574 pw.print("=");
575 }
576 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
577 pw.print(cn.flattenToShortString());
578 pw.print(" (target=");
579 pw.print(ii.targetPackage);
580 pw.println(")");
581 }
582 return 0;
583 }
584
585 private int runListLibraries() throws RemoteException {
586 final PrintWriter pw = getOutPrintWriter();
587 final List<String> list = new ArrayList<String>();
588 final String[] rawList = mInterface.getSystemSharedLibraryNames();
589 for (int i = 0; i < rawList.length; i++) {
590 list.add(rawList[i]);
591 }
592
593 // sort by name
594 Collections.sort(list, new Comparator<String>() {
595 public int compare(String o1, String o2) {
596 if (o1 == o2) return 0;
597 if (o1 == null) return -1;
598 if (o2 == null) return 1;
599 return o1.compareTo(o2);
600 }
601 });
602
603 final int count = (list != null) ? list.size() : 0;
604 for (int p = 0; p < count; p++) {
605 String lib = list.get(p);
606 pw.print("library:");
607 pw.println(lib);
608 }
609 return 0;
610 }
611
612 private int runListPackages(boolean showSourceDir) throws RemoteException {
613 final PrintWriter pw = getOutPrintWriter();
614 int getFlags = 0;
615 boolean listDisabled = false, listEnabled = false;
616 boolean listSystem = false, listThirdParty = false;
617 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700618 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800619 boolean showVersionCode = false;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900620 boolean listApexOnly = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700621 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700622 int userId = UserHandle.USER_SYSTEM;
623 try {
624 String opt;
625 while ((opt = getNextOption()) != null) {
626 switch (opt) {
627 case "-d":
628 listDisabled = true;
629 break;
630 case "-e":
631 listEnabled = true;
632 break;
Andreas Gampe1f110452018-06-04 11:47:48 -0700633 case "-a":
634 getFlags |= PackageManager.MATCH_KNOWN_PACKAGES;
635 getFlags |= PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
636 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700637 case "-f":
638 showSourceDir = true;
639 break;
640 case "-i":
641 listInstaller = true;
642 break;
643 case "-l":
644 // old compat
645 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700646 case "-s":
647 listSystem = true;
648 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700649 case "-U":
650 showUid = true;
651 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700652 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700653 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700654 break;
655 case "-3":
656 listThirdParty = true;
657 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800658 case "--show-versioncode":
659 showVersionCode = true;
660 break;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900661 case "--apex-only":
662 getFlags |= PackageManager.MATCH_APEX;
663 listApexOnly = true;
664 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700665 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800666 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700667 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700668 case "--uid":
669 showUid = true;
670 uid = Integer.parseInt(getNextArgRequired());
671 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700672 default:
673 pw.println("Error: Unknown option: " + opt);
674 return -1;
675 }
676 }
677 } catch (RuntimeException ex) {
678 pw.println("Error: " + ex.toString());
679 return -1;
680 }
681
682 final String filter = getNextArg();
683
684 @SuppressWarnings("unchecked")
685 final ParceledListSlice<PackageInfo> slice =
686 mInterface.getInstalledPackages(getFlags, userId);
687 final List<PackageInfo> packages = slice.getList();
688
689 final int count = packages.size();
690 for (int p = 0; p < count; p++) {
691 final PackageInfo info = packages.get(p);
692 if (filter != null && !info.packageName.contains(filter)) {
693 continue;
694 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900695 final boolean isApex = info.isApex;
696 if (uid != -1 && !isApex && info.applicationInfo.uid != uid) {
Felipe Lemeeece9862016-06-29 11:45:03 -0700697 continue;
698 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900699
700 final boolean isSystem = !isApex &&
Todd Kennedy60459ab2015-10-30 11:32:16 -0700701 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
Jiyong Park4f49abe2018-12-11 13:37:17 +0900702 final boolean isEnabled = !isApex && info.applicationInfo.enabled;
703 if ((!listDisabled || !isEnabled) &&
704 (!listEnabled || isEnabled) &&
Todd Kennedy60459ab2015-10-30 11:32:16 -0700705 (!listSystem || isSystem) &&
Jiyong Park4f49abe2018-12-11 13:37:17 +0900706 (!listThirdParty || !isSystem) &&
707 (!listApexOnly || isApex)) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700708 pw.print("package:");
Jiyong Park4f49abe2018-12-11 13:37:17 +0900709 if (showSourceDir && !isApex) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700710 pw.print(info.applicationInfo.sourceDir);
711 pw.print("=");
712 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800713 pw.print(info.packageName);
Jiyong Parkf50a2932018-12-17 13:54:40 +0900714 if (showVersionCode) {
Todd Kennedybadc69a2017-01-24 11:05:47 -0800715 pw.print(" versionCode:");
Jiyong Parkf50a2932018-12-17 13:54:40 +0900716 if (info.applicationInfo != null) {
Dario Freni788ecb12019-01-23 18:49:32 +0000717 pw.print(info.applicationInfo.longVersionCode);
Jiyong Parkf50a2932018-12-17 13:54:40 +0900718 } else {
Dario Freni788ecb12019-01-23 18:49:32 +0000719 pw.print(info.getLongVersionCode());
Jiyong Parkf50a2932018-12-17 13:54:40 +0900720 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800721 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900722 if (listInstaller && !isApex) {
Todd Kennedy60459ab2015-10-30 11:32:16 -0700723 pw.print(" installer=");
724 pw.print(mInterface.getInstallerPackageName(info.packageName));
725 }
Jiyong Park4f49abe2018-12-11 13:37:17 +0900726 if (showUid && !isApex) {
Felipe Lemeeece9862016-06-29 11:45:03 -0700727 pw.print(" uid:");
728 pw.print(info.applicationInfo.uid);
729 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700730 pw.println();
731 }
732 }
733 return 0;
734 }
735
736 private int runListPermissionGroups() throws RemoteException {
737 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700738 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700739
740 final int count = pgs.size();
741 for (int p = 0; p < count ; p++) {
742 final PermissionGroupInfo pgi = pgs.get(p);
743 pw.print("permission group:");
744 pw.println(pgi.name);
745 }
746 return 0;
747 }
748
749 private int runListPermissions() throws RemoteException {
750 final PrintWriter pw = getOutPrintWriter();
751 boolean labels = false;
752 boolean groups = false;
753 boolean userOnly = false;
754 boolean summary = false;
755 boolean dangerousOnly = false;
756 String opt;
757 while ((opt = getNextOption()) != null) {
758 switch (opt) {
759 case "-d":
760 dangerousOnly = true;
761 break;
762 case "-f":
763 labels = true;
764 break;
765 case "-g":
766 groups = true;
767 break;
768 case "-s":
769 groups = true;
770 labels = true;
771 summary = true;
772 break;
773 case "-u":
774 userOnly = true;
775 break;
776 default:
777 pw.println("Error: Unknown option: " + opt);
778 return 1;
779 }
780 }
781
782 final ArrayList<String> groupList = new ArrayList<String>();
783 if (groups) {
784 final List<PermissionGroupInfo> infos =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700785 mInterface.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700786 final int count = infos.size();
787 for (int i = 0; i < count; i++) {
788 groupList.add(infos.get(i).name);
789 }
790 groupList.add(null);
791 } else {
792 final String grp = getNextArg();
793 groupList.add(grp);
794 }
795
796 if (dangerousOnly) {
797 pw.println("Dangerous Permissions:");
798 pw.println("");
799 doListPermissions(groupList, groups, labels, summary,
800 PermissionInfo.PROTECTION_DANGEROUS,
801 PermissionInfo.PROTECTION_DANGEROUS);
802 if (userOnly) {
803 pw.println("Normal Permissions:");
804 pw.println("");
805 doListPermissions(groupList, groups, labels, summary,
806 PermissionInfo.PROTECTION_NORMAL,
807 PermissionInfo.PROTECTION_NORMAL);
808 }
809 } else if (userOnly) {
810 pw.println("Dangerous and Normal Permissions:");
811 pw.println("");
812 doListPermissions(groupList, groups, labels, summary,
813 PermissionInfo.PROTECTION_NORMAL,
814 PermissionInfo.PROTECTION_DANGEROUS);
815 } else {
816 pw.println("All Permissions:");
817 pw.println("");
818 doListPermissions(groupList, groups, labels, summary,
819 -10000, 10000);
820 }
821 return 0;
822 }
823
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800824 private Intent parseIntentAndUser() throws URISyntaxException {
825 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700826 mBrief = false;
827 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800828 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
829 @Override
830 public boolean handleOption(String opt, ShellCommand cmd) {
831 if ("--user".equals(opt)) {
832 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
833 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700834 } else if ("--brief".equals(opt)) {
835 mBrief = true;
836 return true;
837 } else if ("--components".equals(opt)) {
838 mComponents = true;
839 return true;
Ng Zhi An73971312018-09-11 21:39:14 -0700840 } else if ("--query-flags".equals(opt)) {
841 mQueryFlags = Integer.decode(cmd.getNextArgRequired());
842 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800843 }
844 return false;
845 }
846 });
847 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
848 Binder.getCallingUid(), mTargetUser, false, false, null, null);
849 return intent;
850 }
851
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700852 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
853 boolean brief, boolean components) {
854 if (brief || components) {
855 final ComponentName comp;
856 if (ri.activityInfo != null) {
857 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
858 } else if (ri.serviceInfo != null) {
859 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
860 } else if (ri.providerInfo != null) {
861 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
862 } else {
863 comp = null;
864 }
865 if (comp != null) {
866 if (!components) {
867 pr.println(prefix + "priority=" + ri.priority
868 + " preferredOrder=" + ri.preferredOrder
869 + " match=0x" + Integer.toHexString(ri.match)
870 + " specificIndex=" + ri.specificIndex
871 + " isDefault=" + ri.isDefault);
872 }
873 pr.println(prefix + comp.flattenToShortString());
874 return;
875 }
876 }
877 ri.dump(pr, prefix);
878 }
879
Dianne Hackborn99878e92015-12-02 16:27:41 -0800880 private int runResolveActivity() {
881 Intent intent;
882 try {
883 intent = parseIntentAndUser();
884 } catch (URISyntaxException e) {
885 throw new RuntimeException(e.getMessage(), e);
886 }
887 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700888 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), mQueryFlags,
889 mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800890 PrintWriter pw = getOutPrintWriter();
891 if (ri == null) {
892 pw.println("No activity found");
893 } else {
894 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700895 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800896 }
897 } catch (RemoteException e) {
898 throw new RuntimeException("Failed calling service", e);
899 }
900 return 0;
901 }
902
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800903 private int runQueryIntentActivities() {
904 Intent intent;
905 try {
906 intent = parseIntentAndUser();
907 } catch (URISyntaxException e) {
908 throw new RuntimeException(e.getMessage(), e);
909 }
910 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700911 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(),
912 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800913 PrintWriter pw = getOutPrintWriter();
914 if (result == null || result.size() <= 0) {
915 pw.println("No activities found");
916 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700917 if (!mComponents) {
918 pw.print(result.size()); pw.println(" activities found:");
919 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
920 for (int i = 0; i < result.size(); i++) {
921 pw.print(" Activity #"); pw.print(i); pw.println(":");
922 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
923 }
924 } else {
925 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
926 for (int i = 0; i < result.size(); i++) {
927 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
928 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800929 }
930 }
931 } catch (RemoteException e) {
932 throw new RuntimeException("Failed calling service", e);
933 }
934 return 0;
935 }
936
937 private int runQueryIntentServices() {
938 Intent intent;
939 try {
940 intent = parseIntentAndUser();
941 } catch (URISyntaxException e) {
942 throw new RuntimeException(e.getMessage(), e);
943 }
944 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700945 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(),
946 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800947 PrintWriter pw = getOutPrintWriter();
948 if (result == null || result.size() <= 0) {
949 pw.println("No services found");
950 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700951 if (!mComponents) {
952 pw.print(result.size()); pw.println(" services found:");
953 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
954 for (int i = 0; i < result.size(); i++) {
955 pw.print(" Service #"); pw.print(i); pw.println(":");
956 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
957 }
958 } else {
959 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
960 for (int i = 0; i < result.size(); i++) {
961 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
962 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800963 }
964 }
965 } catch (RemoteException e) {
966 throw new RuntimeException("Failed calling service", e);
967 }
968 return 0;
969 }
970
971 private int runQueryIntentReceivers() {
972 Intent intent;
973 try {
974 intent = parseIntentAndUser();
975 } catch (URISyntaxException e) {
976 throw new RuntimeException(e.getMessage(), e);
977 }
978 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700979 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(),
980 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800981 PrintWriter pw = getOutPrintWriter();
982 if (result == null || result.size() <= 0) {
983 pw.println("No receivers found");
984 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700985 if (!mComponents) {
986 pw.print(result.size()); pw.println(" receivers found:");
987 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
988 for (int i = 0; i < result.size(); i++) {
989 pw.print(" Receiver #"); pw.print(i); pw.println(":");
990 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
991 }
992 } else {
993 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
994 for (int i = 0; i < result.size(); i++) {
995 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
996 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800997 }
998 }
999 } catch (RemoteException e) {
1000 throw new RuntimeException("Failed calling service", e);
1001 }
1002 return 0;
1003 }
1004
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001005 private int runInstall() throws RemoteException {
1006 final PrintWriter pw = getOutPrintWriter();
1007 final InstallParams params = makeInstallParams();
1008 final String inPath = getNextArg();
1009
1010 setParamsSize(params, inPath);
1011 final int sessionId = doCreateSession(params.sessionParams,
1012 params.installerPackageName, params.userId);
1013 boolean abandonSession = true;
1014 try {
1015 if (inPath == null && params.sessionParams.sizeBytes == -1) {
1016 pw.println("Error: must either specify a package size or an APK file");
1017 return 1;
1018 }
Dario Frenid8bf22e2018-08-31 14:18:04 +01001019 final boolean isApex =
1020 (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
1021 String splitName = "base." + (isApex ? "apex" : "apk");
1022 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001023 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
1024 return 1;
1025 }
1026 if (doCommitSession(sessionId, false /*logSuccess*/)
1027 != PackageInstaller.STATUS_SUCCESS) {
1028 return 1;
1029 }
1030 abandonSession = false;
1031 pw.println("Success");
1032 return 0;
1033 } finally {
1034 if (abandonSession) {
1035 try {
1036 doAbandonSession(sessionId, false /*logSuccess*/);
1037 } catch (Exception ignore) {
1038 }
1039 }
1040 }
1041 }
1042
1043 private int runInstallAbandon() throws RemoteException {
1044 final int sessionId = Integer.parseInt(getNextArg());
1045 return doAbandonSession(sessionId, true /*logSuccess*/);
1046 }
1047
1048 private int runInstallCommit() throws RemoteException {
1049 final int sessionId = Integer.parseInt(getNextArg());
1050 return doCommitSession(sessionId, true /*logSuccess*/);
1051 }
1052
1053 private int runInstallCreate() throws RemoteException {
1054 final PrintWriter pw = getOutPrintWriter();
1055 final InstallParams installParams = makeInstallParams();
1056 final int sessionId = doCreateSession(installParams.sessionParams,
1057 installParams.installerPackageName, installParams.userId);
1058
1059 // NOTE: adb depends on parsing this string
1060 pw.println("Success: created install session [" + sessionId + "]");
1061 return 0;
1062 }
1063
1064 private int runInstallWrite() throws RemoteException {
1065 long sizeBytes = -1;
1066
1067 String opt;
1068 while ((opt = getNextOption()) != null) {
1069 if (opt.equals("-S")) {
1070 sizeBytes = Long.parseLong(getNextArg());
1071 } else {
1072 throw new IllegalArgumentException("Unknown option: " + opt);
1073 }
1074 }
1075
1076 final int sessionId = Integer.parseInt(getNextArg());
1077 final String splitName = getNextArg();
1078 final String path = getNextArg();
1079 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
1080 }
1081
Patrick Baumann0aff9b12018-11-08 14:05:08 +00001082 private int runInstallAddSession() throws RemoteException {
1083 final PrintWriter pw = getOutPrintWriter();
1084 final int parentSessionId = Integer.parseInt(getNextArg());
1085
1086 List<Integer> otherSessionIds = new ArrayList<>();
1087 String opt;
1088 while ((opt = getNextArg()) != null) {
1089 otherSessionIds.add(Integer.parseInt(opt));
1090 }
1091 if (otherSessionIds.size() == 0) {
1092 pw.println("Error: At least two sessions are required.");
1093 return 1;
1094 }
1095 return doInstallAddSession(parentSessionId, ArrayUtils.convertToIntArray(otherSessionIds),
1096 true /*logSuccess*/);
1097 }
1098
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001099 private int runInstallRemove() throws RemoteException {
1100 final PrintWriter pw = getOutPrintWriter();
1101
1102 final int sessionId = Integer.parseInt(getNextArg());
1103
1104 final String splitName = getNextArg();
1105 if (splitName == null) {
1106 pw.println("Error: split name not specified");
1107 return 1;
1108 }
1109 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
1110 }
1111
1112 private int runInstallExisting() throws RemoteException {
1113 final PrintWriter pw = getOutPrintWriter();
1114 int userId = UserHandle.USER_SYSTEM;
1115 int installFlags = 0;
1116 String opt;
Chandan Nathe8e463b2019-01-28 15:23:38 +00001117 boolean waitTillComplete = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001118 while ((opt = getNextOption()) != null) {
1119 switch (opt) {
1120 case "--user":
1121 userId = UserHandle.parseUserArg(getNextArgRequired());
1122 break;
1123 case "--ephemeral":
1124 case "--instant":
1125 installFlags |= PackageManager.INSTALL_INSTANT_APP;
1126 installFlags &= ~PackageManager.INSTALL_FULL_APP;
1127 break;
1128 case "--full":
1129 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1130 installFlags |= PackageManager.INSTALL_FULL_APP;
1131 break;
Chandan Nathe8e463b2019-01-28 15:23:38 +00001132 case "--wait":
1133 waitTillComplete = true;
1134 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001135 default:
1136 pw.println("Error: Unknown option: " + opt);
1137 return 1;
1138 }
1139 }
1140
1141 final String packageName = getNextArg();
1142 if (packageName == null) {
1143 pw.println("Error: package name not specified");
1144 return 1;
1145 }
1146
Chandan Nathe8e463b2019-01-28 15:23:38 +00001147 int installReason = PackageManager.INSTALL_REASON_UNKNOWN;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001148 try {
Chandan Nathe8e463b2019-01-28 15:23:38 +00001149 if (waitTillComplete) {
1150 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1151 final IPackageInstaller installer = mInterface.getPackageInstaller();
1152 pw.println("Installing package " + packageName + " for user: " + userId);
1153 installer.installExistingPackage(packageName, installFlags, installReason,
1154 receiver.getIntentSender(), userId);
1155 final Intent result = receiver.getResult();
1156 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1157 PackageInstaller.STATUS_FAILURE);
1158 pw.println("Received intent for package install");
1159 return status == PackageInstaller.STATUS_SUCCESS ? 0 : 1;
1160 }
1161
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001162 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
Chandan Nathe8e463b2019-01-28 15:23:38 +00001163 installFlags, installReason);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001164 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
1165 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1166 }
1167 pw.println("Package " + packageName + " installed for user: " + userId);
1168 return 0;
1169 } catch (RemoteException | NameNotFoundException e) {
1170 pw.println(e.toString());
1171 return 1;
1172 }
1173 }
1174
1175 private int runSetInstallLocation() throws RemoteException {
1176 int loc;
1177
1178 String arg = getNextArg();
1179 if (arg == null) {
1180 getErrPrintWriter().println("Error: no install location specified.");
1181 return 1;
1182 }
1183 try {
1184 loc = Integer.parseInt(arg);
1185 } catch (NumberFormatException e) {
1186 getErrPrintWriter().println("Error: install location has to be a number.");
1187 return 1;
1188 }
1189 if (!mInterface.setInstallLocation(loc)) {
1190 getErrPrintWriter().println("Error: install location has to be a number.");
1191 return 1;
1192 }
1193 return 0;
1194 }
1195
1196 private int runGetInstallLocation() throws RemoteException {
1197 int loc = mInterface.getInstallLocation();
1198 String locStr = "invalid";
1199 if (loc == PackageHelper.APP_INSTALL_AUTO) {
1200 locStr = "auto";
1201 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
1202 locStr = "internal";
1203 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
1204 locStr = "external";
1205 }
1206 getOutPrintWriter().println(loc + "[" + locStr + "]");
1207 return 0;
1208 }
1209
1210 public int runMovePackage() throws RemoteException {
1211 final String packageName = getNextArg();
1212 if (packageName == null) {
1213 getErrPrintWriter().println("Error: package name not specified");
1214 return 1;
1215 }
1216 String volumeUuid = getNextArg();
1217 if ("internal".equals(volumeUuid)) {
1218 volumeUuid = null;
1219 }
1220
1221 final int moveId = mInterface.movePackage(packageName, volumeUuid);
1222
1223 int status = mInterface.getMoveStatus(moveId);
1224 while (!PackageManager.isMoveStatusFinished(status)) {
1225 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1226 status = mInterface.getMoveStatus(moveId);
1227 }
1228
1229 if (status == PackageManager.MOVE_SUCCEEDED) {
1230 getOutPrintWriter().println("Success");
1231 return 0;
1232 } else {
1233 getErrPrintWriter().println("Failure [" + status + "]");
1234 return 1;
1235 }
1236 }
1237
1238 public int runMovePrimaryStorage() throws RemoteException {
1239 String volumeUuid = getNextArg();
1240 if ("internal".equals(volumeUuid)) {
1241 volumeUuid = null;
1242 }
1243
1244 final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1245
1246 int status = mInterface.getMoveStatus(moveId);
1247 while (!PackageManager.isMoveStatusFinished(status)) {
1248 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1249 status = mInterface.getMoveStatus(moveId);
1250 }
1251
1252 if (status == PackageManager.MOVE_SUCCEEDED) {
1253 getOutPrintWriter().println("Success");
1254 return 0;
1255 } else {
1256 getErrPrintWriter().println("Failure [" + status + "]");
1257 return 1;
1258 }
1259 }
1260
1261 private int runCompile() throws RemoteException {
1262 final PrintWriter pw = getOutPrintWriter();
1263 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1264 boolean forceCompilation = false;
1265 boolean allPackages = false;
1266 boolean clearProfileData = false;
1267 String compilerFilter = null;
1268 String compilationReason = null;
1269 String checkProfilesRaw = null;
1270 boolean secondaryDex = false;
1271 String split = null;
Eric Holka1485f62019-01-07 13:58:25 -08001272 boolean compileLayouts = false;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001273
1274 String opt;
1275 while ((opt = getNextOption()) != null) {
1276 switch (opt) {
1277 case "-a":
1278 allPackages = true;
1279 break;
1280 case "-c":
1281 clearProfileData = true;
1282 break;
1283 case "-f":
1284 forceCompilation = true;
1285 break;
1286 case "-m":
1287 compilerFilter = getNextArgRequired();
1288 break;
1289 case "-r":
1290 compilationReason = getNextArgRequired();
1291 break;
Eric Holka1485f62019-01-07 13:58:25 -08001292 case "--compile-layouts":
1293 compileLayouts = true;
1294 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001295 case "--check-prof":
1296 checkProfilesRaw = getNextArgRequired();
1297 break;
1298 case "--reset":
1299 forceCompilation = true;
1300 clearProfileData = true;
1301 compilationReason = "install";
1302 break;
1303 case "--secondary-dex":
1304 secondaryDex = true;
1305 break;
1306 case "--split":
1307 split = getNextArgRequired();
1308 break;
1309 default:
1310 pw.println("Error: Unknown option: " + opt);
1311 return 1;
1312 }
1313 }
1314
1315 if (checkProfilesRaw != null) {
1316 if ("true".equals(checkProfilesRaw)) {
1317 checkProfiles = true;
1318 } else if ("false".equals(checkProfilesRaw)) {
1319 checkProfiles = false;
1320 } else {
1321 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1322 return 1;
1323 }
1324 }
1325
Eric Holka1485f62019-01-07 13:58:25 -08001326 final boolean compilerFilterGiven = compilerFilter != null;
1327 final boolean compilationReasonGiven = compilationReason != null;
1328 // Make sure exactly one of -m, -r, or --compile-layouts is given.
1329 if ((!compilerFilterGiven && !compilationReasonGiven && !compileLayouts)
1330 || (!compilerFilterGiven && compilationReasonGiven && compileLayouts)
1331 || (compilerFilterGiven && !compilationReasonGiven && compileLayouts)
1332 || (compilerFilterGiven && compilationReasonGiven && !compileLayouts)
1333 || (compilerFilterGiven && compilationReasonGiven && compileLayouts)) {
1334 pw.println("Must specify exactly one of compilation filter (\"-m\"), compilation " +
1335 "reason (\"-r\"), or compile layouts (\"--compile-layouts\")");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001336 return 1;
1337 }
1338
1339 if (allPackages && split != null) {
1340 pw.println("-a cannot be specified together with --split");
1341 return 1;
1342 }
1343
1344 if (secondaryDex && split != null) {
1345 pw.println("--secondary-dex cannot be specified together with --split");
1346 return 1;
1347 }
1348
Eric Holka1485f62019-01-07 13:58:25 -08001349 String targetCompilerFilter = null;
1350 if (compilerFilterGiven) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001351 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1352 pw.println("Error: \"" + compilerFilter +
1353 "\" is not a valid compilation filter.");
1354 return 1;
1355 }
1356 targetCompilerFilter = compilerFilter;
Eric Holka1485f62019-01-07 13:58:25 -08001357 }
1358 if (compilationReasonGiven) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001359 int reason = -1;
1360 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1361 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1362 compilationReason)) {
1363 reason = i;
1364 break;
1365 }
1366 }
1367 if (reason == -1) {
1368 pw.println("Error: Unknown compilation reason: " + compilationReason);
1369 return 1;
1370 }
1371 targetCompilerFilter =
1372 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1373 }
1374
1375
1376 List<String> packageNames = null;
1377 if (allPackages) {
1378 packageNames = mInterface.getAllPackages();
1379 } else {
1380 String packageName = getNextArg();
1381 if (packageName == null) {
1382 pw.println("Error: package name not specified");
1383 return 1;
1384 }
1385 packageNames = Collections.singletonList(packageName);
1386 }
1387
1388 List<String> failedPackages = new ArrayList<>();
Andreas Gampecbd08d42017-11-20 17:03:17 -08001389 int index = 0;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001390 for (String packageName : packageNames) {
1391 if (clearProfileData) {
1392 mInterface.clearApplicationProfileData(packageName);
1393 }
1394
Andreas Gampecbd08d42017-11-20 17:03:17 -08001395 if (allPackages) {
1396 pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1397 pw.flush();
1398 }
1399
Eric Holka1485f62019-01-07 13:58:25 -08001400 boolean result = true;
1401 if (compileLayouts) {
1402 PackageManagerInternal internal = LocalServices.getService(
1403 PackageManagerInternal.class);
1404 result = internal.compileLayouts(packageName);
1405 } else {
1406 result = secondaryDex
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001407 ? mInterface.performDexOptSecondary(packageName,
1408 targetCompilerFilter, forceCompilation)
1409 : mInterface.performDexOptMode(packageName,
1410 checkProfiles, targetCompilerFilter, forceCompilation,
1411 true /* bootComplete */, split);
Eric Holka1485f62019-01-07 13:58:25 -08001412 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001413 if (!result) {
1414 failedPackages.add(packageName);
1415 }
1416 }
1417
1418 if (failedPackages.isEmpty()) {
1419 pw.println("Success");
1420 return 0;
1421 } else if (failedPackages.size() == 1) {
1422 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1423 return 1;
1424 } else {
1425 pw.print("Failure: the following packages could not be compiled: ");
1426 boolean is_first = true;
1427 for (String packageName : failedPackages) {
1428 if (is_first) {
1429 is_first = false;
1430 } else {
1431 pw.print(", ");
1432 }
1433 pw.print(packageName);
1434 }
1435 pw.println();
1436 return 1;
1437 }
1438 }
1439
1440 private int runreconcileSecondaryDexFiles() throws RemoteException {
1441 String packageName = getNextArg();
1442 mInterface.reconcileSecondaryDexFiles(packageName);
1443 return 0;
1444 }
1445
1446 public int runForceDexOpt() throws RemoteException {
1447 mInterface.forceDexOpt(getNextArgRequired());
1448 return 0;
1449 }
1450
1451 private int runDexoptJob() throws RemoteException {
Arthur Eubanks09dd1ec2017-09-15 09:28:51 -07001452 String arg;
1453 List<String> packageNames = new ArrayList<>();
1454 while ((arg = getNextArg()) != null) {
1455 packageNames.add(arg);
1456 }
1457 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1458 packageNames);
Andreas Gampefa8b57d2018-08-31 15:47:01 -07001459 getOutPrintWriter().println(result ? "Success" : "Failure");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001460 return result ? 0 : -1;
1461 }
1462
1463 private int runDumpProfiles() throws RemoteException {
1464 String packageName = getNextArg();
1465 mInterface.dumpProfiles(packageName);
1466 return 0;
1467 }
1468
Calin Juravle21216c62018-05-04 17:35:29 -07001469 private int runSnapshotProfile() throws RemoteException {
1470 PrintWriter pw = getOutPrintWriter();
1471
1472 // Parse the arguments
1473 final String packageName = getNextArg();
1474 final boolean isBootImage = "android".equals(packageName);
1475
1476 String codePath = null;
1477 String opt;
1478 while ((opt = getNextArg()) != null) {
1479 switch (opt) {
1480 case "--code-path":
1481 if (isBootImage) {
1482 pw.write("--code-path cannot be used for the boot image.");
1483 return -1;
1484 }
1485 codePath = getNextArg();
1486 break;
1487 default:
1488 pw.write("Unknown arg: " + opt);
1489 return -1;
1490 }
1491 }
1492
1493 // If no code path was explicitly requested, select the base code path.
1494 String baseCodePath = null;
1495 if (!isBootImage) {
1496 PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
1497 /* userId */0);
1498 if (packageInfo == null) {
1499 pw.write("Package not found " + packageName);
1500 return -1;
1501 }
1502 baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
1503 if (codePath == null) {
1504 codePath = baseCodePath;
1505 }
1506 }
1507
1508 // Create the profile snapshot.
1509 final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
1510 // The calling package is needed to debug permission access.
1511 final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
1512 ? "root" : "com.android.shell";
1513 final int profileType = isBootImage
1514 ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
1515 if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
1516 pw.println("Error: Runtime profiling is not enabled");
1517 return -1;
1518 }
1519 mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
1520 codePath, callback, callingPackage);
1521 if (!callback.waitTillDone()) {
1522 pw.println("Error: callback not called");
1523 return callback.mErrCode;
1524 }
1525
1526 // Copy the snapshot profile to the output profile file.
1527 try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
1528 final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
1529 ? "" : ("-" + new File(codePath).getName());
1530 final String outputProfilePath =
1531 ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
1532 try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
1533 Streams.copy(inStream, outStream);
1534 }
Calin Juravlebdd94d92018-05-17 01:23:15 -07001535 // Give read permissions to the other group.
1536 Os.chmod(outputProfilePath, /*mode*/ 0644 );
1537 } catch (IOException | ErrnoException e) {
Calin Juravle21216c62018-05-04 17:35:29 -07001538 pw.println("Error when reading the profile fd: " + e.getMessage());
1539 e.printStackTrace(pw);
1540 return -1;
1541 }
1542 return 0;
1543 }
1544
1545 private static class SnapshotRuntimeProfileCallback
1546 extends ISnapshotRuntimeProfileCallback.Stub {
1547 private boolean mSuccess = false;
1548 private int mErrCode = -1;
1549 private ParcelFileDescriptor mProfileReadFd = null;
1550 private CountDownLatch mDoneSignal = new CountDownLatch(1);
1551
1552 @Override
1553 public void onSuccess(ParcelFileDescriptor profileReadFd) {
1554 mSuccess = true;
1555 try {
1556 // We need to dup the descriptor. We are in the same process as system server
1557 // and we will be receiving the same object (which will be closed on the
1558 // server side).
1559 mProfileReadFd = profileReadFd.dup();
1560 } catch (IOException e) {
1561 e.printStackTrace();
1562 }
1563 mDoneSignal.countDown();
1564 }
1565
1566 @Override
1567 public void onError(int errCode) {
1568 mSuccess = false;
1569 mErrCode = errCode;
1570 mDoneSignal.countDown();
1571 }
1572
1573 boolean waitTillDone() {
1574 boolean done = false;
1575 try {
1576 // The time-out is an arbitrary large value. Since this is a local call the result
1577 // will come very fast.
1578 done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS);
1579 } catch (InterruptedException ignored) {
1580 }
1581 return done && mSuccess;
1582 }
1583 }
1584
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001585 private int runUninstall() throws RemoteException {
1586 final PrintWriter pw = getOutPrintWriter();
1587 int flags = 0;
1588 int userId = UserHandle.USER_ALL;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001589 long versionCode = PackageManager.VERSION_CODE_HIGHEST;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001590
1591 String opt;
1592 while ((opt = getNextOption()) != null) {
1593 switch (opt) {
1594 case "-k":
1595 flags |= PackageManager.DELETE_KEEP_DATA;
1596 break;
1597 case "--user":
1598 userId = UserHandle.parseUserArg(getNextArgRequired());
1599 break;
1600 case "--versionCode":
Dianne Hackborn3accca02013-09-20 09:32:11 -07001601 versionCode = Long.parseLong(getNextArgRequired());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001602 break;
1603 default:
1604 pw.println("Error: Unknown option: " + opt);
1605 return 1;
1606 }
1607 }
1608
1609 final String packageName = getNextArg();
1610 if (packageName == null) {
1611 pw.println("Error: package name not specified");
1612 return 1;
1613 }
1614
1615 // if a split is specified, just remove it and not the whole package
1616 final String splitName = getNextArg();
1617 if (splitName != null) {
1618 return runRemoveSplit(packageName, splitName);
1619 }
1620
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08001621 userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001622 if (userId == UserHandle.USER_ALL) {
1623 userId = UserHandle.USER_SYSTEM;
1624 flags |= PackageManager.DELETE_ALL_USERS;
1625 } else {
1626 final PackageInfo info = mInterface.getPackageInfo(packageName,
1627 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1628 if (info == null) {
1629 pw.println("Failure [not installed for " + userId + "]");
1630 return 1;
1631 }
1632 final boolean isSystem =
1633 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1634 // If we are being asked to delete a system app for just one
1635 // user set flag so it disables rather than reverting to system
1636 // version of the app.
1637 if (isSystem) {
1638 flags |= PackageManager.DELETE_SYSTEM_APP;
1639 }
1640 }
1641
1642 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1643 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1644 versionCode), null /*callerPackageName*/, flags,
1645 receiver.getIntentSender(), userId);
1646
1647 final Intent result = receiver.getResult();
1648 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1649 PackageInstaller.STATUS_FAILURE);
1650 if (status == PackageInstaller.STATUS_SUCCESS) {
1651 pw.println("Success");
1652 return 0;
1653 } else {
1654 pw.println("Failure ["
1655 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1656 return 1;
1657 }
1658 }
1659
1660 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1661 final PrintWriter pw = getOutPrintWriter();
1662 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1663 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1664 sessionParams.appPackageName = packageName;
1665 final int sessionId =
1666 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1667 boolean abandonSession = true;
1668 try {
1669 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1670 != PackageInstaller.STATUS_SUCCESS) {
1671 return 1;
1672 }
1673 if (doCommitSession(sessionId, false /*logSuccess*/)
1674 != PackageInstaller.STATUS_SUCCESS) {
1675 return 1;
1676 }
1677 abandonSession = false;
1678 pw.println("Success");
1679 return 0;
1680 } finally {
1681 if (abandonSession) {
1682 try {
1683 doAbandonSession(sessionId, false /*logSuccess*/);
1684 } catch (Exception ignore) {
1685 }
1686 }
1687 }
1688 }
1689
1690 static class ClearDataObserver extends IPackageDataObserver.Stub {
1691 boolean finished;
1692 boolean result;
1693
1694 @Override
1695 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1696 synchronized (this) {
1697 finished = true;
1698 result = succeeded;
1699 notifyAll();
1700 }
1701 }
1702 }
1703
1704 private int runClear() throws RemoteException {
1705 int userId = UserHandle.USER_SYSTEM;
1706 String option = getNextOption();
1707 if (option != null && option.equals("--user")) {
1708 userId = UserHandle.parseUserArg(getNextArgRequired());
1709 }
1710
1711 String pkg = getNextArg();
1712 if (pkg == null) {
1713 getErrPrintWriter().println("Error: no package specified");
1714 return 1;
1715 }
1716
1717 ClearDataObserver obs = new ClearDataObserver();
Christopher Tate1d99c392017-12-07 16:54:04 -08001718 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001719 synchronized (obs) {
1720 while (!obs.finished) {
1721 try {
1722 obs.wait();
1723 } catch (InterruptedException e) {
1724 }
1725 }
1726 }
1727
1728 if (obs.result) {
1729 getOutPrintWriter().println("Success");
1730 return 0;
1731 } else {
1732 getErrPrintWriter().println("Failed");
1733 return 1;
1734 }
1735 }
1736
1737 private static String enabledSettingToString(int state) {
1738 switch (state) {
1739 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1740 return "default";
1741 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1742 return "enabled";
1743 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1744 return "disabled";
1745 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1746 return "disabled-user";
1747 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1748 return "disabled-until-used";
1749 }
1750 return "unknown";
1751 }
1752
1753 private int runSetEnabledSetting(int state) throws RemoteException {
1754 int userId = UserHandle.USER_SYSTEM;
1755 String option = getNextOption();
1756 if (option != null && option.equals("--user")) {
1757 userId = UserHandle.parseUserArg(getNextArgRequired());
1758 }
1759
1760 String pkg = getNextArg();
1761 if (pkg == null) {
1762 getErrPrintWriter().println("Error: no package or component specified");
1763 return 1;
1764 }
1765 ComponentName cn = ComponentName.unflattenFromString(pkg);
1766 if (cn == null) {
1767 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1768 "shell:" + android.os.Process.myUid());
1769 getOutPrintWriter().println("Package " + pkg + " new state: "
1770 + enabledSettingToString(
1771 mInterface.getApplicationEnabledSetting(pkg, userId)));
1772 return 0;
1773 } else {
1774 mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1775 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1776 + enabledSettingToString(
1777 mInterface.getComponentEnabledSetting(cn, userId)));
1778 return 0;
1779 }
1780 }
1781
1782 private int runSetHiddenSetting(boolean state) throws RemoteException {
1783 int userId = UserHandle.USER_SYSTEM;
1784 String option = getNextOption();
1785 if (option != null && option.equals("--user")) {
1786 userId = UserHandle.parseUserArg(getNextArgRequired());
1787 }
1788
1789 String pkg = getNextArg();
1790 if (pkg == null) {
1791 getErrPrintWriter().println("Error: no package or component specified");
1792 return 1;
1793 }
1794 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1795 getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1796 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1797 return 0;
1798 }
1799
1800 private int runSuspend(boolean suspendedState) {
1801 final PrintWriter pw = getOutPrintWriter();
1802 int userId = UserHandle.USER_SYSTEM;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001803 String dialogMessage = null;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001804 final PersistableBundle appExtras = new PersistableBundle();
1805 final PersistableBundle launcherExtras = new PersistableBundle();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001806 String opt;
1807 while ((opt = getNextOption()) != null) {
1808 switch (opt) {
1809 case "--user":
1810 userId = UserHandle.parseUserArg(getNextArgRequired());
1811 break;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001812 case "--dialogMessage":
1813 dialogMessage = getNextArgRequired();
1814 break;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001815 case "--ael":
1816 case "--aes":
1817 case "--aed":
1818 case "--lel":
1819 case "--les":
1820 case "--led":
1821 final String key = getNextArgRequired();
1822 final String val = getNextArgRequired();
1823 if (!suspendedState) {
1824 break;
1825 }
1826 final PersistableBundle bundleToInsert =
1827 opt.startsWith("--a") ? appExtras : launcherExtras;
1828 switch (opt.charAt(4)) {
1829 case 'l':
1830 bundleToInsert.putLong(key, Long.valueOf(val));
1831 break;
1832 case 'd':
1833 bundleToInsert.putDouble(key, Double.valueOf(val));
1834 break;
1835 case 's':
1836 bundleToInsert.putString(key, val);
1837 break;
1838 }
1839 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001840 default:
1841 pw.println("Error: Unknown option: " + opt);
1842 return 1;
1843 }
1844 }
1845
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001846 final String packageName = getNextArg();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001847 if (packageName == null) {
1848 pw.println("Error: package name not specified");
1849 return 1;
1850 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001851 final String callingPackage =
1852 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07001853
1854 final SuspendDialogInfo info;
1855 if (!TextUtils.isEmpty(dialogMessage)) {
1856 info = new SuspendDialogInfo.Builder()
1857 .setMessage(dialogMessage)
1858 .build();
1859 } else {
1860 info = null;
1861 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001862 try {
1863 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07001864 appExtras, launcherExtras, info, callingPackage, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001865 pw.println("Package " + packageName + " new suspended state: "
1866 + mInterface.isPackageSuspendedForUser(packageName, userId));
1867 return 0;
1868 } catch (RemoteException | IllegalArgumentException e) {
1869 pw.println(e.toString());
1870 return 1;
1871 }
1872 }
1873
1874 private int runGrantRevokePermission(boolean grant) throws RemoteException {
1875 int userId = UserHandle.USER_SYSTEM;
1876
1877 String opt = null;
1878 while ((opt = getNextOption()) != null) {
1879 if (opt.equals("--user")) {
1880 userId = UserHandle.parseUserArg(getNextArgRequired());
1881 }
1882 }
1883
1884 String pkg = getNextArg();
1885 if (pkg == null) {
1886 getErrPrintWriter().println("Error: no package specified");
1887 return 1;
1888 }
1889 String perm = getNextArg();
1890 if (perm == null) {
1891 getErrPrintWriter().println("Error: no permission specified");
1892 return 1;
1893 }
1894
1895 if (grant) {
1896 mInterface.grantRuntimePermission(pkg, perm, userId);
1897 } else {
1898 mInterface.revokeRuntimePermission(pkg, perm, userId);
1899 }
1900 return 0;
1901 }
1902
1903 private int runResetPermissions() throws RemoteException {
1904 mInterface.resetRuntimePermissions();
1905 return 0;
1906 }
1907
1908 private int runSetPermissionEnforced() throws RemoteException {
1909 final String permission = getNextArg();
1910 if (permission == null) {
1911 getErrPrintWriter().println("Error: no permission specified");
1912 return 1;
1913 }
1914 final String enforcedRaw = getNextArg();
1915 if (enforcedRaw == null) {
1916 getErrPrintWriter().println("Error: no enforcement specified");
1917 return 1;
1918 }
1919 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
1920 return 0;
1921 }
1922
Jiyong Park002fdbd2017-02-13 20:50:31 +09001923 private boolean isVendorApp(String pkg) {
1924 try {
1925 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1926 return info != null && info.applicationInfo.isVendor();
1927 } catch (RemoteException e) {
1928 return false;
1929 }
1930 }
1931
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001932 private boolean isProductApp(String pkg) {
1933 try {
1934 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1935 return info != null && info.applicationInfo.isProduct();
1936 } catch (RemoteException e) {
1937 return false;
1938 }
1939 }
1940
Dario Freni2bef1762018-06-01 14:02:08 +01001941 private boolean isProductServicesApp(String pkg) {
1942 try {
1943 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1944 return info != null && info.applicationInfo.isProductServices();
1945 } catch (RemoteException e) {
1946 return false;
1947 }
1948 }
1949
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001950 private int runGetPrivappPermissions() {
1951 final String pkg = getNextArg();
1952 if (pkg == null) {
1953 getErrPrintWriter().println("Error: no package specified.");
1954 return 1;
1955 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001956
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001957 ArraySet<String> privAppPermissions = null;
1958 if (isVendorApp(pkg)) {
1959 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
1960 } else if (isProductApp(pkg)) {
1961 privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
Dario Freni2bef1762018-06-01 14:02:08 +01001962 } else if (isProductServicesApp(pkg)) {
1963 privAppPermissions = SystemConfig.getInstance()
1964 .getProductServicesPrivAppPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001965 } else {
1966 privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
1967 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001968
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001969 getOutPrintWriter().println(privAppPermissions == null
1970 ? "{}" : privAppPermissions.toString());
1971 return 0;
1972 }
1973
1974 private int runGetPrivappDenyPermissions() {
1975 final String pkg = getNextArg();
1976 if (pkg == null) {
1977 getErrPrintWriter().println("Error: no package specified.");
1978 return 1;
1979 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001980
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001981 ArraySet<String> privAppPermissions = null;
1982 if (isVendorApp(pkg)) {
1983 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
1984 } else if (isProductApp(pkg)) {
1985 privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
Dario Freni2bef1762018-06-01 14:02:08 +01001986 } else if (isProductServicesApp(pkg)) {
1987 privAppPermissions = SystemConfig.getInstance()
1988 .getProductServicesPrivAppDenyPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001989 } else {
1990 privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
1991 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001992
1993 getOutPrintWriter().println(privAppPermissions == null
1994 ? "{}" : privAppPermissions.toString());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001995 return 0;
1996 }
1997
1998 private int runGetOemPermissions() {
1999 final String pkg = getNextArg();
2000 if (pkg == null) {
2001 getErrPrintWriter().println("Error: no package specified.");
2002 return 1;
2003 }
2004 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
2005 .getOemPermissions(pkg);
2006 if (oemPermissions == null || oemPermissions.isEmpty()) {
2007 getOutPrintWriter().println("{}");
2008 } else {
2009 oemPermissions.forEach((permission, granted) ->
2010 getOutPrintWriter().println(permission + " granted:" + granted)
2011 );
2012 }
2013 return 0;
2014 }
2015
2016 private String linkStateToString(int state) {
2017 switch (state) {
2018 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
2019 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
2020 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
2021 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
2022 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
2023 }
2024 return "Unknown link state: " + state;
2025 }
2026
2027 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
2028 private int runSetAppLink() throws RemoteException {
2029 int userId = UserHandle.USER_SYSTEM;
2030
2031 String opt;
2032 while ((opt = getNextOption()) != null) {
2033 if (opt.equals("--user")) {
2034 userId = UserHandle.parseUserArg(getNextArgRequired());
2035 } else {
2036 getErrPrintWriter().println("Error: unknown option: " + opt);
2037 return 1;
2038 }
2039 }
2040
2041 // Package name to act on; required
2042 final String pkg = getNextArg();
2043 if (pkg == null) {
2044 getErrPrintWriter().println("Error: no package specified.");
2045 return 1;
2046 }
2047
2048 // State to apply; {always|ask|never|undefined}, required
2049 final String modeString = getNextArg();
2050 if (modeString == null) {
2051 getErrPrintWriter().println("Error: no app link state specified.");
2052 return 1;
2053 }
2054
2055 final int newMode;
2056 switch (modeString.toLowerCase()) {
2057 case "undefined":
2058 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
2059 break;
2060
2061 case "always":
2062 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
2063 break;
2064
2065 case "ask":
2066 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
2067 break;
2068
2069 case "always-ask":
2070 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
2071 break;
2072
2073 case "never":
2074 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
2075 break;
2076
2077 default:
2078 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
2079 return 1;
2080 }
2081
2082 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
2083 if (info == null) {
2084 getErrPrintWriter().println("Error: package " + pkg + " not found.");
2085 return 1;
2086 }
2087
2088 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2089 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2090 return 1;
2091 }
2092
2093 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
2094 getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
2095 return 1;
2096 }
2097
2098 return 0;
2099 }
2100
2101 // pm get-app-link [--user USER_ID] PACKAGE
2102 private int runGetAppLink() throws RemoteException {
2103 int userId = UserHandle.USER_SYSTEM;
2104
2105 String opt;
2106 while ((opt = getNextOption()) != null) {
2107 if (opt.equals("--user")) {
2108 userId = UserHandle.parseUserArg(getNextArgRequired());
2109 } else {
2110 getErrPrintWriter().println("Error: unknown option: " + opt);
2111 return 1;
2112 }
2113 }
2114
2115 // Package name to act on; required
2116 final String pkg = getNextArg();
2117 if (pkg == null) {
2118 getErrPrintWriter().println("Error: no package specified.");
2119 return 1;
2120 }
2121
2122 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
2123 if (info == null) {
2124 getErrPrintWriter().println("Error: package " + pkg + " not found.");
2125 return 1;
2126 }
2127
2128 if ((info.applicationInfo.privateFlags
2129 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2130 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2131 return 1;
2132 }
2133
2134 getOutPrintWriter().println(linkStateToString(
2135 mInterface.getIntentVerificationStatus(pkg, userId)));
2136
2137 return 0;
2138 }
2139
2140 private int runTrimCaches() throws RemoteException {
2141 String size = getNextArg();
2142 if (size == null) {
2143 getErrPrintWriter().println("Error: no size specified");
2144 return 1;
2145 }
2146 long multiplier = 1;
2147 int len = size.length();
2148 char c = size.charAt(len - 1);
2149 if (c < '0' || c > '9') {
2150 if (c == 'K' || c == 'k') {
2151 multiplier = 1024L;
2152 } else if (c == 'M' || c == 'm') {
2153 multiplier = 1024L*1024L;
2154 } else if (c == 'G' || c == 'g') {
2155 multiplier = 1024L*1024L*1024L;
2156 } else {
2157 getErrPrintWriter().println("Invalid suffix: " + c);
2158 return 1;
2159 }
2160 size = size.substring(0, len-1);
2161 }
2162 long sizeVal;
2163 try {
2164 sizeVal = Long.parseLong(size) * multiplier;
2165 } catch (NumberFormatException e) {
2166 getErrPrintWriter().println("Error: expected number at: " + size);
2167 return 1;
2168 }
2169 String volumeUuid = getNextArg();
2170 if ("internal".equals(volumeUuid)) {
2171 volumeUuid = null;
2172 }
2173 ClearDataObserver obs = new ClearDataObserver();
2174 mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
2175 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
2176 synchronized (obs) {
2177 while (!obs.finished) {
2178 try {
2179 obs.wait();
2180 } catch (InterruptedException e) {
2181 }
2182 }
2183 }
2184 return 0;
2185 }
2186
2187 private static boolean isNumber(String s) {
2188 try {
2189 Integer.parseInt(s);
2190 } catch (NumberFormatException nfe) {
2191 return false;
2192 }
2193 return true;
2194 }
2195
2196 public int runCreateUser() throws RemoteException {
2197 String name;
2198 int userId = -1;
2199 int flags = 0;
2200 String opt;
2201 while ((opt = getNextOption()) != null) {
2202 if ("--profileOf".equals(opt)) {
2203 userId = UserHandle.parseUserArg(getNextArgRequired());
2204 } else if ("--managed".equals(opt)) {
2205 flags |= UserInfo.FLAG_MANAGED_PROFILE;
2206 } else if ("--restricted".equals(opt)) {
2207 flags |= UserInfo.FLAG_RESTRICTED;
2208 } else if ("--ephemeral".equals(opt)) {
2209 flags |= UserInfo.FLAG_EPHEMERAL;
2210 } else if ("--guest".equals(opt)) {
2211 flags |= UserInfo.FLAG_GUEST;
2212 } else if ("--demo".equals(opt)) {
2213 flags |= UserInfo.FLAG_DEMO;
2214 } else {
2215 getErrPrintWriter().println("Error: unknown option " + opt);
2216 return 1;
2217 }
2218 }
2219 String arg = getNextArg();
2220 if (arg == null) {
2221 getErrPrintWriter().println("Error: no user name specified.");
2222 return 1;
2223 }
2224 name = arg;
2225 UserInfo info;
2226 IUserManager um = IUserManager.Stub.asInterface(
2227 ServiceManager.getService(Context.USER_SERVICE));
2228 IAccountManager accm = IAccountManager.Stub.asInterface(
2229 ServiceManager.getService(Context.ACCOUNT_SERVICE));
2230 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
2231 // In non-split user mode, userId can only be SYSTEM
2232 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
2233 info = um.createRestrictedProfile(name, parentUserId);
2234 accm.addSharedAccountsFromParentUser(parentUserId, userId,
2235 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
2236 } else if (userId < 0) {
2237 info = um.createUser(name, flags);
2238 } else {
2239 info = um.createProfileForUser(name, flags, userId, null);
2240 }
2241
2242 if (info != null) {
2243 getOutPrintWriter().println("Success: created user id " + info.id);
2244 return 0;
2245 } else {
2246 getErrPrintWriter().println("Error: couldn't create User.");
2247 return 1;
2248 }
2249 }
2250
2251 public int runRemoveUser() throws RemoteException {
2252 int userId;
2253 String arg = getNextArg();
2254 if (arg == null) {
2255 getErrPrintWriter().println("Error: no user id specified.");
2256 return 1;
2257 }
2258 userId = UserHandle.parseUserArg(arg);
2259 IUserManager um = IUserManager.Stub.asInterface(
2260 ServiceManager.getService(Context.USER_SERVICE));
2261 if (um.removeUser(userId)) {
2262 getOutPrintWriter().println("Success: removed user");
2263 return 0;
2264 } else {
2265 getErrPrintWriter().println("Error: couldn't remove user id " + userId);
2266 return 1;
2267 }
2268 }
2269
2270 public int runSetUserRestriction() throws RemoteException {
2271 int userId = UserHandle.USER_SYSTEM;
2272 String opt = getNextOption();
2273 if (opt != null && "--user".equals(opt)) {
2274 userId = UserHandle.parseUserArg(getNextArgRequired());
2275 }
2276
2277 String restriction = getNextArg();
2278 String arg = getNextArg();
2279 boolean value;
2280 if ("1".equals(arg)) {
2281 value = true;
2282 } else if ("0".equals(arg)) {
2283 value = false;
2284 } else {
2285 getErrPrintWriter().println("Error: valid value not specified");
2286 return 1;
2287 }
2288 IUserManager um = IUserManager.Stub.asInterface(
2289 ServiceManager.getService(Context.USER_SERVICE));
2290 um.setUserRestriction(restriction, value, userId);
2291 return 0;
2292 }
2293
2294 public int runGetMaxUsers() {
2295 getOutPrintWriter().println("Maximum supported users: "
2296 + UserManager.getMaxSupportedUsers());
2297 return 0;
2298 }
2299
Alex Chauc12189b2018-01-16 15:01:15 +00002300 public int runGetMaxRunningUsers() {
2301 ActivityManagerInternal activityManagerInternal =
2302 LocalServices.getService(ActivityManagerInternal.class);
2303 getOutPrintWriter().println("Maximum supported running users: "
2304 + activityManagerInternal.getMaxRunningUsers());
2305 return 0;
2306 }
2307
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002308 private static class InstallParams {
2309 SessionParams sessionParams;
2310 String installerPackageName;
2311 int userId = UserHandle.USER_ALL;
2312 }
2313
2314 private InstallParams makeInstallParams() {
2315 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
2316 final InstallParams params = new InstallParams();
2317 params.sessionParams = sessionParams;
2318 String opt;
Patrick Baumanna9333492017-11-28 15:23:49 -08002319 boolean replaceExisting = true;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002320 while ((opt = getNextOption()) != null) {
2321 switch (opt) {
Patrick Baumanna9333492017-11-28 15:23:49 -08002322 case "-r": // ignore
2323 break;
2324 case "-R":
2325 replaceExisting = false;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002326 break;
2327 case "-i":
2328 params.installerPackageName = getNextArg();
2329 if (params.installerPackageName == null) {
2330 throw new IllegalArgumentException("Missing installer package");
2331 }
2332 break;
2333 case "-t":
2334 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
2335 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002336 case "-f":
2337 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
2338 break;
2339 case "-d":
2340 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
2341 break;
2342 case "-g":
2343 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
2344 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002345 case "--dont-kill":
2346 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
2347 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002348 case "--originating-uri":
2349 sessionParams.originatingUri = Uri.parse(getNextArg());
2350 break;
2351 case "--referrer":
2352 sessionParams.referrerUri = Uri.parse(getNextArg());
2353 break;
2354 case "-p":
2355 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
2356 sessionParams.appPackageName = getNextArg();
2357 if (sessionParams.appPackageName == null) {
2358 throw new IllegalArgumentException("Missing inherit package name");
2359 }
2360 break;
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002361 case "--pkg":
2362 sessionParams.appPackageName = getNextArg();
2363 if (sessionParams.appPackageName == null) {
2364 throw new IllegalArgumentException("Missing package name");
2365 }
2366 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002367 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002368 final long sizeBytes = Long.parseLong(getNextArg());
2369 if (sizeBytes <= 0) {
2370 throw new IllegalArgumentException("Size must be positive");
2371 }
2372 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002373 break;
2374 case "--abi":
2375 sessionParams.abiOverride = checkAbiArgument(getNextArg());
2376 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08002377 case "--ephemeral":
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002378 case "--instant":
Todd Kennedybe0b8892017-02-15 14:13:52 -08002379 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08002380 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08002381 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08002382 case "--full":
2383 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
2384 break;
Todd Kennedy78a72502017-07-19 12:49:30 -07002385 case "--preload":
2386 sessionParams.setInstallAsVirtualPreload();
2387 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002388 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002389 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002390 break;
2391 case "--install-location":
2392 sessionParams.installLocation = Integer.parseInt(getNextArg());
2393 break;
Sunny Goyalabd4d442018-09-19 15:49:50 -07002394 case "--install-reason":
2395 sessionParams.installReason = Integer.parseInt(getNextArg());
2396 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002397 case "--force-uuid":
2398 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
2399 sessionParams.volumeUuid = getNextArg();
2400 if ("internal".equals(sessionParams.volumeUuid)) {
2401 sessionParams.volumeUuid = null;
2402 }
2403 break;
Nicholas Lativyeb23e4d2019-02-01 13:39:28 +00002404 case "--force-sdk": // ignore
Todd Kennedyb1072712016-04-26 15:41:20 -07002405 break;
Dario Frenid8bf22e2018-08-31 14:18:04 +01002406 case "--apex":
Dario Freni3fa46d82019-01-23 19:31:47 +00002407 sessionParams.setInstallAsApex();
Dario Freni505b8152019-01-08 12:30:43 +00002408 sessionParams.setStaged();
Dario Frenid8bf22e2018-08-31 14:18:04 +01002409 break;
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002410 case "--multi-package":
2411 sessionParams.setMultiPackage();
2412 break;
Dario Freniaac4ba42018-12-06 15:47:16 +00002413 case "--staged":
2414 sessionParams.setStaged();
2415 break;
Richard Uhlerb29f1452018-09-12 16:38:15 +01002416 case "--enable-rollback":
2417 sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
2418 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002419 default:
2420 throw new IllegalArgumentException("Unknown option " + opt);
2421 }
Patrick Baumanna9333492017-11-28 15:23:49 -08002422 if (replaceExisting) {
2423 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
2424 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002425 }
2426 return params;
2427 }
2428
Makoto Onuki4828a592016-03-15 18:06:57 -07002429 private int runSetHomeActivity() {
2430 final PrintWriter pw = getOutPrintWriter();
2431 int userId = UserHandle.USER_SYSTEM;
2432 String opt;
2433 while ((opt = getNextOption()) != null) {
2434 switch (opt) {
2435 case "--user":
2436 userId = UserHandle.parseUserArg(getNextArgRequired());
2437 break;
2438 default:
2439 pw.println("Error: Unknown option: " + opt);
2440 return 1;
2441 }
2442 }
2443
2444 String component = getNextArg();
2445 ComponentName componentName =
2446 component != null ? ComponentName.unflattenFromString(component) : null;
2447
2448 if (componentName == null) {
2449 pw.println("Error: component name not specified or invalid");
2450 return 1;
2451 }
2452
2453 try {
2454 mInterface.setHomeActivity(componentName, userId);
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002455 pw.println("Success");
Makoto Onuki4828a592016-03-15 18:06:57 -07002456 return 0;
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002457 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07002458 pw.println(e.toString());
2459 return 1;
2460 }
2461 }
2462
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002463 private int runSetInstaller() throws RemoteException {
2464 final String targetPackage = getNextArg();
2465 final String installerPackageName = getNextArg();
Fyodor Kupolov51245c72016-12-01 11:34:10 -08002466
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002467 if (targetPackage == null || installerPackageName == null) {
2468 getErrPrintWriter().println("Must provide both target and installer package names");
Todd Kennedy74629e32017-08-15 14:48:07 -07002469 return 1;
2470 }
Todd Kennedy74629e32017-08-15 14:48:07 -07002471
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002472 mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2473 getOutPrintWriter().println("Success");
Svet Ganov087dce22017-09-07 15:42:16 -07002474 return 0;
2475 }
2476
Todd Kennedy0a3f0812017-05-08 14:43:15 -07002477 private int runGetInstantAppResolver() {
2478 final PrintWriter pw = getOutPrintWriter();
2479 try {
2480 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2481 if (instantAppsResolver == null) {
2482 return 1;
2483 }
2484 pw.println(instantAppsResolver.flattenToString());
2485 return 0;
2486 } catch (Exception e) {
2487 pw.println(e.toString());
2488 return 1;
2489 }
2490 }
2491
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09002492 private int runHasFeature() {
2493 final PrintWriter err = getErrPrintWriter();
2494 final String featureName = getNextArg();
2495 if (featureName == null) {
2496 err.println("Error: expected FEATURE name");
2497 return 1;
2498 }
2499 final String versionString = getNextArg();
2500 try {
2501 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2502 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2503 getOutPrintWriter().println(hasFeature);
2504 return hasFeature ? 0 : 1;
2505 } catch (NumberFormatException e) {
2506 err.println("Error: illegal version number " + versionString);
2507 return 1;
2508 } catch (RemoteException e) {
2509 err.println(e.toString());
2510 return 1;
2511 }
2512 }
2513
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002514 private int runDump() {
2515 String pkg = getNextArg();
2516 if (pkg == null) {
2517 getErrPrintWriter().println("Error: no package specified");
2518 return 1;
2519 }
2520 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2521 return 0;
2522 }
2523
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002524 private int runSetHarmfulAppWarning() throws RemoteException {
2525 int userId = UserHandle.USER_CURRENT;
2526
2527 String opt;
2528 while ((opt = getNextOption()) != null) {
2529 if (opt.equals("--user")) {
2530 userId = UserHandle.parseUserArg(getNextArgRequired());
2531 } else {
2532 getErrPrintWriter().println("Error: Unknown option: " + opt);
2533 return -1;
2534 }
2535 }
2536
2537 userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning");
2538
2539 final String packageName = getNextArgRequired();
2540 final String warning = getNextArg();
2541
2542 mInterface.setHarmfulAppWarning(packageName, warning, userId);
2543
2544 return 0;
2545 }
2546
Ben Gruver9ef60092018-01-10 11:32:30 -08002547 private int runGetHarmfulAppWarning() throws RemoteException {
2548 int userId = UserHandle.USER_CURRENT;
2549
2550 String opt;
2551 while ((opt = getNextOption()) != null) {
2552 if (opt.equals("--user")) {
2553 userId = UserHandle.parseUserArg(getNextArgRequired());
2554 } else {
2555 getErrPrintWriter().println("Error: Unknown option: " + opt);
2556 return -1;
2557 }
2558 }
2559
2560 userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning");
2561
2562 final String packageName = getNextArgRequired();
2563 final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId);
2564 if (!TextUtils.isEmpty(warning)) {
2565 getOutPrintWriter().println(warning);
2566 return 0;
2567 } else {
2568 return 1;
2569 }
2570 }
2571
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002572 private static String checkAbiArgument(String abi) {
2573 if (TextUtils.isEmpty(abi)) {
2574 throw new IllegalArgumentException("Missing ABI argument");
2575 }
2576
2577 if ("-".equals(abi)) {
2578 return abi;
2579 }
2580
2581 final String[] supportedAbis = Build.SUPPORTED_ABIS;
2582 for (String supportedAbi : supportedAbis) {
2583 if (supportedAbi.equals(abi)) {
2584 return abi;
2585 }
2586 }
2587
2588 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2589 }
2590
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002591 private int translateUserId(int userId, boolean allowAll, String logContext) {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002592 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002593 userId, allowAll, true, logContext, "pm command");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002594 }
2595
2596 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2597 throws RemoteException {
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002598 userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002599 if (userId == UserHandle.USER_ALL) {
2600 userId = UserHandle.USER_SYSTEM;
2601 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2602 }
2603
2604 final int sessionId = mInterface.getPackageInstaller()
2605 .createSession(params, installerPackageName, userId);
2606 return sessionId;
2607 }
2608
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002609 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002610 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002611 PackageInstaller.Session session = null;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002612 try {
Jeff Sharkeya651b782018-07-23 13:45:28 -06002613 final PrintWriter pw = getOutPrintWriter();
2614 final ParcelFileDescriptor fd;
2615 if (STDIN_PATH.equals(inPath)) {
2616 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2617 } else if (inPath != null) {
2618 fd = openFileForSystem(inPath, "r");
2619 if (fd == null) {
2620 return -1;
2621 }
2622 sizeBytes = fd.getStatSize();
2623 if (sizeBytes < 0) {
2624 getErrPrintWriter().println("Unable to get size of: " + inPath);
2625 return -1;
2626 }
2627 } else {
2628 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2629 }
2630 if (sizeBytes <= 0) {
2631 getErrPrintWriter().println("Error: must specify a APK size");
2632 return 1;
2633 }
2634
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002635 session = new PackageInstaller.Session(
2636 mInterface.getPackageInstaller().openSession(sessionId));
Jeff Sharkey0451de62018-02-02 11:27:21 -07002637 session.write(splitName, 0, sizeBytes, fd);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002638
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002639 if (logSuccess) {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002640 pw.println("Success: streamed " + sizeBytes + " bytes");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002641 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002642 return 0;
2643 } catch (IOException e) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002644 getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002645 return 1;
2646 } finally {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002647 IoUtils.closeQuietly(session);
2648 }
2649 }
2650
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002651 private int doInstallAddSession(int parentId, int[] sessionIds, boolean logSuccess)
2652 throws RemoteException {
2653 final PrintWriter pw = getOutPrintWriter();
2654 PackageInstaller.Session session = null;
2655 try {
2656 session = new PackageInstaller.Session(
2657 mInterface.getPackageInstaller().openSession(parentId));
2658 if (!session.isMultiPackage()) {
2659 getErrPrintWriter().println(
2660 "Error: parent session ID is not a multi-package session");
2661 return 1;
2662 }
2663 for (int i = 0; i < sessionIds.length; i++) {
2664 session.addChildSessionId(sessionIds[i]);
2665 }
2666 if (logSuccess) {
2667 pw.println("Success");
2668 }
2669 return 0;
2670 } finally {
2671 IoUtils.closeQuietly(session);
2672 }
2673 }
2674
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002675 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2676 throws RemoteException {
2677 final PrintWriter pw = getOutPrintWriter();
2678 PackageInstaller.Session session = null;
2679 try {
2680 session = new PackageInstaller.Session(
2681 mInterface.getPackageInstaller().openSession(sessionId));
2682 session.removeSplit(splitName);
2683
2684 if (logSuccess) {
2685 pw.println("Success");
2686 }
2687 return 0;
2688 } catch (IOException e) {
2689 pw.println("Error: failed to remove split; " + e.getMessage());
2690 return 1;
2691 } finally {
2692 IoUtils.closeQuietly(session);
2693 }
2694 }
2695
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002696 private int doCommitSession(int sessionId, boolean logSuccess)
2697 throws RemoteException {
2698
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002699 final PrintWriter pw = getOutPrintWriter();
2700 PackageInstaller.Session session = null;
2701 try {
2702 session = new PackageInstaller.Session(
2703 mInterface.getPackageInstaller().openSession(sessionId));
Dario Frenia8f4b132018-12-30 00:36:49 +00002704 if (!session.isMultiPackage() && !session.isStaged()) {
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002705 // Sanity check that all .dm files match an apk.
2706 // (The installer does not support standalone .dm files and will not process them.)
2707 try {
2708 DexMetadataHelper.validateDexPaths(session.getNames());
2709 } catch (IllegalStateException | IOException e) {
2710 pw.println(
2711 "Warning [Could not validate the dex paths: " + e.getMessage() + "]");
2712 }
Calin Juravle3fc56c32017-12-11 18:26:13 -08002713 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002714 final LocalIntentReceiver receiver = new LocalIntentReceiver();
2715 session.commit(receiver.getIntentSender());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002716 final Intent result = receiver.getResult();
2717 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2718 PackageInstaller.STATUS_FAILURE);
2719 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002720 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07002721 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002722 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002723 } else {
2724 pw.println("Failure ["
2725 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002726 }
2727 return status;
2728 } finally {
2729 IoUtils.closeQuietly(session);
2730 }
2731 }
2732
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002733 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002734 final PrintWriter pw = getOutPrintWriter();
2735 PackageInstaller.Session session = null;
2736 try {
2737 session = new PackageInstaller.Session(
2738 mInterface.getPackageInstaller().openSession(sessionId));
2739 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002740 if (logSuccess) {
2741 pw.println("Success");
2742 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002743 return 0;
2744 } finally {
2745 IoUtils.closeQuietly(session);
2746 }
2747 }
2748
Todd Kennedy60459ab2015-10-30 11:32:16 -07002749 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2750 boolean summary, int startProtectionLevel, int endProtectionLevel)
2751 throws RemoteException {
2752 final PrintWriter pw = getOutPrintWriter();
2753 final int groupCount = groupList.size();
2754 for (int i = 0; i < groupCount; i++) {
2755 String groupName = groupList.get(i);
2756 String prefix = "";
2757 if (groups) {
2758 if (i > 0) {
2759 pw.println("");
2760 }
2761 if (groupName != null) {
2762 PermissionGroupInfo pgi =
2763 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2764 if (summary) {
2765 Resources res = getResources(pgi);
2766 if (res != null) {
2767 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2768 } else {
2769 pw.print(pgi.name + ": ");
2770
2771 }
2772 } else {
2773 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2774 if (labels) {
2775 pw.println(" package:" + pgi.packageName);
2776 Resources res = getResources(pgi);
2777 if (res != null) {
2778 pw.println(" label:"
2779 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
2780 pw.println(" description:"
2781 + loadText(pgi, pgi.descriptionRes,
2782 pgi.nonLocalizedDescription));
2783 }
2784 }
2785 }
2786 } else {
2787 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
2788 }
2789 prefix = " ";
2790 }
2791 List<PermissionInfo> ps =
Jeff Sharkeyd5896632016-03-04 16:16:00 -07002792 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07002793 final int count = ps.size();
2794 boolean first = true;
2795 for (int p = 0 ; p < count ; p++) {
2796 PermissionInfo pi = ps.get(p);
2797 if (groups && groupName == null && pi.group != null) {
2798 continue;
2799 }
2800 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
2801 if (base < startProtectionLevel
2802 || base > endProtectionLevel) {
2803 continue;
2804 }
2805 if (summary) {
2806 if (first) {
2807 first = false;
2808 } else {
2809 pw.print(", ");
2810 }
2811 Resources res = getResources(pi);
2812 if (res != null) {
2813 pw.print(loadText(pi, pi.labelRes,
2814 pi.nonLocalizedLabel));
2815 } else {
2816 pw.print(pi.name);
2817 }
2818 } else {
2819 pw.println(prefix + (labels ? "+ " : "")
2820 + "permission:" + pi.name);
2821 if (labels) {
2822 pw.println(prefix + " package:" + pi.packageName);
2823 Resources res = getResources(pi);
2824 if (res != null) {
2825 pw.println(prefix + " label:"
2826 + loadText(pi, pi.labelRes,
2827 pi.nonLocalizedLabel));
2828 pw.println(prefix + " description:"
2829 + loadText(pi, pi.descriptionRes,
2830 pi.nonLocalizedDescription));
2831 }
2832 pw.println(prefix + " protectionLevel:"
2833 + PermissionInfo.protectionToString(pi.protectionLevel));
2834 }
2835 }
2836 }
2837
2838 if (summary) {
2839 pw.println("");
2840 }
2841 }
2842 }
2843
2844 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
2845 throws RemoteException {
2846 if (nonLocalized != null) {
2847 return nonLocalized.toString();
2848 }
2849 if (res != 0) {
2850 Resources r = getResources(pii);
2851 if (r != null) {
2852 try {
2853 return r.getString(res);
2854 } catch (Resources.NotFoundException e) {
2855 }
2856 }
2857 }
2858 return null;
2859 }
2860
2861 private Resources getResources(PackageItemInfo pii) throws RemoteException {
2862 Resources res = mResourceCache.get(pii.packageName);
2863 if (res != null) return res;
2864
2865 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
2866 AssetManager am = new AssetManager();
2867 am.addAssetPath(ai.publicSourceDir);
2868 res = new Resources(am, null, null);
2869 mResourceCache.put(pii.packageName, res);
2870 return res;
2871 }
2872
2873 @Override
2874 public void onHelp() {
2875 final PrintWriter pw = getOutPrintWriter();
2876 pw.println("Package manager (package) commands:");
2877 pw.println(" help");
2878 pw.println(" Print this help text.");
2879 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002880 pw.println(" path [--user USER_ID] PACKAGE");
2881 pw.println(" Print the path to the .apk of the given PACKAGE.");
2882 pw.println("");
2883 pw.println(" dump PACKAGE");
2884 pw.println(" Print various system state associated with the given PACKAGE.");
2885 pw.println("");
2886 pw.println(" list features");
2887 pw.println(" Prints all features of the system.");
2888 pw.println("");
2889 pw.println(" has-feature FEATURE_NAME [version]");
2890 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,");
2891 pw.println(" otherwise prints false and returns exit status 1");
2892 pw.println("");
2893 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
2894 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
2895 pw.println(" Options:");
2896 pw.println(" -f: dump the name of the .apk file containing the test package");
2897 pw.println("");
2898 pw.println(" list libraries");
2899 pw.println(" Prints all system libraries.");
2900 pw.println("");
2901 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
Jiyong Parkf50a2932018-12-17 13:54:40 +09002902 pw.println(" [--show-versioncode] [--apex-only] [--uid UID] [--user USER_ID] [FILTER]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002903 pw.println(" Prints all packages; optionally only those whose name contains");
2904 pw.println(" the text in FILTER. Options are:");
2905 pw.println(" -f: see their associated file");
Jiyong Park4f49abe2018-12-11 13:37:17 +09002906 pw.println(" -a: all known packages (but excluding APEXes)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002907 pw.println(" -d: filter to only show disabled packages");
2908 pw.println(" -e: filter to only show enabled packages");
2909 pw.println(" -s: filter to only show system packages");
2910 pw.println(" -3: filter to only show third party packages");
2911 pw.println(" -i: see the installer for the packages");
2912 pw.println(" -l: ignored (used for compatibility with older releases)");
2913 pw.println(" -U: also show the package UID");
2914 pw.println(" -u: also include uninstalled packages");
Jiyong Parkf50a2932018-12-17 13:54:40 +09002915 pw.println(" --show-versioncode: also show the version code");
Jiyong Park4f49abe2018-12-11 13:37:17 +09002916 pw.println(" --apex-only: only show APEX packages");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002917 pw.println(" --uid UID: filter to only show packages with the given UID");
2918 pw.println(" --user USER_ID: only list packages belonging to the given user");
2919 pw.println("");
2920 pw.println(" list permission-groups");
2921 pw.println(" Prints all known permission groups.");
2922 pw.println("");
2923 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
2924 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:");
2925 pw.println(" -g: organize by group");
2926 pw.println(" -f: print all information");
2927 pw.println(" -s: short summary");
2928 pw.println(" -d: only list dangerous permissions");
2929 pw.println(" -u: list only the permissions users will see");
2930 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07002931 pw.println(" resolve-activity [--brief] [--components] [--query-flags FLAGS]");
2932 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002933 pw.println(" Prints the activity that resolves to the given INTENT.");
2934 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07002935 pw.println(" query-activities [--brief] [--components] [--query-flags FLAGS]");
2936 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002937 pw.println(" Prints all activities that can handle the given INTENT.");
2938 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07002939 pw.println(" query-services [--brief] [--components] [--query-flags FLAGS]");
2940 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002941 pw.println(" Prints all services that can handle the given INTENT.");
2942 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07002943 pw.println(" query-receivers [--brief] [--components] [--query-flags FLAGS]");
2944 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002945 pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
2946 pw.println("");
2947 pw.println(" install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2948 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07002949 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
2950 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002951 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
Richard Uhlerb29f1452018-09-12 16:38:15 +01002952 pw.println(" [--enable-rollback]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01002953 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [--apex]");
2954 pw.println(" [PATH|-]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002955 pw.println(" Install an application. Must provide the apk data to install, either as a");
2956 pw.println(" file path or '-' to read from stdin. Options are:");
2957 pw.println(" -l: forward lock application");
Patrick Baumanna9333492017-11-28 15:23:49 -08002958 pw.println(" -R: disallow replacement of existing application");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002959 pw.println(" -t: allow test packages");
2960 pw.println(" -i: specify package name of installer owning the app");
2961 pw.println(" -s: install application on sdcard");
2962 pw.println(" -f: install application on internal flash");
2963 pw.println(" -d: allow version code downgrade (debuggable packages only)");
2964 pw.println(" -p: partial application install (new split on top of existing pkg)");
2965 pw.println(" -g: grant all runtime permissions");
2966 pw.println(" -S: size in bytes of package, required for stdin");
2967 pw.println(" --user: install under the given user.");
2968 pw.println(" --dont-kill: installing a new feature split, don't kill running app");
2969 pw.println(" --originating-uri: set URI where app was downloaded from");
2970 pw.println(" --referrer: set URI that instigated the install of the app");
2971 pw.println(" --pkg: specify expected package name of app being installed");
2972 pw.println(" --abi: override the default ABI of the platform");
2973 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app");
2974 pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
2975 pw.println(" --install-location: force the install location:");
2976 pw.println(" 0=auto, 1=internal only, 2=prefer external");
Sunny Goyalabd4d442018-09-19 15:49:50 -07002977 pw.println(" --install-reason: indicates why the app is being installed:");
2978 pw.println(" 0=unknown, 1=admin policy, 2=device restore,");
2979 pw.println(" 3=device setup, 4=user request");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002980 pw.println(" --force-uuid: force install on to disk volume with given UUID");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01002981 pw.println(" --apex: install an .apex file, not an .apk");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002982 pw.println("");
2983 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2984 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07002985 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
2986 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002987 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01002988 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [--apex] [-S BYTES]");
Dario Freniaac4ba42018-12-06 15:47:16 +00002989 pw.println(" [--multi-package] [--staged]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002990 pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
2991 pw.println(" to push data into the session, and \"install-commit\" to finish.");
2992 pw.println("");
2993 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
2994 pw.println(" Write an apk into the given install session. If the path is '-', data");
2995 pw.println(" will be read from stdin. Options are:");
2996 pw.println(" -S: size in bytes of package, required for stdin");
2997 pw.println("");
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002998 pw.println(" install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs");
2999 pw.println(" Add one or more session IDs to a multi-package session.");
3000 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003001 pw.println(" install-commit SESSION_ID");
3002 pw.println(" Commit the given active install session, installing the app.");
3003 pw.println("");
3004 pw.println(" install-abandon SESSION_ID");
3005 pw.println(" Delete the given active install session.");
3006 pw.println("");
3007 pw.println(" set-install-location LOCATION");
3008 pw.println(" Changes the default install location. NOTE this is only intended for debugging;");
3009 pw.println(" using this can cause applications to break and other undersireable behavior.");
3010 pw.println(" LOCATION is one of:");
3011 pw.println(" 0 [auto]: Let system decide the best location");
3012 pw.println(" 1 [internal]: Install on internal device storage");
3013 pw.println(" 2 [external]: Install on external media");
3014 pw.println("");
3015 pw.println(" get-install-location");
3016 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location.");
3017 pw.println("");
3018 pw.println(" move-package PACKAGE [internal|UUID]");
3019 pw.println("");
3020 pw.println(" move-primary-storage [internal|UUID]");
3021 pw.println("");
3022 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
3023 pw.println(" Remove the given package name from the system. May remove an entire app");
3024 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
3025 pw.println(" given app. Options are:");
3026 pw.println(" -k: keep the data and cache directories around after package removal.");
3027 pw.println(" --user: remove the app from the given user.");
3028 pw.println(" --versionCode: only uninstall if the app has the given version code.");
3029 pw.println("");
3030 pw.println(" clear [--user USER_ID] PACKAGE");
3031 pw.println(" Deletes all data associated with a package.");
3032 pw.println("");
3033 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT");
3034 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT");
3035 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
3036 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
3037 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
3038 pw.println(" These commands change the enabled state of a given package or");
3039 pw.println(" component (written as \"package/class\").");
3040 pw.println("");
3041 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT");
3042 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
3043 pw.println("");
3044 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
3045 pw.println(" Suspends the specified package (as user).");
3046 pw.println("");
3047 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
3048 pw.println(" Unsuspends the specified package (as user).");
3049 pw.println("");
3050 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
3051 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
3052 pw.println(" These commands either grant or revoke permissions to apps. The permissions");
3053 pw.println(" must be declared as used in the app's manifest, be runtime permissions");
3054 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
3055 pw.println("");
3056 pw.println(" reset-permissions");
3057 pw.println(" Revert all runtime permissions to their default state.");
3058 pw.println("");
3059 pw.println(" set-permission-enforced PERMISSION [true|false]");
3060 pw.println("");
3061 pw.println(" get-privapp-permissions TARGET-PACKAGE");
3062 pw.println(" Prints all privileged permissions for a package.");
3063 pw.println("");
3064 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE");
3065 pw.println(" Prints all privileged permissions that are denied for a package.");
3066 pw.println("");
3067 pw.println(" get-oem-permissions TARGET-PACKAGE");
3068 pw.println(" Prints all OEM permissions for a package.");
3069 pw.println("");
3070 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
3071 pw.println(" get-app-link [--user USER_ID] PACKAGE");
3072 pw.println("");
3073 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
3074 pw.println(" Trim cache files to reach the given free space.");
3075 pw.println("");
3076 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
3077 pw.println(" [--guest] USER_NAME");
3078 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
3079 pw.println(" of the user.");
3080 pw.println("");
3081 pw.println(" remove-user USER_ID");
3082 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data");
3083 pw.println(" associated with that user");
3084 pw.println("");
3085 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE");
3086 pw.println("");
3087 pw.println(" get-max-users");
3088 pw.println("");
Alex Chauc12189b2018-01-16 15:01:15 +00003089 pw.println(" get-max-running-users");
3090 pw.println("");
Calin Juravleb6f844d2017-07-17 15:23:21 -07003091 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
Richard Uhler568a9692016-05-03 16:02:52 -07003092 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003093 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
David Brazdil990fb6b2016-03-01 10:02:27 +00003094 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00003095 pw.println(" -c: clear profile data before compiling");
3096 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00003097 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07003098 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01003099 pw.println(" assume-verified");
3100 pw.println(" extract");
3101 pw.println(" verify");
3102 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07003103 pw.println(" space-profile");
3104 pw.println(" space");
3105 pw.println(" speed-profile");
3106 pw.println(" speed");
3107 pw.println(" everything");
3108 pw.println(" -r: select compilation reason");
3109 pw.println(" REASON is one of:");
3110 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
3111 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
3112 }
David Brazdilcf046952016-03-08 16:40:20 +00003113 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07003114 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08003115 pw.println(" --secondary-dex: compile app secondary dex files");
Calin Juravleb6f844d2017-07-17 15:23:21 -07003116 pw.println(" --split SPLIT: compile only the given split name");
Eric Holka1485f62019-01-07 13:58:25 -08003117 pw.println(" --compile-layouts: compile layout resources for faster inflation");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003118 pw.println("");
3119 pw.println(" force-dex-opt PACKAGE");
3120 pw.println(" Force immediate execution of dex opt for the given PACKAGE.");
3121 pw.println("");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08003122 pw.println(" bg-dexopt-job");
3123 pw.println(" Execute the background optimizations immediately.");
3124 pw.println(" Note that the command only runs the background optimizer logic. It may");
3125 pw.println(" overlap with the actual job but the job scheduler will not be able to");
3126 pw.println(" cancel it. It will also run even if the device is not in the idle");
3127 pw.println(" maintenance mode.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003128 pw.println("");
Calin Juravle1aa5f882017-01-25 01:05:50 -08003129 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
3130 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003131 pw.println("");
David Sehrcae13b02016-06-07 09:11:27 -07003132 pw.println(" dump-profiles TARGET-PACKAGE");
3133 pw.println(" Dumps method/class profile files to");
Calin Juravle21216c62018-05-04 17:35:29 -07003134 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt");
3135 pw.println("");
3136 pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]");
3137 pw.println(" Take a snapshot of the package profiles to");
3138 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
3139 + "TARGET-PACKAGE[-code-path].prof");
3140 pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003141 pw.println("");
Makoto Onuki4828a592016-03-15 18:06:57 -07003142 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003143 pw.println(" Set the default home activity (aka launcher).");
3144 pw.println("");
3145 pw.println(" set-installer PACKAGE INSTALLER");
3146 pw.println(" Set installer package name");
3147 pw.println("");
3148 pw.println(" get-instantapp-resolver");
3149 pw.println(" Return the name of the component that is the current instant app installer.");
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08003150 pw.println("");
3151 pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
3152 pw.println(" Mark the app as harmful with the given warning message.");
Ben Gruver9ef60092018-01-10 11:32:30 -08003153 pw.println("");
3154 pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
3155 pw.println(" Return the harmful app warning message for the given app, if present");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003156 pw.println();
Patrick Baumanna980e142018-02-12 11:45:23 -08003157 pw.println(" uninstall-system-updates");
3158 pw.println(" Remove updates to all system applications and fall back to their /system " +
3159 "version.");
3160 pw.println();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003161 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07003162 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003163
3164 private static class LocalIntentReceiver {
wangmingming155414292018-04-10 09:35:25 +08003165 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003166
3167 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
3168 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07003169 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003170 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
3171 try {
3172 mResult.offer(intent, 5, TimeUnit.SECONDS);
3173 } catch (InterruptedException e) {
3174 throw new RuntimeException(e);
3175 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003176 }
3177 };
3178
3179 public IntentSender getIntentSender() {
3180 return new IntentSender((IIntentSender) mLocalSender);
3181 }
3182
3183 public Intent getResult() {
3184 try {
3185 return mResult.take();
3186 } catch (InterruptedException e) {
3187 throw new RuntimeException(e);
3188 }
3189 }
3190 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07003191}