blob: 6f275ece1a1f48cf3c10b97221395d60bb1cf69e [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;
Jeff Sharkey0451de62018-02-02 11:27:21 -070042import android.content.pm.PackageInstaller.SessionParams;
Todd Kennedy60459ab2015-10-30 11:32:16 -070043import android.content.pm.PackageItemInfo;
44import android.content.pm.PackageManager;
Jeff Sharkey0451de62018-02-02 11:27:21 -070045import android.content.pm.PackageManager.NameNotFoundException;
Shunta Sato4f26cb52016-06-28 09:29:19 +090046import android.content.pm.PackageParser;
47import android.content.pm.PackageParser.ApkLite;
48import android.content.pm.PackageParser.PackageLite;
49import android.content.pm.PackageParser.PackageParserException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070050import android.content.pm.ParceledListSlice;
51import android.content.pm.PermissionGroupInfo;
52import android.content.pm.PermissionInfo;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080053import android.content.pm.ResolveInfo;
Suprabh Shukla389cb6f2018-10-01 18:20:39 -070054import android.content.pm.SuspendDialogInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070055import android.content.pm.UserInfo;
Svet Ganov67882122016-12-11 16:36:34 -080056import android.content.pm.VersionedPackage;
Calin Juravle21216c62018-05-04 17:35:29 -070057import android.content.pm.dex.ArtManager;
Calin Juravle3fc56c32017-12-11 18:26:13 -080058import android.content.pm.dex.DexMetadataHelper;
Calin Juravle21216c62018-05-04 17:35:29 -070059import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
Todd Kennedy60459ab2015-10-30 11:32:16 -070060import android.content.res.AssetManager;
61import android.content.res.Resources;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080062import android.net.Uri;
63import android.os.Binder;
64import android.os.Build;
65import android.os.Bundle;
Dianne Hackborn98305522017-05-05 17:53:53 -070066import android.os.IBinder;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070067import android.os.IUserManager;
Dianne Hackbornca3872c2017-10-30 14:19:32 -070068import android.os.ParcelFileDescriptor;
Calin Juravle21216c62018-05-04 17:35:29 -070069import android.os.ParcelFileDescriptor.AutoCloseInputStream;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080070import android.os.PersistableBundle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070071import android.os.Process;
Todd Kennedy60459ab2015-10-30 11:32:16 -070072import android.os.RemoteException;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070073import android.os.ServiceManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070074import android.os.ShellCommand;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070075import android.os.SystemClock;
Calin Juravle8bc758b2016-03-28 12:31:52 +010076import android.os.SystemProperties;
Todd Kennedy60459ab2015-10-30 11:32:16 -070077import android.os.UserHandle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070078import android.os.UserManager;
79import android.os.storage.StorageManager;
Calin Juravlebdd94d92018-05-17 01:23:15 -070080import android.system.ErrnoException;
81import android.system.Os;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080082import android.text.TextUtils;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070083import android.text.format.DateUtils;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080084import android.util.ArraySet;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080085import android.util.PrintWriterPrinter;
Dario Freni2bef1762018-06-01 14:02:08 +010086
Shunta Sato4f26cb52016-06-28 09:29:19 +090087import com.android.internal.content.PackageHelper;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070088import com.android.internal.util.ArrayUtils;
Alex Chauc12189b2018-01-16 15:01:15 +000089import com.android.server.LocalServices;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080090import com.android.server.SystemConfig;
Dario Freni2bef1762018-06-01 14:02:08 +010091
Andreas Gampebdd30d82016-03-20 11:32:11 -070092import dalvik.system.DexFile;
Dario Freni2bef1762018-06-01 14:02:08 +010093
94import libcore.io.IoUtils;
95import libcore.io.Streams;
96
Calin Juravle21216c62018-05-04 17:35:29 -070097import java.io.File;
98import java.io.FileOutputStream;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080099import java.io.IOException;
Calin Juravle21216c62018-05-04 17:35:29 -0700100import java.io.InputStream;
101import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700102import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800103import java.net.URISyntaxException;
Calin Juravle21216c62018-05-04 17:35:29 -0700104import java.util.ArrayList;
105import java.util.Collections;
106import java.util.Comparator;
107import java.util.LinkedList;
108import java.util.List;
109import java.util.Map;
110import java.util.Objects;
111import java.util.WeakHashMap;
112import java.util.concurrent.CountDownLatch;
wangmingming155414292018-04-10 09:35:25 +0800113import java.util.concurrent.LinkedBlockingQueue;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800114import java.util.concurrent.TimeUnit;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700115
116class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700117 /** Path for streaming APK content */
118 private static final String STDIN_PATH = "-";
Calin Juravle21216c62018-05-04 17:35:29 -0700119 /** Path where ART profiles snapshots are dumped for the shell user */
120 private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700121
Todd Kennedy60459ab2015-10-30 11:32:16 -0700122 final IPackageManager mInterface;
123 final private WeakHashMap<String, Resources> mResourceCache =
124 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800125 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700126 boolean mBrief;
127 boolean mComponents;
Ng Zhi An73971312018-09-11 21:39:14 -0700128 int mQueryFlags;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700129
130 PackageManagerShellCommand(PackageManagerService service) {
131 mInterface = service;
132 }
133
134 @Override
135 public int onCommand(String cmd) {
136 if (cmd == null) {
137 return handleDefaultCommands(cmd);
138 }
139
140 final PrintWriter pw = getOutPrintWriter();
141 try {
142 switch(cmd) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700143 case "path":
144 return runPath();
145 case "dump":
146 return runDump();
147 case "list":
148 return runList();
149 case "resolve-activity":
150 return runResolveActivity();
151 case "query-activities":
152 return runQueryIntentActivities();
153 case "query-services":
154 return runQueryIntentServices();
155 case "query-receivers":
156 return runQueryIntentReceivers();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800157 case "install":
158 return runInstall();
159 case "install-abandon":
160 case "install-destroy":
161 return runInstallAbandon();
162 case "install-commit":
163 return runInstallCommit();
164 case "install-create":
165 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800166 case "install-remove":
167 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800168 case "install-write":
169 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800170 case "install-existing":
171 return runInstallExisting();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700172 case "set-install-location":
173 return runSetInstallLocation();
174 case "get-install-location":
175 return runGetInstallLocation();
Patrick Baumann0aff9b12018-11-08 14:05:08 +0000176 case "install-add-session":
177 return runInstallAddSession();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700178 case "move-package":
179 return runMovePackage();
180 case "move-primary-storage":
181 return runMovePrimaryStorage();
David Brazdil493411a2016-02-01 13:48:46 +0000182 case "compile":
183 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800184 case "reconcile-secondary-dex-files":
185 return runreconcileSecondaryDexFiles();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700186 case "force-dex-opt":
187 return runForceDexOpt();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800188 case "bg-dexopt-job":
189 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700190 case "dump-profiles":
191 return runDumpProfiles();
Calin Juravle21216c62018-05-04 17:35:29 -0700192 case "snapshot-profile":
193 return runSnapshotProfile();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800194 case "uninstall":
195 return runUninstall();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700196 case "clear":
197 return runClear();
198 case "enable":
199 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
200 case "disable":
201 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
202 case "disable-user":
203 return runSetEnabledSetting(
204 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
205 case "disable-until-used":
206 return runSetEnabledSetting(
207 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
208 case "default-state":
209 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
210 case "hide":
211 return runSetHiddenSetting(true);
212 case "unhide":
213 return runSetHiddenSetting(false);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000214 case "suspend":
215 return runSuspend(true);
216 case "unsuspend":
217 return runSuspend(false);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700218 case "grant":
219 return runGrantRevokePermission(true);
220 case "revoke":
221 return runGrantRevokePermission(false);
222 case "reset-permissions":
223 return runResetPermissions();
224 case "set-permission-enforced":
225 return runSetPermissionEnforced();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800226 case "get-privapp-permissions":
227 return runGetPrivappPermissions();
Todd Kennedy74629e32017-08-15 14:48:07 -0700228 case "get-privapp-deny-permissions":
229 return runGetPrivappDenyPermissions();
Svet Ganov087dce22017-09-07 15:42:16 -0700230 case "get-oem-permissions":
231 return runGetOemPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700232 case "set-app-link":
233 return runSetAppLink();
234 case "get-app-link":
235 return runGetAppLink();
236 case "trim-caches":
237 return runTrimCaches();
238 case "create-user":
239 return runCreateUser();
240 case "remove-user":
241 return runRemoveUser();
242 case "set-user-restriction":
243 return runSetUserRestriction();
244 case "get-max-users":
245 return runGetMaxUsers();
Alex Chauc12189b2018-01-16 15:01:15 +0000246 case "get-max-running-users":
247 return runGetMaxRunningUsers();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700248 case "set-home-activity":
249 return runSetHomeActivity();
250 case "set-installer":
251 return runSetInstaller();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700252 case "get-instantapp-resolver":
253 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900254 case "has-feature":
255 return runHasFeature();
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800256 case "set-harmful-app-warning":
257 return runSetHarmfulAppWarning();
Ben Gruver9ef60092018-01-10 11:32:30 -0800258 case "get-harmful-app-warning":
259 return runGetHarmfulAppWarning();
Patrick Baumanna980e142018-02-12 11:45:23 -0800260 case "uninstall-system-updates":
261 return uninstallSystemUpdates();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700262 default: {
263 String nextArg = getNextArg();
264 if (nextArg == null) {
265 if (cmd.equalsIgnoreCase("-l")) {
266 return runListPackages(false);
267 } else if (cmd.equalsIgnoreCase("-lf")) {
268 return runListPackages(true);
269 }
270 } else if (getNextArg() == null) {
271 if (cmd.equalsIgnoreCase("-p")) {
272 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
273 }
274 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700275 return handleDefaultCommands(cmd);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700276 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700277 }
278 } catch (RemoteException e) {
279 pw.println("Remote exception: " + e);
280 }
281 return -1;
282 }
283
Patrick Baumanna980e142018-02-12 11:45:23 -0800284 private int uninstallSystemUpdates() {
285 final PrintWriter pw = getOutPrintWriter();
286 List<String> failedUninstalls = new LinkedList<>();
287 try {
288 final ParceledListSlice<ApplicationInfo> packages =
289 mInterface.getInstalledApplications(
290 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
291 final IPackageInstaller installer = mInterface.getPackageInstaller();
292 List<ApplicationInfo> list = packages.getList();
293 for (ApplicationInfo info : list) {
294 if (info.isUpdatedSystemApp()) {
295 pw.println("Uninstalling updates to " + info.packageName + "...");
296 final LocalIntentReceiver receiver = new LocalIntentReceiver();
297 installer.uninstall(new VersionedPackage(info.packageName,
298 info.versionCode), null /*callerPackageName*/, 0 /* flags */,
299 receiver.getIntentSender(), 0);
300
301 final Intent result = receiver.getResult();
302 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
303 PackageInstaller.STATUS_FAILURE);
304 if (status != PackageInstaller.STATUS_SUCCESS) {
305 failedUninstalls.add(info.packageName);
306 }
307 }
308 }
309 } catch (RemoteException e) {
310 pw.println("Failure ["
311 + e.getClass().getName() + " - "
312 + e.getMessage() + "]");
313 return 0;
314 }
315 if (!failedUninstalls.isEmpty()) {
316 pw.println("Failure [Couldn't uninstall packages: "
317 + TextUtils.join(", ", failedUninstalls)
318 + "]");
319 return 0;
320 }
321 pw.println("Success");
322 return 1;
323 }
324
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700325 private void setParamsSize(InstallParams params, String inPath) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700326 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700327 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
328 if (fd == null) {
329 getErrPrintWriter().println("Error: Can't open file: " + inPath);
330 throw new IllegalArgumentException("Error: Can't open file: " + inPath);
331 }
332 try {
333 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
334 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
335 null, null);
336 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
Dianne Hackborn1704e3c2017-10-31 19:55:42 +0000337 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700338 } catch (PackageParserException | IOException e) {
339 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
340 throw new IllegalArgumentException(
341 "Error: Failed to parse APK file: " + inPath, e);
342 } finally {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900343 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700344 fd.close();
345 } catch (IOException e) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900346 }
347 }
348 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700349 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700350 /**
351 * Displays the package file for a package.
352 * @param pckg
353 */
354 private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
355 PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId);
356 if (info != null && info.applicationInfo != null) {
357 final PrintWriter pw = getOutPrintWriter();
358 pw.print("package:");
359 pw.println(info.applicationInfo.sourceDir);
360 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
361 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
362 pw.print("package:");
363 pw.println(splitSourceDir);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800364 }
365 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700366 return 0;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800367 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700368 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800369 }
370
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700371 private int runPath() throws RemoteException {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000372 int userId = UserHandle.USER_SYSTEM;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700373 String option = getNextOption();
374 if (option != null && option.equals("--user")) {
375 userId = UserHandle.parseUserArg(getNextArgRequired());
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000376 }
377
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700378 String pkg = getNextArgRequired();
379 if (pkg == null) {
380 getErrPrintWriter().println("Error: no package specified");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000381 return 1;
382 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700383 return displayPackageFilePath(pkg, userId);
David Sehra8777082016-05-24 15:25:23 -0700384 }
385
Todd Kennedy60459ab2015-10-30 11:32:16 -0700386 private int runList() throws RemoteException {
387 final PrintWriter pw = getOutPrintWriter();
388 final String type = getNextArg();
389 if (type == null) {
390 pw.println("Error: didn't specify type of data to list");
391 return -1;
392 }
393 switch(type) {
394 case "features":
395 return runListFeatures();
396 case "instrumentation":
397 return runListInstrumentation();
398 case "libraries":
399 return runListLibraries();
400 case "package":
401 case "packages":
402 return runListPackages(false /*showSourceDir*/);
403 case "permission-groups":
404 return runListPermissionGroups();
405 case "permissions":
406 return runListPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700407 case "users":
408 ServiceManager.getService("user").shellCommand(
409 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
410 new String[] { "list" }, getShellCallback(), adoptResultReceiver());
411 return 0;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700412 }
413 pw.println("Error: unknown list type '" + type + "'");
414 return -1;
415 }
416
417 private int runListFeatures() throws RemoteException {
418 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700419 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700420
421 // sort by name
422 Collections.sort(list, new Comparator<FeatureInfo>() {
423 public int compare(FeatureInfo o1, FeatureInfo o2) {
424 if (o1.name == o2.name) return 0;
425 if (o1.name == null) return -1;
426 if (o2.name == null) return 1;
427 return o1.name.compareTo(o2.name);
428 }
429 });
430
431 final int count = (list != null) ? list.size() : 0;
432 for (int p = 0; p < count; p++) {
433 FeatureInfo fi = list.get(p);
434 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700435 if (fi.name != null) {
436 pw.print(fi.name);
437 if (fi.version > 0) {
438 pw.print("=");
439 pw.print(fi.version);
440 }
441 pw.println();
442 } else {
443 pw.println("reqGlEsVersion=0x"
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700444 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700445 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700446 }
447 return 0;
448 }
449
450 private int runListInstrumentation() throws RemoteException {
451 final PrintWriter pw = getOutPrintWriter();
452 boolean showSourceDir = false;
453 String targetPackage = null;
454
455 try {
456 String opt;
457 while ((opt = getNextArg()) != null) {
458 switch (opt) {
459 case "-f":
460 showSourceDir = true;
461 break;
462 default:
463 if (opt.charAt(0) != '-') {
464 targetPackage = opt;
465 } else {
466 pw.println("Error: Unknown option: " + opt);
467 return -1;
468 }
469 break;
470 }
471 }
472 } catch (RuntimeException ex) {
473 pw.println("Error: " + ex.toString());
474 return -1;
475 }
476
477 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700478 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700479
480 // sort by target package
481 Collections.sort(list, new Comparator<InstrumentationInfo>() {
482 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
483 return o1.targetPackage.compareTo(o2.targetPackage);
484 }
485 });
486
487 final int count = (list != null) ? list.size() : 0;
488 for (int p = 0; p < count; p++) {
489 final InstrumentationInfo ii = list.get(p);
490 pw.print("instrumentation:");
491 if (showSourceDir) {
492 pw.print(ii.sourceDir);
493 pw.print("=");
494 }
495 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
496 pw.print(cn.flattenToShortString());
497 pw.print(" (target=");
498 pw.print(ii.targetPackage);
499 pw.println(")");
500 }
501 return 0;
502 }
503
504 private int runListLibraries() throws RemoteException {
505 final PrintWriter pw = getOutPrintWriter();
506 final List<String> list = new ArrayList<String>();
507 final String[] rawList = mInterface.getSystemSharedLibraryNames();
508 for (int i = 0; i < rawList.length; i++) {
509 list.add(rawList[i]);
510 }
511
512 // sort by name
513 Collections.sort(list, new Comparator<String>() {
514 public int compare(String o1, String o2) {
515 if (o1 == o2) return 0;
516 if (o1 == null) return -1;
517 if (o2 == null) return 1;
518 return o1.compareTo(o2);
519 }
520 });
521
522 final int count = (list != null) ? list.size() : 0;
523 for (int p = 0; p < count; p++) {
524 String lib = list.get(p);
525 pw.print("library:");
526 pw.println(lib);
527 }
528 return 0;
529 }
530
531 private int runListPackages(boolean showSourceDir) throws RemoteException {
532 final PrintWriter pw = getOutPrintWriter();
533 int getFlags = 0;
534 boolean listDisabled = false, listEnabled = false;
535 boolean listSystem = false, listThirdParty = false;
536 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700537 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800538 boolean showVersionCode = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700539 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700540 int userId = UserHandle.USER_SYSTEM;
541 try {
542 String opt;
543 while ((opt = getNextOption()) != null) {
544 switch (opt) {
545 case "-d":
546 listDisabled = true;
547 break;
548 case "-e":
549 listEnabled = true;
550 break;
Andreas Gampe1f110452018-06-04 11:47:48 -0700551 case "-a":
552 getFlags |= PackageManager.MATCH_KNOWN_PACKAGES;
553 getFlags |= PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
554 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700555 case "-f":
556 showSourceDir = true;
557 break;
558 case "-i":
559 listInstaller = true;
560 break;
561 case "-l":
562 // old compat
563 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700564 case "-s":
565 listSystem = true;
566 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700567 case "-U":
568 showUid = true;
569 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700570 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700571 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700572 break;
573 case "-3":
574 listThirdParty = true;
575 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800576 case "--show-versioncode":
577 showVersionCode = true;
578 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700579 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800580 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700581 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700582 case "--uid":
583 showUid = true;
584 uid = Integer.parseInt(getNextArgRequired());
585 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700586 default:
587 pw.println("Error: Unknown option: " + opt);
588 return -1;
589 }
590 }
591 } catch (RuntimeException ex) {
592 pw.println("Error: " + ex.toString());
593 return -1;
594 }
595
596 final String filter = getNextArg();
597
598 @SuppressWarnings("unchecked")
599 final ParceledListSlice<PackageInfo> slice =
600 mInterface.getInstalledPackages(getFlags, userId);
601 final List<PackageInfo> packages = slice.getList();
602
603 final int count = packages.size();
604 for (int p = 0; p < count; p++) {
605 final PackageInfo info = packages.get(p);
606 if (filter != null && !info.packageName.contains(filter)) {
607 continue;
608 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700609 if (uid != -1 && info.applicationInfo.uid != uid) {
610 continue;
611 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700612 final boolean isSystem =
613 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
614 if ((!listDisabled || !info.applicationInfo.enabled) &&
615 (!listEnabled || info.applicationInfo.enabled) &&
616 (!listSystem || isSystem) &&
617 (!listThirdParty || !isSystem)) {
618 pw.print("package:");
619 if (showSourceDir) {
620 pw.print(info.applicationInfo.sourceDir);
621 pw.print("=");
622 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800623 pw.print(info.packageName);
624 if (showVersionCode) {
625 pw.print(" versionCode:");
626 pw.print(info.applicationInfo.versionCode);
627 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700628 if (listInstaller) {
629 pw.print(" installer=");
630 pw.print(mInterface.getInstallerPackageName(info.packageName));
631 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700632 if (showUid) {
633 pw.print(" uid:");
634 pw.print(info.applicationInfo.uid);
635 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700636 pw.println();
637 }
638 }
639 return 0;
640 }
641
642 private int runListPermissionGroups() throws RemoteException {
643 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700644 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700645
646 final int count = pgs.size();
647 for (int p = 0; p < count ; p++) {
648 final PermissionGroupInfo pgi = pgs.get(p);
649 pw.print("permission group:");
650 pw.println(pgi.name);
651 }
652 return 0;
653 }
654
655 private int runListPermissions() throws RemoteException {
656 final PrintWriter pw = getOutPrintWriter();
657 boolean labels = false;
658 boolean groups = false;
659 boolean userOnly = false;
660 boolean summary = false;
661 boolean dangerousOnly = false;
662 String opt;
663 while ((opt = getNextOption()) != null) {
664 switch (opt) {
665 case "-d":
666 dangerousOnly = true;
667 break;
668 case "-f":
669 labels = true;
670 break;
671 case "-g":
672 groups = true;
673 break;
674 case "-s":
675 groups = true;
676 labels = true;
677 summary = true;
678 break;
679 case "-u":
680 userOnly = true;
681 break;
682 default:
683 pw.println("Error: Unknown option: " + opt);
684 return 1;
685 }
686 }
687
688 final ArrayList<String> groupList = new ArrayList<String>();
689 if (groups) {
690 final List<PermissionGroupInfo> infos =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700691 mInterface.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700692 final int count = infos.size();
693 for (int i = 0; i < count; i++) {
694 groupList.add(infos.get(i).name);
695 }
696 groupList.add(null);
697 } else {
698 final String grp = getNextArg();
699 groupList.add(grp);
700 }
701
702 if (dangerousOnly) {
703 pw.println("Dangerous Permissions:");
704 pw.println("");
705 doListPermissions(groupList, groups, labels, summary,
706 PermissionInfo.PROTECTION_DANGEROUS,
707 PermissionInfo.PROTECTION_DANGEROUS);
708 if (userOnly) {
709 pw.println("Normal Permissions:");
710 pw.println("");
711 doListPermissions(groupList, groups, labels, summary,
712 PermissionInfo.PROTECTION_NORMAL,
713 PermissionInfo.PROTECTION_NORMAL);
714 }
715 } else if (userOnly) {
716 pw.println("Dangerous and Normal Permissions:");
717 pw.println("");
718 doListPermissions(groupList, groups, labels, summary,
719 PermissionInfo.PROTECTION_NORMAL,
720 PermissionInfo.PROTECTION_DANGEROUS);
721 } else {
722 pw.println("All Permissions:");
723 pw.println("");
724 doListPermissions(groupList, groups, labels, summary,
725 -10000, 10000);
726 }
727 return 0;
728 }
729
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800730 private Intent parseIntentAndUser() throws URISyntaxException {
731 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700732 mBrief = false;
733 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800734 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
735 @Override
736 public boolean handleOption(String opt, ShellCommand cmd) {
737 if ("--user".equals(opt)) {
738 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
739 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700740 } else if ("--brief".equals(opt)) {
741 mBrief = true;
742 return true;
743 } else if ("--components".equals(opt)) {
744 mComponents = true;
745 return true;
Ng Zhi An73971312018-09-11 21:39:14 -0700746 } else if ("--query-flags".equals(opt)) {
747 mQueryFlags = Integer.decode(cmd.getNextArgRequired());
748 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800749 }
750 return false;
751 }
752 });
753 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
754 Binder.getCallingUid(), mTargetUser, false, false, null, null);
755 return intent;
756 }
757
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700758 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
759 boolean brief, boolean components) {
760 if (brief || components) {
761 final ComponentName comp;
762 if (ri.activityInfo != null) {
763 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
764 } else if (ri.serviceInfo != null) {
765 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
766 } else if (ri.providerInfo != null) {
767 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
768 } else {
769 comp = null;
770 }
771 if (comp != null) {
772 if (!components) {
773 pr.println(prefix + "priority=" + ri.priority
774 + " preferredOrder=" + ri.preferredOrder
775 + " match=0x" + Integer.toHexString(ri.match)
776 + " specificIndex=" + ri.specificIndex
777 + " isDefault=" + ri.isDefault);
778 }
779 pr.println(prefix + comp.flattenToShortString());
780 return;
781 }
782 }
783 ri.dump(pr, prefix);
784 }
785
Dianne Hackborn99878e92015-12-02 16:27:41 -0800786 private int runResolveActivity() {
787 Intent intent;
788 try {
789 intent = parseIntentAndUser();
790 } catch (URISyntaxException e) {
791 throw new RuntimeException(e.getMessage(), e);
792 }
793 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700794 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), mQueryFlags,
795 mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800796 PrintWriter pw = getOutPrintWriter();
797 if (ri == null) {
798 pw.println("No activity found");
799 } else {
800 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700801 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800802 }
803 } catch (RemoteException e) {
804 throw new RuntimeException("Failed calling service", e);
805 }
806 return 0;
807 }
808
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800809 private int runQueryIntentActivities() {
810 Intent intent;
811 try {
812 intent = parseIntentAndUser();
813 } catch (URISyntaxException e) {
814 throw new RuntimeException(e.getMessage(), e);
815 }
816 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700817 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(),
818 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800819 PrintWriter pw = getOutPrintWriter();
820 if (result == null || result.size() <= 0) {
821 pw.println("No activities found");
822 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700823 if (!mComponents) {
824 pw.print(result.size()); pw.println(" activities found:");
825 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
826 for (int i = 0; i < result.size(); i++) {
827 pw.print(" Activity #"); pw.print(i); pw.println(":");
828 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
829 }
830 } else {
831 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
832 for (int i = 0; i < result.size(); i++) {
833 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
834 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800835 }
836 }
837 } catch (RemoteException e) {
838 throw new RuntimeException("Failed calling service", e);
839 }
840 return 0;
841 }
842
843 private int runQueryIntentServices() {
844 Intent intent;
845 try {
846 intent = parseIntentAndUser();
847 } catch (URISyntaxException e) {
848 throw new RuntimeException(e.getMessage(), e);
849 }
850 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700851 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(),
852 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800853 PrintWriter pw = getOutPrintWriter();
854 if (result == null || result.size() <= 0) {
855 pw.println("No services found");
856 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700857 if (!mComponents) {
858 pw.print(result.size()); pw.println(" services found:");
859 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
860 for (int i = 0; i < result.size(); i++) {
861 pw.print(" Service #"); pw.print(i); pw.println(":");
862 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
863 }
864 } else {
865 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
866 for (int i = 0; i < result.size(); i++) {
867 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
868 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800869 }
870 }
871 } catch (RemoteException e) {
872 throw new RuntimeException("Failed calling service", e);
873 }
874 return 0;
875 }
876
877 private int runQueryIntentReceivers() {
878 Intent intent;
879 try {
880 intent = parseIntentAndUser();
881 } catch (URISyntaxException e) {
882 throw new RuntimeException(e.getMessage(), e);
883 }
884 try {
Ng Zhi An73971312018-09-11 21:39:14 -0700885 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(),
886 mQueryFlags, mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800887 PrintWriter pw = getOutPrintWriter();
888 if (result == null || result.size() <= 0) {
889 pw.println("No receivers found");
890 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700891 if (!mComponents) {
892 pw.print(result.size()); pw.println(" receivers found:");
893 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
894 for (int i = 0; i < result.size(); i++) {
895 pw.print(" Receiver #"); pw.print(i); pw.println(":");
896 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
897 }
898 } else {
899 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
900 for (int i = 0; i < result.size(); i++) {
901 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
902 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800903 }
904 }
905 } catch (RemoteException e) {
906 throw new RuntimeException("Failed calling service", e);
907 }
908 return 0;
909 }
910
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700911 private int runInstall() throws RemoteException {
912 final PrintWriter pw = getOutPrintWriter();
913 final InstallParams params = makeInstallParams();
914 final String inPath = getNextArg();
915
916 setParamsSize(params, inPath);
917 final int sessionId = doCreateSession(params.sessionParams,
918 params.installerPackageName, params.userId);
919 boolean abandonSession = true;
920 try {
921 if (inPath == null && params.sessionParams.sizeBytes == -1) {
922 pw.println("Error: must either specify a package size or an APK file");
923 return 1;
924 }
Dario Frenid8bf22e2018-08-31 14:18:04 +0100925 final boolean isApex =
926 (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
927 String splitName = "base." + (isApex ? "apex" : "apk");
928 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700929 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
930 return 1;
931 }
932 if (doCommitSession(sessionId, false /*logSuccess*/)
933 != PackageInstaller.STATUS_SUCCESS) {
934 return 1;
935 }
936 abandonSession = false;
937 pw.println("Success");
938 return 0;
939 } finally {
940 if (abandonSession) {
941 try {
942 doAbandonSession(sessionId, false /*logSuccess*/);
943 } catch (Exception ignore) {
944 }
945 }
946 }
947 }
948
949 private int runInstallAbandon() throws RemoteException {
950 final int sessionId = Integer.parseInt(getNextArg());
951 return doAbandonSession(sessionId, true /*logSuccess*/);
952 }
953
954 private int runInstallCommit() throws RemoteException {
955 final int sessionId = Integer.parseInt(getNextArg());
956 return doCommitSession(sessionId, true /*logSuccess*/);
957 }
958
959 private int runInstallCreate() throws RemoteException {
960 final PrintWriter pw = getOutPrintWriter();
961 final InstallParams installParams = makeInstallParams();
962 final int sessionId = doCreateSession(installParams.sessionParams,
963 installParams.installerPackageName, installParams.userId);
964
965 // NOTE: adb depends on parsing this string
966 pw.println("Success: created install session [" + sessionId + "]");
967 return 0;
968 }
969
970 private int runInstallWrite() throws RemoteException {
971 long sizeBytes = -1;
972
973 String opt;
974 while ((opt = getNextOption()) != null) {
975 if (opt.equals("-S")) {
976 sizeBytes = Long.parseLong(getNextArg());
977 } else {
978 throw new IllegalArgumentException("Unknown option: " + opt);
979 }
980 }
981
982 final int sessionId = Integer.parseInt(getNextArg());
983 final String splitName = getNextArg();
984 final String path = getNextArg();
985 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
986 }
987
Patrick Baumann0aff9b12018-11-08 14:05:08 +0000988 private int runInstallAddSession() throws RemoteException {
989 final PrintWriter pw = getOutPrintWriter();
990 final int parentSessionId = Integer.parseInt(getNextArg());
991
992 List<Integer> otherSessionIds = new ArrayList<>();
993 String opt;
994 while ((opt = getNextArg()) != null) {
995 otherSessionIds.add(Integer.parseInt(opt));
996 }
997 if (otherSessionIds.size() == 0) {
998 pw.println("Error: At least two sessions are required.");
999 return 1;
1000 }
1001 return doInstallAddSession(parentSessionId, ArrayUtils.convertToIntArray(otherSessionIds),
1002 true /*logSuccess*/);
1003 }
1004
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001005 private int runInstallRemove() throws RemoteException {
1006 final PrintWriter pw = getOutPrintWriter();
1007
1008 final int sessionId = Integer.parseInt(getNextArg());
1009
1010 final String splitName = getNextArg();
1011 if (splitName == null) {
1012 pw.println("Error: split name not specified");
1013 return 1;
1014 }
1015 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
1016 }
1017
1018 private int runInstallExisting() throws RemoteException {
1019 final PrintWriter pw = getOutPrintWriter();
1020 int userId = UserHandle.USER_SYSTEM;
1021 int installFlags = 0;
1022 String opt;
1023 while ((opt = getNextOption()) != null) {
1024 switch (opt) {
1025 case "--user":
1026 userId = UserHandle.parseUserArg(getNextArgRequired());
1027 break;
1028 case "--ephemeral":
1029 case "--instant":
1030 installFlags |= PackageManager.INSTALL_INSTANT_APP;
1031 installFlags &= ~PackageManager.INSTALL_FULL_APP;
1032 break;
1033 case "--full":
1034 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1035 installFlags |= PackageManager.INSTALL_FULL_APP;
1036 break;
1037 default:
1038 pw.println("Error: Unknown option: " + opt);
1039 return 1;
1040 }
1041 }
1042
1043 final String packageName = getNextArg();
1044 if (packageName == null) {
1045 pw.println("Error: package name not specified");
1046 return 1;
1047 }
1048
1049 try {
1050 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
1051 installFlags, PackageManager.INSTALL_REASON_UNKNOWN);
1052 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
1053 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1054 }
1055 pw.println("Package " + packageName + " installed for user: " + userId);
1056 return 0;
1057 } catch (RemoteException | NameNotFoundException e) {
1058 pw.println(e.toString());
1059 return 1;
1060 }
1061 }
1062
1063 private int runSetInstallLocation() throws RemoteException {
1064 int loc;
1065
1066 String arg = getNextArg();
1067 if (arg == null) {
1068 getErrPrintWriter().println("Error: no install location specified.");
1069 return 1;
1070 }
1071 try {
1072 loc = Integer.parseInt(arg);
1073 } catch (NumberFormatException e) {
1074 getErrPrintWriter().println("Error: install location has to be a number.");
1075 return 1;
1076 }
1077 if (!mInterface.setInstallLocation(loc)) {
1078 getErrPrintWriter().println("Error: install location has to be a number.");
1079 return 1;
1080 }
1081 return 0;
1082 }
1083
1084 private int runGetInstallLocation() throws RemoteException {
1085 int loc = mInterface.getInstallLocation();
1086 String locStr = "invalid";
1087 if (loc == PackageHelper.APP_INSTALL_AUTO) {
1088 locStr = "auto";
1089 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
1090 locStr = "internal";
1091 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
1092 locStr = "external";
1093 }
1094 getOutPrintWriter().println(loc + "[" + locStr + "]");
1095 return 0;
1096 }
1097
1098 public int runMovePackage() throws RemoteException {
1099 final String packageName = getNextArg();
1100 if (packageName == null) {
1101 getErrPrintWriter().println("Error: package name not specified");
1102 return 1;
1103 }
1104 String volumeUuid = getNextArg();
1105 if ("internal".equals(volumeUuid)) {
1106 volumeUuid = null;
1107 }
1108
1109 final int moveId = mInterface.movePackage(packageName, volumeUuid);
1110
1111 int status = mInterface.getMoveStatus(moveId);
1112 while (!PackageManager.isMoveStatusFinished(status)) {
1113 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1114 status = mInterface.getMoveStatus(moveId);
1115 }
1116
1117 if (status == PackageManager.MOVE_SUCCEEDED) {
1118 getOutPrintWriter().println("Success");
1119 return 0;
1120 } else {
1121 getErrPrintWriter().println("Failure [" + status + "]");
1122 return 1;
1123 }
1124 }
1125
1126 public int runMovePrimaryStorage() throws RemoteException {
1127 String volumeUuid = getNextArg();
1128 if ("internal".equals(volumeUuid)) {
1129 volumeUuid = null;
1130 }
1131
1132 final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1133
1134 int status = mInterface.getMoveStatus(moveId);
1135 while (!PackageManager.isMoveStatusFinished(status)) {
1136 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1137 status = mInterface.getMoveStatus(moveId);
1138 }
1139
1140 if (status == PackageManager.MOVE_SUCCEEDED) {
1141 getOutPrintWriter().println("Success");
1142 return 0;
1143 } else {
1144 getErrPrintWriter().println("Failure [" + status + "]");
1145 return 1;
1146 }
1147 }
1148
1149 private int runCompile() throws RemoteException {
1150 final PrintWriter pw = getOutPrintWriter();
1151 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1152 boolean forceCompilation = false;
1153 boolean allPackages = false;
1154 boolean clearProfileData = false;
1155 String compilerFilter = null;
1156 String compilationReason = null;
1157 String checkProfilesRaw = null;
1158 boolean secondaryDex = false;
1159 String split = null;
1160
1161 String opt;
1162 while ((opt = getNextOption()) != null) {
1163 switch (opt) {
1164 case "-a":
1165 allPackages = true;
1166 break;
1167 case "-c":
1168 clearProfileData = true;
1169 break;
1170 case "-f":
1171 forceCompilation = true;
1172 break;
1173 case "-m":
1174 compilerFilter = getNextArgRequired();
1175 break;
1176 case "-r":
1177 compilationReason = getNextArgRequired();
1178 break;
1179 case "--check-prof":
1180 checkProfilesRaw = getNextArgRequired();
1181 break;
1182 case "--reset":
1183 forceCompilation = true;
1184 clearProfileData = true;
1185 compilationReason = "install";
1186 break;
1187 case "--secondary-dex":
1188 secondaryDex = true;
1189 break;
1190 case "--split":
1191 split = getNextArgRequired();
1192 break;
1193 default:
1194 pw.println("Error: Unknown option: " + opt);
1195 return 1;
1196 }
1197 }
1198
1199 if (checkProfilesRaw != null) {
1200 if ("true".equals(checkProfilesRaw)) {
1201 checkProfiles = true;
1202 } else if ("false".equals(checkProfilesRaw)) {
1203 checkProfiles = false;
1204 } else {
1205 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1206 return 1;
1207 }
1208 }
1209
1210 if (compilerFilter != null && compilationReason != null) {
1211 pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
1212 "at the same time");
1213 return 1;
1214 }
1215 if (compilerFilter == null && compilationReason == null) {
1216 pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " +
1217 "reason (\"-r\") at the same time");
1218 return 1;
1219 }
1220
1221 if (allPackages && split != null) {
1222 pw.println("-a cannot be specified together with --split");
1223 return 1;
1224 }
1225
1226 if (secondaryDex && split != null) {
1227 pw.println("--secondary-dex cannot be specified together with --split");
1228 return 1;
1229 }
1230
1231 String targetCompilerFilter;
1232 if (compilerFilter != null) {
1233 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1234 pw.println("Error: \"" + compilerFilter +
1235 "\" is not a valid compilation filter.");
1236 return 1;
1237 }
1238 targetCompilerFilter = compilerFilter;
1239 } else {
1240 int reason = -1;
1241 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1242 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1243 compilationReason)) {
1244 reason = i;
1245 break;
1246 }
1247 }
1248 if (reason == -1) {
1249 pw.println("Error: Unknown compilation reason: " + compilationReason);
1250 return 1;
1251 }
1252 targetCompilerFilter =
1253 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1254 }
1255
1256
1257 List<String> packageNames = null;
1258 if (allPackages) {
1259 packageNames = mInterface.getAllPackages();
1260 } else {
1261 String packageName = getNextArg();
1262 if (packageName == null) {
1263 pw.println("Error: package name not specified");
1264 return 1;
1265 }
1266 packageNames = Collections.singletonList(packageName);
1267 }
1268
1269 List<String> failedPackages = new ArrayList<>();
Andreas Gampecbd08d42017-11-20 17:03:17 -08001270 int index = 0;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001271 for (String packageName : packageNames) {
1272 if (clearProfileData) {
1273 mInterface.clearApplicationProfileData(packageName);
1274 }
1275
Andreas Gampecbd08d42017-11-20 17:03:17 -08001276 if (allPackages) {
1277 pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1278 pw.flush();
1279 }
1280
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001281 boolean result = secondaryDex
1282 ? mInterface.performDexOptSecondary(packageName,
1283 targetCompilerFilter, forceCompilation)
1284 : mInterface.performDexOptMode(packageName,
1285 checkProfiles, targetCompilerFilter, forceCompilation,
1286 true /* bootComplete */, split);
1287 if (!result) {
1288 failedPackages.add(packageName);
1289 }
1290 }
1291
1292 if (failedPackages.isEmpty()) {
1293 pw.println("Success");
1294 return 0;
1295 } else if (failedPackages.size() == 1) {
1296 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1297 return 1;
1298 } else {
1299 pw.print("Failure: the following packages could not be compiled: ");
1300 boolean is_first = true;
1301 for (String packageName : failedPackages) {
1302 if (is_first) {
1303 is_first = false;
1304 } else {
1305 pw.print(", ");
1306 }
1307 pw.print(packageName);
1308 }
1309 pw.println();
1310 return 1;
1311 }
1312 }
1313
1314 private int runreconcileSecondaryDexFiles() throws RemoteException {
1315 String packageName = getNextArg();
1316 mInterface.reconcileSecondaryDexFiles(packageName);
1317 return 0;
1318 }
1319
1320 public int runForceDexOpt() throws RemoteException {
1321 mInterface.forceDexOpt(getNextArgRequired());
1322 return 0;
1323 }
1324
1325 private int runDexoptJob() throws RemoteException {
Arthur Eubanks09dd1ec2017-09-15 09:28:51 -07001326 String arg;
1327 List<String> packageNames = new ArrayList<>();
1328 while ((arg = getNextArg()) != null) {
1329 packageNames.add(arg);
1330 }
1331 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1332 packageNames);
Andreas Gampefa8b57d2018-08-31 15:47:01 -07001333 getOutPrintWriter().println(result ? "Success" : "Failure");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001334 return result ? 0 : -1;
1335 }
1336
1337 private int runDumpProfiles() throws RemoteException {
1338 String packageName = getNextArg();
1339 mInterface.dumpProfiles(packageName);
1340 return 0;
1341 }
1342
Calin Juravle21216c62018-05-04 17:35:29 -07001343 private int runSnapshotProfile() throws RemoteException {
1344 PrintWriter pw = getOutPrintWriter();
1345
1346 // Parse the arguments
1347 final String packageName = getNextArg();
1348 final boolean isBootImage = "android".equals(packageName);
1349
1350 String codePath = null;
1351 String opt;
1352 while ((opt = getNextArg()) != null) {
1353 switch (opt) {
1354 case "--code-path":
1355 if (isBootImage) {
1356 pw.write("--code-path cannot be used for the boot image.");
1357 return -1;
1358 }
1359 codePath = getNextArg();
1360 break;
1361 default:
1362 pw.write("Unknown arg: " + opt);
1363 return -1;
1364 }
1365 }
1366
1367 // If no code path was explicitly requested, select the base code path.
1368 String baseCodePath = null;
1369 if (!isBootImage) {
1370 PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
1371 /* userId */0);
1372 if (packageInfo == null) {
1373 pw.write("Package not found " + packageName);
1374 return -1;
1375 }
1376 baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
1377 if (codePath == null) {
1378 codePath = baseCodePath;
1379 }
1380 }
1381
1382 // Create the profile snapshot.
1383 final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
1384 // The calling package is needed to debug permission access.
1385 final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
1386 ? "root" : "com.android.shell";
1387 final int profileType = isBootImage
1388 ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
1389 if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
1390 pw.println("Error: Runtime profiling is not enabled");
1391 return -1;
1392 }
1393 mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
1394 codePath, callback, callingPackage);
1395 if (!callback.waitTillDone()) {
1396 pw.println("Error: callback not called");
1397 return callback.mErrCode;
1398 }
1399
1400 // Copy the snapshot profile to the output profile file.
1401 try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
1402 final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
1403 ? "" : ("-" + new File(codePath).getName());
1404 final String outputProfilePath =
1405 ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
1406 try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
1407 Streams.copy(inStream, outStream);
1408 }
Calin Juravlebdd94d92018-05-17 01:23:15 -07001409 // Give read permissions to the other group.
1410 Os.chmod(outputProfilePath, /*mode*/ 0644 );
1411 } catch (IOException | ErrnoException e) {
Calin Juravle21216c62018-05-04 17:35:29 -07001412 pw.println("Error when reading the profile fd: " + e.getMessage());
1413 e.printStackTrace(pw);
1414 return -1;
1415 }
1416 return 0;
1417 }
1418
1419 private static class SnapshotRuntimeProfileCallback
1420 extends ISnapshotRuntimeProfileCallback.Stub {
1421 private boolean mSuccess = false;
1422 private int mErrCode = -1;
1423 private ParcelFileDescriptor mProfileReadFd = null;
1424 private CountDownLatch mDoneSignal = new CountDownLatch(1);
1425
1426 @Override
1427 public void onSuccess(ParcelFileDescriptor profileReadFd) {
1428 mSuccess = true;
1429 try {
1430 // We need to dup the descriptor. We are in the same process as system server
1431 // and we will be receiving the same object (which will be closed on the
1432 // server side).
1433 mProfileReadFd = profileReadFd.dup();
1434 } catch (IOException e) {
1435 e.printStackTrace();
1436 }
1437 mDoneSignal.countDown();
1438 }
1439
1440 @Override
1441 public void onError(int errCode) {
1442 mSuccess = false;
1443 mErrCode = errCode;
1444 mDoneSignal.countDown();
1445 }
1446
1447 boolean waitTillDone() {
1448 boolean done = false;
1449 try {
1450 // The time-out is an arbitrary large value. Since this is a local call the result
1451 // will come very fast.
1452 done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS);
1453 } catch (InterruptedException ignored) {
1454 }
1455 return done && mSuccess;
1456 }
1457 }
1458
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001459 private int runUninstall() throws RemoteException {
1460 final PrintWriter pw = getOutPrintWriter();
1461 int flags = 0;
1462 int userId = UserHandle.USER_ALL;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001463 long versionCode = PackageManager.VERSION_CODE_HIGHEST;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001464
1465 String opt;
1466 while ((opt = getNextOption()) != null) {
1467 switch (opt) {
1468 case "-k":
1469 flags |= PackageManager.DELETE_KEEP_DATA;
1470 break;
1471 case "--user":
1472 userId = UserHandle.parseUserArg(getNextArgRequired());
1473 break;
1474 case "--versionCode":
Dianne Hackborn3accca02013-09-20 09:32:11 -07001475 versionCode = Long.parseLong(getNextArgRequired());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001476 break;
1477 default:
1478 pw.println("Error: Unknown option: " + opt);
1479 return 1;
1480 }
1481 }
1482
1483 final String packageName = getNextArg();
1484 if (packageName == null) {
1485 pw.println("Error: package name not specified");
1486 return 1;
1487 }
1488
1489 // if a split is specified, just remove it and not the whole package
1490 final String splitName = getNextArg();
1491 if (splitName != null) {
1492 return runRemoveSplit(packageName, splitName);
1493 }
1494
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08001495 userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001496 if (userId == UserHandle.USER_ALL) {
1497 userId = UserHandle.USER_SYSTEM;
1498 flags |= PackageManager.DELETE_ALL_USERS;
1499 } else {
1500 final PackageInfo info = mInterface.getPackageInfo(packageName,
1501 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1502 if (info == null) {
1503 pw.println("Failure [not installed for " + userId + "]");
1504 return 1;
1505 }
1506 final boolean isSystem =
1507 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1508 // If we are being asked to delete a system app for just one
1509 // user set flag so it disables rather than reverting to system
1510 // version of the app.
1511 if (isSystem) {
1512 flags |= PackageManager.DELETE_SYSTEM_APP;
1513 }
1514 }
1515
1516 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1517 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1518 versionCode), null /*callerPackageName*/, flags,
1519 receiver.getIntentSender(), userId);
1520
1521 final Intent result = receiver.getResult();
1522 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1523 PackageInstaller.STATUS_FAILURE);
1524 if (status == PackageInstaller.STATUS_SUCCESS) {
1525 pw.println("Success");
1526 return 0;
1527 } else {
1528 pw.println("Failure ["
1529 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1530 return 1;
1531 }
1532 }
1533
1534 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1535 final PrintWriter pw = getOutPrintWriter();
1536 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1537 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1538 sessionParams.appPackageName = packageName;
1539 final int sessionId =
1540 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1541 boolean abandonSession = true;
1542 try {
1543 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1544 != PackageInstaller.STATUS_SUCCESS) {
1545 return 1;
1546 }
1547 if (doCommitSession(sessionId, false /*logSuccess*/)
1548 != PackageInstaller.STATUS_SUCCESS) {
1549 return 1;
1550 }
1551 abandonSession = false;
1552 pw.println("Success");
1553 return 0;
1554 } finally {
1555 if (abandonSession) {
1556 try {
1557 doAbandonSession(sessionId, false /*logSuccess*/);
1558 } catch (Exception ignore) {
1559 }
1560 }
1561 }
1562 }
1563
1564 static class ClearDataObserver extends IPackageDataObserver.Stub {
1565 boolean finished;
1566 boolean result;
1567
1568 @Override
1569 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1570 synchronized (this) {
1571 finished = true;
1572 result = succeeded;
1573 notifyAll();
1574 }
1575 }
1576 }
1577
1578 private int runClear() throws RemoteException {
1579 int userId = UserHandle.USER_SYSTEM;
1580 String option = getNextOption();
1581 if (option != null && option.equals("--user")) {
1582 userId = UserHandle.parseUserArg(getNextArgRequired());
1583 }
1584
1585 String pkg = getNextArg();
1586 if (pkg == null) {
1587 getErrPrintWriter().println("Error: no package specified");
1588 return 1;
1589 }
1590
1591 ClearDataObserver obs = new ClearDataObserver();
Christopher Tate1d99c392017-12-07 16:54:04 -08001592 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001593 synchronized (obs) {
1594 while (!obs.finished) {
1595 try {
1596 obs.wait();
1597 } catch (InterruptedException e) {
1598 }
1599 }
1600 }
1601
1602 if (obs.result) {
1603 getOutPrintWriter().println("Success");
1604 return 0;
1605 } else {
1606 getErrPrintWriter().println("Failed");
1607 return 1;
1608 }
1609 }
1610
1611 private static String enabledSettingToString(int state) {
1612 switch (state) {
1613 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1614 return "default";
1615 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1616 return "enabled";
1617 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1618 return "disabled";
1619 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1620 return "disabled-user";
1621 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1622 return "disabled-until-used";
1623 }
1624 return "unknown";
1625 }
1626
1627 private int runSetEnabledSetting(int state) throws RemoteException {
1628 int userId = UserHandle.USER_SYSTEM;
1629 String option = getNextOption();
1630 if (option != null && option.equals("--user")) {
1631 userId = UserHandle.parseUserArg(getNextArgRequired());
1632 }
1633
1634 String pkg = getNextArg();
1635 if (pkg == null) {
1636 getErrPrintWriter().println("Error: no package or component specified");
1637 return 1;
1638 }
1639 ComponentName cn = ComponentName.unflattenFromString(pkg);
1640 if (cn == null) {
1641 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1642 "shell:" + android.os.Process.myUid());
1643 getOutPrintWriter().println("Package " + pkg + " new state: "
1644 + enabledSettingToString(
1645 mInterface.getApplicationEnabledSetting(pkg, userId)));
1646 return 0;
1647 } else {
1648 mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1649 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1650 + enabledSettingToString(
1651 mInterface.getComponentEnabledSetting(cn, userId)));
1652 return 0;
1653 }
1654 }
1655
1656 private int runSetHiddenSetting(boolean state) throws RemoteException {
1657 int userId = UserHandle.USER_SYSTEM;
1658 String option = getNextOption();
1659 if (option != null && option.equals("--user")) {
1660 userId = UserHandle.parseUserArg(getNextArgRequired());
1661 }
1662
1663 String pkg = getNextArg();
1664 if (pkg == null) {
1665 getErrPrintWriter().println("Error: no package or component specified");
1666 return 1;
1667 }
1668 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1669 getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1670 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1671 return 0;
1672 }
1673
1674 private int runSuspend(boolean suspendedState) {
1675 final PrintWriter pw = getOutPrintWriter();
1676 int userId = UserHandle.USER_SYSTEM;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001677 String dialogMessage = null;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001678 final PersistableBundle appExtras = new PersistableBundle();
1679 final PersistableBundle launcherExtras = new PersistableBundle();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001680 String opt;
1681 while ((opt = getNextOption()) != null) {
1682 switch (opt) {
1683 case "--user":
1684 userId = UserHandle.parseUserArg(getNextArgRequired());
1685 break;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001686 case "--dialogMessage":
1687 dialogMessage = getNextArgRequired();
1688 break;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001689 case "--ael":
1690 case "--aes":
1691 case "--aed":
1692 case "--lel":
1693 case "--les":
1694 case "--led":
1695 final String key = getNextArgRequired();
1696 final String val = getNextArgRequired();
1697 if (!suspendedState) {
1698 break;
1699 }
1700 final PersistableBundle bundleToInsert =
1701 opt.startsWith("--a") ? appExtras : launcherExtras;
1702 switch (opt.charAt(4)) {
1703 case 'l':
1704 bundleToInsert.putLong(key, Long.valueOf(val));
1705 break;
1706 case 'd':
1707 bundleToInsert.putDouble(key, Double.valueOf(val));
1708 break;
1709 case 's':
1710 bundleToInsert.putString(key, val);
1711 break;
1712 }
1713 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001714 default:
1715 pw.println("Error: Unknown option: " + opt);
1716 return 1;
1717 }
1718 }
1719
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001720 final String packageName = getNextArg();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001721 if (packageName == null) {
1722 pw.println("Error: package name not specified");
1723 return 1;
1724 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001725 final String callingPackage =
1726 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07001727
1728 final SuspendDialogInfo info;
1729 if (!TextUtils.isEmpty(dialogMessage)) {
1730 info = new SuspendDialogInfo.Builder()
1731 .setMessage(dialogMessage)
1732 .build();
1733 } else {
1734 info = null;
1735 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001736 try {
1737 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
Suprabh Shukla389cb6f2018-10-01 18:20:39 -07001738 appExtras, launcherExtras, info, callingPackage, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001739 pw.println("Package " + packageName + " new suspended state: "
1740 + mInterface.isPackageSuspendedForUser(packageName, userId));
1741 return 0;
1742 } catch (RemoteException | IllegalArgumentException e) {
1743 pw.println(e.toString());
1744 return 1;
1745 }
1746 }
1747
1748 private int runGrantRevokePermission(boolean grant) throws RemoteException {
1749 int userId = UserHandle.USER_SYSTEM;
1750
1751 String opt = null;
1752 while ((opt = getNextOption()) != null) {
1753 if (opt.equals("--user")) {
1754 userId = UserHandle.parseUserArg(getNextArgRequired());
1755 }
1756 }
1757
1758 String pkg = getNextArg();
1759 if (pkg == null) {
1760 getErrPrintWriter().println("Error: no package specified");
1761 return 1;
1762 }
1763 String perm = getNextArg();
1764 if (perm == null) {
1765 getErrPrintWriter().println("Error: no permission specified");
1766 return 1;
1767 }
1768
1769 if (grant) {
1770 mInterface.grantRuntimePermission(pkg, perm, userId);
1771 } else {
1772 mInterface.revokeRuntimePermission(pkg, perm, userId);
1773 }
1774 return 0;
1775 }
1776
1777 private int runResetPermissions() throws RemoteException {
1778 mInterface.resetRuntimePermissions();
1779 return 0;
1780 }
1781
1782 private int runSetPermissionEnforced() throws RemoteException {
1783 final String permission = getNextArg();
1784 if (permission == null) {
1785 getErrPrintWriter().println("Error: no permission specified");
1786 return 1;
1787 }
1788 final String enforcedRaw = getNextArg();
1789 if (enforcedRaw == null) {
1790 getErrPrintWriter().println("Error: no enforcement specified");
1791 return 1;
1792 }
1793 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
1794 return 0;
1795 }
1796
Jiyong Park002fdbd2017-02-13 20:50:31 +09001797 private boolean isVendorApp(String pkg) {
1798 try {
1799 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1800 return info != null && info.applicationInfo.isVendor();
1801 } catch (RemoteException e) {
1802 return false;
1803 }
1804 }
1805
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001806 private boolean isProductApp(String pkg) {
1807 try {
1808 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1809 return info != null && info.applicationInfo.isProduct();
1810 } catch (RemoteException e) {
1811 return false;
1812 }
1813 }
1814
Dario Freni2bef1762018-06-01 14:02:08 +01001815 private boolean isProductServicesApp(String pkg) {
1816 try {
1817 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1818 return info != null && info.applicationInfo.isProductServices();
1819 } catch (RemoteException e) {
1820 return false;
1821 }
1822 }
1823
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001824 private int runGetPrivappPermissions() {
1825 final String pkg = getNextArg();
1826 if (pkg == null) {
1827 getErrPrintWriter().println("Error: no package specified.");
1828 return 1;
1829 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001830
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001831 ArraySet<String> privAppPermissions = null;
1832 if (isVendorApp(pkg)) {
1833 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
1834 } else if (isProductApp(pkg)) {
1835 privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
Dario Freni2bef1762018-06-01 14:02:08 +01001836 } else if (isProductServicesApp(pkg)) {
1837 privAppPermissions = SystemConfig.getInstance()
1838 .getProductServicesPrivAppPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001839 } else {
1840 privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
1841 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001842
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001843 getOutPrintWriter().println(privAppPermissions == null
1844 ? "{}" : privAppPermissions.toString());
1845 return 0;
1846 }
1847
1848 private int runGetPrivappDenyPermissions() {
1849 final String pkg = getNextArg();
1850 if (pkg == null) {
1851 getErrPrintWriter().println("Error: no package specified.");
1852 return 1;
1853 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001854
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001855 ArraySet<String> privAppPermissions = null;
1856 if (isVendorApp(pkg)) {
1857 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
1858 } else if (isProductApp(pkg)) {
1859 privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
Dario Freni2bef1762018-06-01 14:02:08 +01001860 } else if (isProductServicesApp(pkg)) {
1861 privAppPermissions = SystemConfig.getInstance()
1862 .getProductServicesPrivAppDenyPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001863 } else {
1864 privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
1865 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001866
1867 getOutPrintWriter().println(privAppPermissions == null
1868 ? "{}" : privAppPermissions.toString());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001869 return 0;
1870 }
1871
1872 private int runGetOemPermissions() {
1873 final String pkg = getNextArg();
1874 if (pkg == null) {
1875 getErrPrintWriter().println("Error: no package specified.");
1876 return 1;
1877 }
1878 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
1879 .getOemPermissions(pkg);
1880 if (oemPermissions == null || oemPermissions.isEmpty()) {
1881 getOutPrintWriter().println("{}");
1882 } else {
1883 oemPermissions.forEach((permission, granted) ->
1884 getOutPrintWriter().println(permission + " granted:" + granted)
1885 );
1886 }
1887 return 0;
1888 }
1889
1890 private String linkStateToString(int state) {
1891 switch (state) {
1892 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
1893 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
1894 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
1895 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
1896 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
1897 }
1898 return "Unknown link state: " + state;
1899 }
1900
1901 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
1902 private int runSetAppLink() throws RemoteException {
1903 int userId = UserHandle.USER_SYSTEM;
1904
1905 String opt;
1906 while ((opt = getNextOption()) != null) {
1907 if (opt.equals("--user")) {
1908 userId = UserHandle.parseUserArg(getNextArgRequired());
1909 } else {
1910 getErrPrintWriter().println("Error: unknown option: " + opt);
1911 return 1;
1912 }
1913 }
1914
1915 // Package name to act on; required
1916 final String pkg = getNextArg();
1917 if (pkg == null) {
1918 getErrPrintWriter().println("Error: no package specified.");
1919 return 1;
1920 }
1921
1922 // State to apply; {always|ask|never|undefined}, required
1923 final String modeString = getNextArg();
1924 if (modeString == null) {
1925 getErrPrintWriter().println("Error: no app link state specified.");
1926 return 1;
1927 }
1928
1929 final int newMode;
1930 switch (modeString.toLowerCase()) {
1931 case "undefined":
1932 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1933 break;
1934
1935 case "always":
1936 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1937 break;
1938
1939 case "ask":
1940 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1941 break;
1942
1943 case "always-ask":
1944 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
1945 break;
1946
1947 case "never":
1948 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
1949 break;
1950
1951 default:
1952 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
1953 return 1;
1954 }
1955
1956 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1957 if (info == null) {
1958 getErrPrintWriter().println("Error: package " + pkg + " not found.");
1959 return 1;
1960 }
1961
1962 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1963 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1964 return 1;
1965 }
1966
1967 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
1968 getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
1969 return 1;
1970 }
1971
1972 return 0;
1973 }
1974
1975 // pm get-app-link [--user USER_ID] PACKAGE
1976 private int runGetAppLink() throws RemoteException {
1977 int userId = UserHandle.USER_SYSTEM;
1978
1979 String opt;
1980 while ((opt = getNextOption()) != null) {
1981 if (opt.equals("--user")) {
1982 userId = UserHandle.parseUserArg(getNextArgRequired());
1983 } else {
1984 getErrPrintWriter().println("Error: unknown option: " + opt);
1985 return 1;
1986 }
1987 }
1988
1989 // Package name to act on; required
1990 final String pkg = getNextArg();
1991 if (pkg == null) {
1992 getErrPrintWriter().println("Error: no package specified.");
1993 return 1;
1994 }
1995
1996 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1997 if (info == null) {
1998 getErrPrintWriter().println("Error: package " + pkg + " not found.");
1999 return 1;
2000 }
2001
2002 if ((info.applicationInfo.privateFlags
2003 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
2004 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
2005 return 1;
2006 }
2007
2008 getOutPrintWriter().println(linkStateToString(
2009 mInterface.getIntentVerificationStatus(pkg, userId)));
2010
2011 return 0;
2012 }
2013
2014 private int runTrimCaches() throws RemoteException {
2015 String size = getNextArg();
2016 if (size == null) {
2017 getErrPrintWriter().println("Error: no size specified");
2018 return 1;
2019 }
2020 long multiplier = 1;
2021 int len = size.length();
2022 char c = size.charAt(len - 1);
2023 if (c < '0' || c > '9') {
2024 if (c == 'K' || c == 'k') {
2025 multiplier = 1024L;
2026 } else if (c == 'M' || c == 'm') {
2027 multiplier = 1024L*1024L;
2028 } else if (c == 'G' || c == 'g') {
2029 multiplier = 1024L*1024L*1024L;
2030 } else {
2031 getErrPrintWriter().println("Invalid suffix: " + c);
2032 return 1;
2033 }
2034 size = size.substring(0, len-1);
2035 }
2036 long sizeVal;
2037 try {
2038 sizeVal = Long.parseLong(size) * multiplier;
2039 } catch (NumberFormatException e) {
2040 getErrPrintWriter().println("Error: expected number at: " + size);
2041 return 1;
2042 }
2043 String volumeUuid = getNextArg();
2044 if ("internal".equals(volumeUuid)) {
2045 volumeUuid = null;
2046 }
2047 ClearDataObserver obs = new ClearDataObserver();
2048 mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
2049 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
2050 synchronized (obs) {
2051 while (!obs.finished) {
2052 try {
2053 obs.wait();
2054 } catch (InterruptedException e) {
2055 }
2056 }
2057 }
2058 return 0;
2059 }
2060
2061 private static boolean isNumber(String s) {
2062 try {
2063 Integer.parseInt(s);
2064 } catch (NumberFormatException nfe) {
2065 return false;
2066 }
2067 return true;
2068 }
2069
2070 public int runCreateUser() throws RemoteException {
2071 String name;
2072 int userId = -1;
2073 int flags = 0;
2074 String opt;
2075 while ((opt = getNextOption()) != null) {
2076 if ("--profileOf".equals(opt)) {
2077 userId = UserHandle.parseUserArg(getNextArgRequired());
2078 } else if ("--managed".equals(opt)) {
2079 flags |= UserInfo.FLAG_MANAGED_PROFILE;
2080 } else if ("--restricted".equals(opt)) {
2081 flags |= UserInfo.FLAG_RESTRICTED;
2082 } else if ("--ephemeral".equals(opt)) {
2083 flags |= UserInfo.FLAG_EPHEMERAL;
2084 } else if ("--guest".equals(opt)) {
2085 flags |= UserInfo.FLAG_GUEST;
2086 } else if ("--demo".equals(opt)) {
2087 flags |= UserInfo.FLAG_DEMO;
2088 } else {
2089 getErrPrintWriter().println("Error: unknown option " + opt);
2090 return 1;
2091 }
2092 }
2093 String arg = getNextArg();
2094 if (arg == null) {
2095 getErrPrintWriter().println("Error: no user name specified.");
2096 return 1;
2097 }
2098 name = arg;
2099 UserInfo info;
2100 IUserManager um = IUserManager.Stub.asInterface(
2101 ServiceManager.getService(Context.USER_SERVICE));
2102 IAccountManager accm = IAccountManager.Stub.asInterface(
2103 ServiceManager.getService(Context.ACCOUNT_SERVICE));
2104 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
2105 // In non-split user mode, userId can only be SYSTEM
2106 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
2107 info = um.createRestrictedProfile(name, parentUserId);
2108 accm.addSharedAccountsFromParentUser(parentUserId, userId,
2109 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
2110 } else if (userId < 0) {
2111 info = um.createUser(name, flags);
2112 } else {
2113 info = um.createProfileForUser(name, flags, userId, null);
2114 }
2115
2116 if (info != null) {
2117 getOutPrintWriter().println("Success: created user id " + info.id);
2118 return 0;
2119 } else {
2120 getErrPrintWriter().println("Error: couldn't create User.");
2121 return 1;
2122 }
2123 }
2124
2125 public int runRemoveUser() throws RemoteException {
2126 int userId;
2127 String arg = getNextArg();
2128 if (arg == null) {
2129 getErrPrintWriter().println("Error: no user id specified.");
2130 return 1;
2131 }
2132 userId = UserHandle.parseUserArg(arg);
2133 IUserManager um = IUserManager.Stub.asInterface(
2134 ServiceManager.getService(Context.USER_SERVICE));
2135 if (um.removeUser(userId)) {
2136 getOutPrintWriter().println("Success: removed user");
2137 return 0;
2138 } else {
2139 getErrPrintWriter().println("Error: couldn't remove user id " + userId);
2140 return 1;
2141 }
2142 }
2143
2144 public int runSetUserRestriction() throws RemoteException {
2145 int userId = UserHandle.USER_SYSTEM;
2146 String opt = getNextOption();
2147 if (opt != null && "--user".equals(opt)) {
2148 userId = UserHandle.parseUserArg(getNextArgRequired());
2149 }
2150
2151 String restriction = getNextArg();
2152 String arg = getNextArg();
2153 boolean value;
2154 if ("1".equals(arg)) {
2155 value = true;
2156 } else if ("0".equals(arg)) {
2157 value = false;
2158 } else {
2159 getErrPrintWriter().println("Error: valid value not specified");
2160 return 1;
2161 }
2162 IUserManager um = IUserManager.Stub.asInterface(
2163 ServiceManager.getService(Context.USER_SERVICE));
2164 um.setUserRestriction(restriction, value, userId);
2165 return 0;
2166 }
2167
2168 public int runGetMaxUsers() {
2169 getOutPrintWriter().println("Maximum supported users: "
2170 + UserManager.getMaxSupportedUsers());
2171 return 0;
2172 }
2173
Alex Chauc12189b2018-01-16 15:01:15 +00002174 public int runGetMaxRunningUsers() {
2175 ActivityManagerInternal activityManagerInternal =
2176 LocalServices.getService(ActivityManagerInternal.class);
2177 getOutPrintWriter().println("Maximum supported running users: "
2178 + activityManagerInternal.getMaxRunningUsers());
2179 return 0;
2180 }
2181
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002182 private static class InstallParams {
2183 SessionParams sessionParams;
2184 String installerPackageName;
2185 int userId = UserHandle.USER_ALL;
2186 }
2187
2188 private InstallParams makeInstallParams() {
2189 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
2190 final InstallParams params = new InstallParams();
2191 params.sessionParams = sessionParams;
2192 String opt;
Patrick Baumanna9333492017-11-28 15:23:49 -08002193 boolean replaceExisting = true;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002194 while ((opt = getNextOption()) != null) {
2195 switch (opt) {
2196 case "-l":
2197 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
2198 break;
Patrick Baumanna9333492017-11-28 15:23:49 -08002199 case "-r": // ignore
2200 break;
2201 case "-R":
2202 replaceExisting = false;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002203 break;
2204 case "-i":
2205 params.installerPackageName = getNextArg();
2206 if (params.installerPackageName == null) {
2207 throw new IllegalArgumentException("Missing installer package");
2208 }
2209 break;
2210 case "-t":
2211 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
2212 break;
2213 case "-s":
2214 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL;
2215 break;
2216 case "-f":
2217 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
2218 break;
2219 case "-d":
2220 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
2221 break;
2222 case "-g":
2223 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
2224 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002225 case "--dont-kill":
2226 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
2227 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002228 case "--originating-uri":
2229 sessionParams.originatingUri = Uri.parse(getNextArg());
2230 break;
2231 case "--referrer":
2232 sessionParams.referrerUri = Uri.parse(getNextArg());
2233 break;
2234 case "-p":
2235 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
2236 sessionParams.appPackageName = getNextArg();
2237 if (sessionParams.appPackageName == null) {
2238 throw new IllegalArgumentException("Missing inherit package name");
2239 }
2240 break;
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002241 case "--pkg":
2242 sessionParams.appPackageName = getNextArg();
2243 if (sessionParams.appPackageName == null) {
2244 throw new IllegalArgumentException("Missing package name");
2245 }
2246 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002247 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002248 final long sizeBytes = Long.parseLong(getNextArg());
2249 if (sizeBytes <= 0) {
2250 throw new IllegalArgumentException("Size must be positive");
2251 }
2252 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002253 break;
2254 case "--abi":
2255 sessionParams.abiOverride = checkAbiArgument(getNextArg());
2256 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08002257 case "--ephemeral":
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002258 case "--instant":
Todd Kennedybe0b8892017-02-15 14:13:52 -08002259 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08002260 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08002261 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08002262 case "--full":
2263 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
2264 break;
Todd Kennedy78a72502017-07-19 12:49:30 -07002265 case "--preload":
2266 sessionParams.setInstallAsVirtualPreload();
2267 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002268 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002269 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002270 break;
2271 case "--install-location":
2272 sessionParams.installLocation = Integer.parseInt(getNextArg());
2273 break;
Sunny Goyalabd4d442018-09-19 15:49:50 -07002274 case "--install-reason":
2275 sessionParams.installReason = Integer.parseInt(getNextArg());
2276 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002277 case "--force-uuid":
2278 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
2279 sessionParams.volumeUuid = getNextArg();
2280 if ("internal".equals(sessionParams.volumeUuid)) {
2281 sessionParams.volumeUuid = null;
2282 }
2283 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002284 case "--force-sdk":
2285 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK;
2286 break;
Dario Frenid8bf22e2018-08-31 14:18:04 +01002287 case "--apex":
2288 sessionParams.installFlags |= PackageManager.INSTALL_APEX;
2289 break;
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002290 case "--multi-package":
2291 sessionParams.setMultiPackage();
2292 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002293 default:
2294 throw new IllegalArgumentException("Unknown option " + opt);
2295 }
Patrick Baumanna9333492017-11-28 15:23:49 -08002296 if (replaceExisting) {
2297 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
2298 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002299 }
2300 return params;
2301 }
2302
Makoto Onuki4828a592016-03-15 18:06:57 -07002303 private int runSetHomeActivity() {
2304 final PrintWriter pw = getOutPrintWriter();
2305 int userId = UserHandle.USER_SYSTEM;
2306 String opt;
2307 while ((opt = getNextOption()) != null) {
2308 switch (opt) {
2309 case "--user":
2310 userId = UserHandle.parseUserArg(getNextArgRequired());
2311 break;
2312 default:
2313 pw.println("Error: Unknown option: " + opt);
2314 return 1;
2315 }
2316 }
2317
2318 String component = getNextArg();
2319 ComponentName componentName =
2320 component != null ? ComponentName.unflattenFromString(component) : null;
2321
2322 if (componentName == null) {
2323 pw.println("Error: component name not specified or invalid");
2324 return 1;
2325 }
2326
2327 try {
2328 mInterface.setHomeActivity(componentName, userId);
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002329 pw.println("Success");
Makoto Onuki4828a592016-03-15 18:06:57 -07002330 return 0;
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002331 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07002332 pw.println(e.toString());
2333 return 1;
2334 }
2335 }
2336
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002337 private int runSetInstaller() throws RemoteException {
2338 final String targetPackage = getNextArg();
2339 final String installerPackageName = getNextArg();
Fyodor Kupolov51245c72016-12-01 11:34:10 -08002340
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002341 if (targetPackage == null || installerPackageName == null) {
2342 getErrPrintWriter().println("Must provide both target and installer package names");
Todd Kennedy74629e32017-08-15 14:48:07 -07002343 return 1;
2344 }
Todd Kennedy74629e32017-08-15 14:48:07 -07002345
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002346 mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2347 getOutPrintWriter().println("Success");
Svet Ganov087dce22017-09-07 15:42:16 -07002348 return 0;
2349 }
2350
Todd Kennedy0a3f0812017-05-08 14:43:15 -07002351 private int runGetInstantAppResolver() {
2352 final PrintWriter pw = getOutPrintWriter();
2353 try {
2354 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2355 if (instantAppsResolver == null) {
2356 return 1;
2357 }
2358 pw.println(instantAppsResolver.flattenToString());
2359 return 0;
2360 } catch (Exception e) {
2361 pw.println(e.toString());
2362 return 1;
2363 }
2364 }
2365
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09002366 private int runHasFeature() {
2367 final PrintWriter err = getErrPrintWriter();
2368 final String featureName = getNextArg();
2369 if (featureName == null) {
2370 err.println("Error: expected FEATURE name");
2371 return 1;
2372 }
2373 final String versionString = getNextArg();
2374 try {
2375 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2376 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2377 getOutPrintWriter().println(hasFeature);
2378 return hasFeature ? 0 : 1;
2379 } catch (NumberFormatException e) {
2380 err.println("Error: illegal version number " + versionString);
2381 return 1;
2382 } catch (RemoteException e) {
2383 err.println(e.toString());
2384 return 1;
2385 }
2386 }
2387
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002388 private int runDump() {
2389 String pkg = getNextArg();
2390 if (pkg == null) {
2391 getErrPrintWriter().println("Error: no package specified");
2392 return 1;
2393 }
2394 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2395 return 0;
2396 }
2397
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002398 private int runSetHarmfulAppWarning() throws RemoteException {
2399 int userId = UserHandle.USER_CURRENT;
2400
2401 String opt;
2402 while ((opt = getNextOption()) != null) {
2403 if (opt.equals("--user")) {
2404 userId = UserHandle.parseUserArg(getNextArgRequired());
2405 } else {
2406 getErrPrintWriter().println("Error: Unknown option: " + opt);
2407 return -1;
2408 }
2409 }
2410
2411 userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning");
2412
2413 final String packageName = getNextArgRequired();
2414 final String warning = getNextArg();
2415
2416 mInterface.setHarmfulAppWarning(packageName, warning, userId);
2417
2418 return 0;
2419 }
2420
Ben Gruver9ef60092018-01-10 11:32:30 -08002421 private int runGetHarmfulAppWarning() throws RemoteException {
2422 int userId = UserHandle.USER_CURRENT;
2423
2424 String opt;
2425 while ((opt = getNextOption()) != null) {
2426 if (opt.equals("--user")) {
2427 userId = UserHandle.parseUserArg(getNextArgRequired());
2428 } else {
2429 getErrPrintWriter().println("Error: Unknown option: " + opt);
2430 return -1;
2431 }
2432 }
2433
2434 userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning");
2435
2436 final String packageName = getNextArgRequired();
2437 final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId);
2438 if (!TextUtils.isEmpty(warning)) {
2439 getOutPrintWriter().println(warning);
2440 return 0;
2441 } else {
2442 return 1;
2443 }
2444 }
2445
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002446 private static String checkAbiArgument(String abi) {
2447 if (TextUtils.isEmpty(abi)) {
2448 throw new IllegalArgumentException("Missing ABI argument");
2449 }
2450
2451 if ("-".equals(abi)) {
2452 return abi;
2453 }
2454
2455 final String[] supportedAbis = Build.SUPPORTED_ABIS;
2456 for (String supportedAbi : supportedAbis) {
2457 if (supportedAbi.equals(abi)) {
2458 return abi;
2459 }
2460 }
2461
2462 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2463 }
2464
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002465 private int translateUserId(int userId, boolean allowAll, String logContext) {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002466 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002467 userId, allowAll, true, logContext, "pm command");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002468 }
2469
2470 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2471 throws RemoteException {
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002472 userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002473 if (userId == UserHandle.USER_ALL) {
2474 userId = UserHandle.USER_SYSTEM;
2475 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2476 }
2477
2478 final int sessionId = mInterface.getPackageInstaller()
2479 .createSession(params, installerPackageName, userId);
2480 return sessionId;
2481 }
2482
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002483 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002484 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002485 PackageInstaller.Session session = null;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002486 try {
Jeff Sharkeya651b782018-07-23 13:45:28 -06002487 final PrintWriter pw = getOutPrintWriter();
2488 final ParcelFileDescriptor fd;
2489 if (STDIN_PATH.equals(inPath)) {
2490 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2491 } else if (inPath != null) {
2492 fd = openFileForSystem(inPath, "r");
2493 if (fd == null) {
2494 return -1;
2495 }
2496 sizeBytes = fd.getStatSize();
2497 if (sizeBytes < 0) {
2498 getErrPrintWriter().println("Unable to get size of: " + inPath);
2499 return -1;
2500 }
2501 } else {
2502 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2503 }
2504 if (sizeBytes <= 0) {
2505 getErrPrintWriter().println("Error: must specify a APK size");
2506 return 1;
2507 }
2508
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002509 session = new PackageInstaller.Session(
2510 mInterface.getPackageInstaller().openSession(sessionId));
Jeff Sharkey0451de62018-02-02 11:27:21 -07002511 session.write(splitName, 0, sizeBytes, fd);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002512
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002513 if (logSuccess) {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002514 pw.println("Success: streamed " + sizeBytes + " bytes");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002515 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002516 return 0;
2517 } catch (IOException e) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002518 getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002519 return 1;
2520 } finally {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002521 IoUtils.closeQuietly(session);
2522 }
2523 }
2524
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002525 private int doInstallAddSession(int parentId, int[] sessionIds, boolean logSuccess)
2526 throws RemoteException {
2527 final PrintWriter pw = getOutPrintWriter();
2528 PackageInstaller.Session session = null;
2529 try {
2530 session = new PackageInstaller.Session(
2531 mInterface.getPackageInstaller().openSession(parentId));
2532 if (!session.isMultiPackage()) {
2533 getErrPrintWriter().println(
2534 "Error: parent session ID is not a multi-package session");
2535 return 1;
2536 }
2537 for (int i = 0; i < sessionIds.length; i++) {
2538 session.addChildSessionId(sessionIds[i]);
2539 }
2540 if (logSuccess) {
2541 pw.println("Success");
2542 }
2543 return 0;
2544 } finally {
2545 IoUtils.closeQuietly(session);
2546 }
2547 }
2548
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002549 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2550 throws RemoteException {
2551 final PrintWriter pw = getOutPrintWriter();
2552 PackageInstaller.Session session = null;
2553 try {
2554 session = new PackageInstaller.Session(
2555 mInterface.getPackageInstaller().openSession(sessionId));
2556 session.removeSplit(splitName);
2557
2558 if (logSuccess) {
2559 pw.println("Success");
2560 }
2561 return 0;
2562 } catch (IOException e) {
2563 pw.println("Error: failed to remove split; " + e.getMessage());
2564 return 1;
2565 } finally {
2566 IoUtils.closeQuietly(session);
2567 }
2568 }
2569
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002570 private int doCommitSession(int sessionId, boolean logSuccess)
2571 throws RemoteException {
2572
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002573 final PrintWriter pw = getOutPrintWriter();
2574 PackageInstaller.Session session = null;
2575 try {
2576 session = new PackageInstaller.Session(
2577 mInterface.getPackageInstaller().openSession(sessionId));
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002578 if (!session.isMultiPackage()) {
2579 // Sanity check that all .dm files match an apk.
2580 // (The installer does not support standalone .dm files and will not process them.)
2581 try {
2582 DexMetadataHelper.validateDexPaths(session.getNames());
2583 } catch (IllegalStateException | IOException e) {
2584 pw.println(
2585 "Warning [Could not validate the dex paths: " + e.getMessage() + "]");
2586 }
Calin Juravle3fc56c32017-12-11 18:26:13 -08002587 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002588 final LocalIntentReceiver receiver = new LocalIntentReceiver();
2589 session.commit(receiver.getIntentSender());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002590 final Intent result = receiver.getResult();
2591 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2592 PackageInstaller.STATUS_FAILURE);
2593 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002594 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07002595 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002596 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002597 } else {
2598 pw.println("Failure ["
2599 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002600 }
2601 return status;
2602 } finally {
2603 IoUtils.closeQuietly(session);
2604 }
2605 }
2606
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002607 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002608 final PrintWriter pw = getOutPrintWriter();
2609 PackageInstaller.Session session = null;
2610 try {
2611 session = new PackageInstaller.Session(
2612 mInterface.getPackageInstaller().openSession(sessionId));
2613 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002614 if (logSuccess) {
2615 pw.println("Success");
2616 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002617 return 0;
2618 } finally {
2619 IoUtils.closeQuietly(session);
2620 }
2621 }
2622
Todd Kennedy60459ab2015-10-30 11:32:16 -07002623 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2624 boolean summary, int startProtectionLevel, int endProtectionLevel)
2625 throws RemoteException {
2626 final PrintWriter pw = getOutPrintWriter();
2627 final int groupCount = groupList.size();
2628 for (int i = 0; i < groupCount; i++) {
2629 String groupName = groupList.get(i);
2630 String prefix = "";
2631 if (groups) {
2632 if (i > 0) {
2633 pw.println("");
2634 }
2635 if (groupName != null) {
2636 PermissionGroupInfo pgi =
2637 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2638 if (summary) {
2639 Resources res = getResources(pgi);
2640 if (res != null) {
2641 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2642 } else {
2643 pw.print(pgi.name + ": ");
2644
2645 }
2646 } else {
2647 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2648 if (labels) {
2649 pw.println(" package:" + pgi.packageName);
2650 Resources res = getResources(pgi);
2651 if (res != null) {
2652 pw.println(" label:"
2653 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
2654 pw.println(" description:"
2655 + loadText(pgi, pgi.descriptionRes,
2656 pgi.nonLocalizedDescription));
2657 }
2658 }
2659 }
2660 } else {
2661 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
2662 }
2663 prefix = " ";
2664 }
2665 List<PermissionInfo> ps =
Jeff Sharkeyd5896632016-03-04 16:16:00 -07002666 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07002667 final int count = ps.size();
2668 boolean first = true;
2669 for (int p = 0 ; p < count ; p++) {
2670 PermissionInfo pi = ps.get(p);
2671 if (groups && groupName == null && pi.group != null) {
2672 continue;
2673 }
2674 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
2675 if (base < startProtectionLevel
2676 || base > endProtectionLevel) {
2677 continue;
2678 }
2679 if (summary) {
2680 if (first) {
2681 first = false;
2682 } else {
2683 pw.print(", ");
2684 }
2685 Resources res = getResources(pi);
2686 if (res != null) {
2687 pw.print(loadText(pi, pi.labelRes,
2688 pi.nonLocalizedLabel));
2689 } else {
2690 pw.print(pi.name);
2691 }
2692 } else {
2693 pw.println(prefix + (labels ? "+ " : "")
2694 + "permission:" + pi.name);
2695 if (labels) {
2696 pw.println(prefix + " package:" + pi.packageName);
2697 Resources res = getResources(pi);
2698 if (res != null) {
2699 pw.println(prefix + " label:"
2700 + loadText(pi, pi.labelRes,
2701 pi.nonLocalizedLabel));
2702 pw.println(prefix + " description:"
2703 + loadText(pi, pi.descriptionRes,
2704 pi.nonLocalizedDescription));
2705 }
2706 pw.println(prefix + " protectionLevel:"
2707 + PermissionInfo.protectionToString(pi.protectionLevel));
2708 }
2709 }
2710 }
2711
2712 if (summary) {
2713 pw.println("");
2714 }
2715 }
2716 }
2717
2718 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
2719 throws RemoteException {
2720 if (nonLocalized != null) {
2721 return nonLocalized.toString();
2722 }
2723 if (res != 0) {
2724 Resources r = getResources(pii);
2725 if (r != null) {
2726 try {
2727 return r.getString(res);
2728 } catch (Resources.NotFoundException e) {
2729 }
2730 }
2731 }
2732 return null;
2733 }
2734
2735 private Resources getResources(PackageItemInfo pii) throws RemoteException {
2736 Resources res = mResourceCache.get(pii.packageName);
2737 if (res != null) return res;
2738
2739 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
2740 AssetManager am = new AssetManager();
2741 am.addAssetPath(ai.publicSourceDir);
2742 res = new Resources(am, null, null);
2743 mResourceCache.put(pii.packageName, res);
2744 return res;
2745 }
2746
2747 @Override
2748 public void onHelp() {
2749 final PrintWriter pw = getOutPrintWriter();
2750 pw.println("Package manager (package) commands:");
2751 pw.println(" help");
2752 pw.println(" Print this help text.");
2753 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002754 pw.println(" path [--user USER_ID] PACKAGE");
2755 pw.println(" Print the path to the .apk of the given PACKAGE.");
2756 pw.println("");
2757 pw.println(" dump PACKAGE");
2758 pw.println(" Print various system state associated with the given PACKAGE.");
2759 pw.println("");
2760 pw.println(" list features");
2761 pw.println(" Prints all features of the system.");
2762 pw.println("");
2763 pw.println(" has-feature FEATURE_NAME [version]");
2764 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,");
2765 pw.println(" otherwise prints false and returns exit status 1");
2766 pw.println("");
2767 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
2768 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
2769 pw.println(" Options:");
2770 pw.println(" -f: dump the name of the .apk file containing the test package");
2771 pw.println("");
2772 pw.println(" list libraries");
2773 pw.println(" Prints all system libraries.");
2774 pw.println("");
2775 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
2776 pw.println(" [--uid UID] [--user USER_ID] [FILTER]");
2777 pw.println(" Prints all packages; optionally only those whose name contains");
2778 pw.println(" the text in FILTER. Options are:");
2779 pw.println(" -f: see their associated file");
Andreas Gampe1f110452018-06-04 11:47:48 -07002780 pw.println(" -a: all known packages");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002781 pw.println(" -d: filter to only show disabled packages");
2782 pw.println(" -e: filter to only show enabled packages");
2783 pw.println(" -s: filter to only show system packages");
2784 pw.println(" -3: filter to only show third party packages");
2785 pw.println(" -i: see the installer for the packages");
2786 pw.println(" -l: ignored (used for compatibility with older releases)");
2787 pw.println(" -U: also show the package UID");
2788 pw.println(" -u: also include uninstalled packages");
2789 pw.println(" --uid UID: filter to only show packages with the given UID");
2790 pw.println(" --user USER_ID: only list packages belonging to the given user");
2791 pw.println("");
2792 pw.println(" list permission-groups");
2793 pw.println(" Prints all known permission groups.");
2794 pw.println("");
2795 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
2796 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:");
2797 pw.println(" -g: organize by group");
2798 pw.println(" -f: print all information");
2799 pw.println(" -s: short summary");
2800 pw.println(" -d: only list dangerous permissions");
2801 pw.println(" -u: list only the permissions users will see");
2802 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07002803 pw.println(" resolve-activity [--brief] [--components] [--query-flags FLAGS]");
2804 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002805 pw.println(" Prints the activity that resolves to the given INTENT.");
2806 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07002807 pw.println(" query-activities [--brief] [--components] [--query-flags FLAGS]");
2808 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002809 pw.println(" Prints all activities that can handle the given INTENT.");
2810 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07002811 pw.println(" query-services [--brief] [--components] [--query-flags FLAGS]");
2812 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002813 pw.println(" Prints all services that can handle the given INTENT.");
2814 pw.println("");
Ng Zhi An73971312018-09-11 21:39:14 -07002815 pw.println(" query-receivers [--brief] [--components] [--query-flags FLAGS]");
2816 pw.println(" [--user USER_ID] INTENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002817 pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
2818 pw.println("");
2819 pw.println(" install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2820 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07002821 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
2822 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002823 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01002824 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [--apex]");
2825 pw.println(" [PATH|-]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002826 pw.println(" Install an application. Must provide the apk data to install, either as a");
2827 pw.println(" file path or '-' to read from stdin. Options are:");
2828 pw.println(" -l: forward lock application");
Patrick Baumanna9333492017-11-28 15:23:49 -08002829 pw.println(" -R: disallow replacement of existing application");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002830 pw.println(" -t: allow test packages");
2831 pw.println(" -i: specify package name of installer owning the app");
2832 pw.println(" -s: install application on sdcard");
2833 pw.println(" -f: install application on internal flash");
2834 pw.println(" -d: allow version code downgrade (debuggable packages only)");
2835 pw.println(" -p: partial application install (new split on top of existing pkg)");
2836 pw.println(" -g: grant all runtime permissions");
2837 pw.println(" -S: size in bytes of package, required for stdin");
2838 pw.println(" --user: install under the given user.");
2839 pw.println(" --dont-kill: installing a new feature split, don't kill running app");
2840 pw.println(" --originating-uri: set URI where app was downloaded from");
2841 pw.println(" --referrer: set URI that instigated the install of the app");
2842 pw.println(" --pkg: specify expected package name of app being installed");
2843 pw.println(" --abi: override the default ABI of the platform");
2844 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app");
2845 pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
2846 pw.println(" --install-location: force the install location:");
2847 pw.println(" 0=auto, 1=internal only, 2=prefer external");
Sunny Goyalabd4d442018-09-19 15:49:50 -07002848 pw.println(" --install-reason: indicates why the app is being installed:");
2849 pw.println(" 0=unknown, 1=admin policy, 2=device restore,");
2850 pw.println(" 3=device setup, 4=user request");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002851 pw.println(" --force-uuid: force install on to disk volume with given UUID");
2852 pw.println(" --force-sdk: allow install even when existing app targets platform");
2853 pw.println(" codename but new one targets a final API level");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01002854 pw.println(" --apex: install an .apex file, not an .apk");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002855 pw.println("");
2856 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2857 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
Sunny Goyalabd4d442018-09-19 15:49:50 -07002858 pw.println(" [--install-reason 0/1/2/3/4] [--originating-uri URI]");
2859 pw.println(" [--referrer URI] [--abi ABI_NAME] [--force-sdk]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002860 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
MÃ¥rten Kongstad2a5989342018-11-16 15:04:44 +01002861 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [--apex] [-S BYTES]");
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002862 pw.println(" [--multi-package]");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002863 pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
2864 pw.println(" to push data into the session, and \"install-commit\" to finish.");
2865 pw.println("");
2866 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
2867 pw.println(" Write an apk into the given install session. If the path is '-', data");
2868 pw.println(" will be read from stdin. Options are:");
2869 pw.println(" -S: size in bytes of package, required for stdin");
2870 pw.println("");
Patrick Baumann0aff9b12018-11-08 14:05:08 +00002871 pw.println(" install-add-session MULTI_PACKAGE_SESSION_ID CHILD_SESSION_IDs");
2872 pw.println(" Add one or more session IDs to a multi-package session.");
2873 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002874 pw.println(" install-commit SESSION_ID");
2875 pw.println(" Commit the given active install session, installing the app.");
2876 pw.println("");
2877 pw.println(" install-abandon SESSION_ID");
2878 pw.println(" Delete the given active install session.");
2879 pw.println("");
2880 pw.println(" set-install-location LOCATION");
2881 pw.println(" Changes the default install location. NOTE this is only intended for debugging;");
2882 pw.println(" using this can cause applications to break and other undersireable behavior.");
2883 pw.println(" LOCATION is one of:");
2884 pw.println(" 0 [auto]: Let system decide the best location");
2885 pw.println(" 1 [internal]: Install on internal device storage");
2886 pw.println(" 2 [external]: Install on external media");
2887 pw.println("");
2888 pw.println(" get-install-location");
2889 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location.");
2890 pw.println("");
2891 pw.println(" move-package PACKAGE [internal|UUID]");
2892 pw.println("");
2893 pw.println(" move-primary-storage [internal|UUID]");
2894 pw.println("");
2895 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
2896 pw.println(" Remove the given package name from the system. May remove an entire app");
2897 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
2898 pw.println(" given app. Options are:");
2899 pw.println(" -k: keep the data and cache directories around after package removal.");
2900 pw.println(" --user: remove the app from the given user.");
2901 pw.println(" --versionCode: only uninstall if the app has the given version code.");
2902 pw.println("");
2903 pw.println(" clear [--user USER_ID] PACKAGE");
2904 pw.println(" Deletes all data associated with a package.");
2905 pw.println("");
2906 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT");
2907 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT");
2908 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
2909 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
2910 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
2911 pw.println(" These commands change the enabled state of a given package or");
2912 pw.println(" component (written as \"package/class\").");
2913 pw.println("");
2914 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT");
2915 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
2916 pw.println("");
2917 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
2918 pw.println(" Suspends the specified package (as user).");
2919 pw.println("");
2920 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
2921 pw.println(" Unsuspends the specified package (as user).");
2922 pw.println("");
2923 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
2924 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
2925 pw.println(" These commands either grant or revoke permissions to apps. The permissions");
2926 pw.println(" must be declared as used in the app's manifest, be runtime permissions");
2927 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
2928 pw.println("");
2929 pw.println(" reset-permissions");
2930 pw.println(" Revert all runtime permissions to their default state.");
2931 pw.println("");
2932 pw.println(" set-permission-enforced PERMISSION [true|false]");
2933 pw.println("");
2934 pw.println(" get-privapp-permissions TARGET-PACKAGE");
2935 pw.println(" Prints all privileged permissions for a package.");
2936 pw.println("");
2937 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE");
2938 pw.println(" Prints all privileged permissions that are denied for a package.");
2939 pw.println("");
2940 pw.println(" get-oem-permissions TARGET-PACKAGE");
2941 pw.println(" Prints all OEM permissions for a package.");
2942 pw.println("");
2943 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
2944 pw.println(" get-app-link [--user USER_ID] PACKAGE");
2945 pw.println("");
2946 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
2947 pw.println(" Trim cache files to reach the given free space.");
2948 pw.println("");
2949 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
2950 pw.println(" [--guest] USER_NAME");
2951 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
2952 pw.println(" of the user.");
2953 pw.println("");
2954 pw.println(" remove-user USER_ID");
2955 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data");
2956 pw.println(" associated with that user");
2957 pw.println("");
2958 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE");
2959 pw.println("");
2960 pw.println(" get-max-users");
2961 pw.println("");
Alex Chauc12189b2018-01-16 15:01:15 +00002962 pw.println(" get-max-running-users");
2963 pw.println("");
Calin Juravleb6f844d2017-07-17 15:23:21 -07002964 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
Richard Uhler568a9692016-05-03 16:02:52 -07002965 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002966 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
David Brazdil990fb6b2016-03-01 10:02:27 +00002967 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00002968 pw.println(" -c: clear profile data before compiling");
2969 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00002970 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07002971 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01002972 pw.println(" assume-verified");
2973 pw.println(" extract");
2974 pw.println(" verify");
2975 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07002976 pw.println(" space-profile");
2977 pw.println(" space");
2978 pw.println(" speed-profile");
2979 pw.println(" speed");
2980 pw.println(" everything");
2981 pw.println(" -r: select compilation reason");
2982 pw.println(" REASON is one of:");
2983 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
2984 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
2985 }
David Brazdilcf046952016-03-08 16:40:20 +00002986 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07002987 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08002988 pw.println(" --secondary-dex: compile app secondary dex files");
Calin Juravleb6f844d2017-07-17 15:23:21 -07002989 pw.println(" --split SPLIT: compile only the given split name");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002990 pw.println("");
2991 pw.println(" force-dex-opt PACKAGE");
2992 pw.println(" Force immediate execution of dex opt for the given PACKAGE.");
2993 pw.println("");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08002994 pw.println(" bg-dexopt-job");
2995 pw.println(" Execute the background optimizations immediately.");
2996 pw.println(" Note that the command only runs the background optimizer logic. It may");
2997 pw.println(" overlap with the actual job but the job scheduler will not be able to");
2998 pw.println(" cancel it. It will also run even if the device is not in the idle");
2999 pw.println(" maintenance mode.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003000 pw.println("");
Calin Juravle1aa5f882017-01-25 01:05:50 -08003001 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
3002 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003003 pw.println("");
David Sehrcae13b02016-06-07 09:11:27 -07003004 pw.println(" dump-profiles TARGET-PACKAGE");
3005 pw.println(" Dumps method/class profile files to");
Calin Juravle21216c62018-05-04 17:35:29 -07003006 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt");
3007 pw.println("");
3008 pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]");
3009 pw.println(" Take a snapshot of the package profiles to");
3010 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
3011 + "TARGET-PACKAGE[-code-path].prof");
3012 pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003013 pw.println("");
Makoto Onuki4828a592016-03-15 18:06:57 -07003014 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07003015 pw.println(" Set the default home activity (aka launcher).");
3016 pw.println("");
3017 pw.println(" set-installer PACKAGE INSTALLER");
3018 pw.println(" Set installer package name");
3019 pw.println("");
3020 pw.println(" get-instantapp-resolver");
3021 pw.println(" Return the name of the component that is the current instant app installer.");
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08003022 pw.println("");
3023 pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
3024 pw.println(" Mark the app as harmful with the given warning message.");
Ben Gruver9ef60092018-01-10 11:32:30 -08003025 pw.println("");
3026 pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
3027 pw.println(" Return the harmful app warning message for the given app, if present");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003028 pw.println();
Patrick Baumanna980e142018-02-12 11:45:23 -08003029 pw.println(" uninstall-system-updates");
3030 pw.println(" Remove updates to all system applications and fall back to their /system " +
3031 "version.");
3032 pw.println();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08003033 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07003034 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003035
3036 private static class LocalIntentReceiver {
wangmingming155414292018-04-10 09:35:25 +08003037 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003038
3039 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
3040 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07003041 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003042 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
3043 try {
3044 mResult.offer(intent, 5, TimeUnit.SECONDS);
3045 } catch (InterruptedException e) {
3046 throw new RuntimeException(e);
3047 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08003048 }
3049 };
3050
3051 public IntentSender getIntentSender() {
3052 return new IntentSender((IIntentSender) mLocalSender);
3053 }
3054
3055 public Intent getResult() {
3056 try {
3057 return mResult.take();
3058 } catch (InterruptedException e) {
3059 throw new RuntimeException(e);
3060 }
3061 }
3062 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07003063}