blob: d06437e562ed34f281f96686e224db3f580a974d [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;
Calin Juravle21216c62018-05-04 17:35:29 -070028import android.app.Application;
Todd Kennedy60459ab2015-10-30 11:32:16 -070029import android.content.ComponentName;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070030import android.content.Context;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080031import android.content.IIntentReceiver;
32import android.content.IIntentSender;
33import android.content.Intent;
34import android.content.IntentSender;
Todd Kennedy60459ab2015-10-30 11:32:16 -070035import android.content.pm.ApplicationInfo;
36import android.content.pm.FeatureInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070037import android.content.pm.IPackageDataObserver;
Patrick Baumanna980e142018-02-12 11:45:23 -080038import android.content.pm.IPackageInstaller;
Todd Kennedy60459ab2015-10-30 11:32:16 -070039import android.content.pm.IPackageManager;
40import android.content.pm.InstrumentationInfo;
41import android.content.pm.PackageInfo;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080042import android.content.pm.PackageInstaller;
Jeff Sharkey0451de62018-02-02 11:27:21 -070043import android.content.pm.PackageInstaller.SessionParams;
Todd Kennedy60459ab2015-10-30 11:32:16 -070044import android.content.pm.PackageItemInfo;
45import android.content.pm.PackageManager;
Jeff Sharkey0451de62018-02-02 11:27:21 -070046import android.content.pm.PackageManager.NameNotFoundException;
Shunta Sato4f26cb52016-06-28 09:29:19 +090047import android.content.pm.PackageParser;
48import android.content.pm.PackageParser.ApkLite;
49import android.content.pm.PackageParser.PackageLite;
50import android.content.pm.PackageParser.PackageParserException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070051import android.content.pm.ParceledListSlice;
52import android.content.pm.PermissionGroupInfo;
53import android.content.pm.PermissionInfo;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080054import android.content.pm.ResolveInfo;
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;
70import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080071import android.os.PersistableBundle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070072import android.os.Process;
Todd Kennedy60459ab2015-10-30 11:32:16 -070073import android.os.RemoteException;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070074import android.os.ServiceManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070075import android.os.ShellCommand;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070076import android.os.SystemClock;
Calin Juravle8bc758b2016-03-28 12:31:52 +010077import android.os.SystemProperties;
Todd Kennedy60459ab2015-10-30 11:32:16 -070078import android.os.UserHandle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070079import android.os.UserManager;
80import android.os.storage.StorageManager;
Calin Juravlebdd94d92018-05-17 01:23:15 -070081import android.system.ErrnoException;
82import android.system.Os;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080083import android.text.TextUtils;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070084import android.text.format.DateUtils;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080085import android.util.ArraySet;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080086import android.util.PrintWriterPrinter;
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;
Andreas Gampebdd30d82016-03-20 11:32:11 -070091import dalvik.system.DexFile;
Calin Juravle21216c62018-05-04 17:35:29 -070092import java.io.File;
93import java.io.FileOutputStream;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080094import java.io.IOException;
Calin Juravle21216c62018-05-04 17:35:29 -070095import java.io.InputStream;
96import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -070097import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080098import java.net.URISyntaxException;
Calin Juravle21216c62018-05-04 17:35:29 -070099import java.nio.file.Files;
100import java.nio.file.Paths;
101import java.nio.file.StandardCopyOption;
102import java.nio.file.attribute.FileAttribute;
103import java.util.ArrayList;
104import java.util.Collections;
105import java.util.Comparator;
106import java.util.LinkedList;
107import java.util.List;
108import java.util.Map;
109import java.util.Objects;
110import java.util.WeakHashMap;
111import java.util.concurrent.CountDownLatch;
wangmingming155414292018-04-10 09:35:25 +0800112import java.util.concurrent.LinkedBlockingQueue;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800113import java.util.concurrent.SynchronousQueue;
114import java.util.concurrent.TimeUnit;
Calin Juravle21216c62018-05-04 17:35:29 -0700115import libcore.io.IoUtils;
116import libcore.io.Streams;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700117
118class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700119 /** Path for streaming APK content */
120 private static final String STDIN_PATH = "-";
Calin Juravle21216c62018-05-04 17:35:29 -0700121 /** Path where ART profiles snapshots are dumped for the shell user */
122 private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700123
Todd Kennedy60459ab2015-10-30 11:32:16 -0700124 final IPackageManager mInterface;
125 final private WeakHashMap<String, Resources> mResourceCache =
126 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800127 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700128 boolean mBrief;
129 boolean mComponents;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700130
131 PackageManagerShellCommand(PackageManagerService service) {
132 mInterface = service;
133 }
134
135 @Override
136 public int onCommand(String cmd) {
137 if (cmd == null) {
138 return handleDefaultCommands(cmd);
139 }
140
141 final PrintWriter pw = getOutPrintWriter();
142 try {
143 switch(cmd) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700144 case "path":
145 return runPath();
146 case "dump":
147 return runDump();
148 case "list":
149 return runList();
150 case "resolve-activity":
151 return runResolveActivity();
152 case "query-activities":
153 return runQueryIntentActivities();
154 case "query-services":
155 return runQueryIntentServices();
156 case "query-receivers":
157 return runQueryIntentReceivers();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800158 case "install":
159 return runInstall();
160 case "install-abandon":
161 case "install-destroy":
162 return runInstallAbandon();
163 case "install-commit":
164 return runInstallCommit();
165 case "install-create":
166 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800167 case "install-remove":
168 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800169 case "install-write":
170 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800171 case "install-existing":
172 return runInstallExisting();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700173 case "set-install-location":
174 return runSetInstallLocation();
175 case "get-install-location":
176 return runGetInstallLocation();
177 case "move-package":
178 return runMovePackage();
179 case "move-primary-storage":
180 return runMovePrimaryStorage();
David Brazdil493411a2016-02-01 13:48:46 +0000181 case "compile":
182 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800183 case "reconcile-secondary-dex-files":
184 return runreconcileSecondaryDexFiles();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700185 case "force-dex-opt":
186 return runForceDexOpt();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800187 case "bg-dexopt-job":
188 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700189 case "dump-profiles":
190 return runDumpProfiles();
Calin Juravle21216c62018-05-04 17:35:29 -0700191 case "snapshot-profile":
192 return runSnapshotProfile();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800193 case "uninstall":
194 return runUninstall();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700195 case "clear":
196 return runClear();
197 case "enable":
198 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
199 case "disable":
200 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
201 case "disable-user":
202 return runSetEnabledSetting(
203 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
204 case "disable-until-used":
205 return runSetEnabledSetting(
206 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
207 case "default-state":
208 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
209 case "hide":
210 return runSetHiddenSetting(true);
211 case "unhide":
212 return runSetHiddenSetting(false);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000213 case "suspend":
214 return runSuspend(true);
215 case "unsuspend":
216 return runSuspend(false);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700217 case "grant":
218 return runGrantRevokePermission(true);
219 case "revoke":
220 return runGrantRevokePermission(false);
221 case "reset-permissions":
222 return runResetPermissions();
223 case "set-permission-enforced":
224 return runSetPermissionEnforced();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800225 case "get-privapp-permissions":
226 return runGetPrivappPermissions();
Todd Kennedy74629e32017-08-15 14:48:07 -0700227 case "get-privapp-deny-permissions":
228 return runGetPrivappDenyPermissions();
Svet Ganov087dce22017-09-07 15:42:16 -0700229 case "get-oem-permissions":
230 return runGetOemPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700231 case "set-app-link":
232 return runSetAppLink();
233 case "get-app-link":
234 return runGetAppLink();
235 case "trim-caches":
236 return runTrimCaches();
237 case "create-user":
238 return runCreateUser();
239 case "remove-user":
240 return runRemoveUser();
241 case "set-user-restriction":
242 return runSetUserRestriction();
243 case "get-max-users":
244 return runGetMaxUsers();
Alex Chauc12189b2018-01-16 15:01:15 +0000245 case "get-max-running-users":
246 return runGetMaxRunningUsers();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700247 case "set-home-activity":
248 return runSetHomeActivity();
249 case "set-installer":
250 return runSetInstaller();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700251 case "get-instantapp-resolver":
252 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900253 case "has-feature":
254 return runHasFeature();
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800255 case "set-harmful-app-warning":
256 return runSetHarmfulAppWarning();
Ben Gruver9ef60092018-01-10 11:32:30 -0800257 case "get-harmful-app-warning":
258 return runGetHarmfulAppWarning();
Patrick Baumanna980e142018-02-12 11:45:23 -0800259 case "uninstall-system-updates":
260 return uninstallSystemUpdates();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700261 default: {
262 String nextArg = getNextArg();
263 if (nextArg == null) {
264 if (cmd.equalsIgnoreCase("-l")) {
265 return runListPackages(false);
266 } else if (cmd.equalsIgnoreCase("-lf")) {
267 return runListPackages(true);
268 }
269 } else if (getNextArg() == null) {
270 if (cmd.equalsIgnoreCase("-p")) {
271 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
272 }
273 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700274 return handleDefaultCommands(cmd);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700275 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700276 }
277 } catch (RemoteException e) {
278 pw.println("Remote exception: " + e);
279 }
280 return -1;
281 }
282
Patrick Baumanna980e142018-02-12 11:45:23 -0800283 private int uninstallSystemUpdates() {
284 final PrintWriter pw = getOutPrintWriter();
285 List<String> failedUninstalls = new LinkedList<>();
286 try {
287 final ParceledListSlice<ApplicationInfo> packages =
288 mInterface.getInstalledApplications(
289 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
290 final IPackageInstaller installer = mInterface.getPackageInstaller();
291 List<ApplicationInfo> list = packages.getList();
292 for (ApplicationInfo info : list) {
293 if (info.isUpdatedSystemApp()) {
294 pw.println("Uninstalling updates to " + info.packageName + "...");
295 final LocalIntentReceiver receiver = new LocalIntentReceiver();
296 installer.uninstall(new VersionedPackage(info.packageName,
297 info.versionCode), null /*callerPackageName*/, 0 /* flags */,
298 receiver.getIntentSender(), 0);
299
300 final Intent result = receiver.getResult();
301 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
302 PackageInstaller.STATUS_FAILURE);
303 if (status != PackageInstaller.STATUS_SUCCESS) {
304 failedUninstalls.add(info.packageName);
305 }
306 }
307 }
308 } catch (RemoteException e) {
309 pw.println("Failure ["
310 + e.getClass().getName() + " - "
311 + e.getMessage() + "]");
312 return 0;
313 }
314 if (!failedUninstalls.isEmpty()) {
315 pw.println("Failure [Couldn't uninstall packages: "
316 + TextUtils.join(", ", failedUninstalls)
317 + "]");
318 return 0;
319 }
320 pw.println("Success");
321 return 1;
322 }
323
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700324 private void setParamsSize(InstallParams params, String inPath) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700325 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700326 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
327 if (fd == null) {
328 getErrPrintWriter().println("Error: Can't open file: " + inPath);
329 throw new IllegalArgumentException("Error: Can't open file: " + inPath);
330 }
331 try {
332 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
333 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
334 null, null);
335 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
Dianne Hackborn1704e3c2017-10-31 19:55:42 +0000336 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700337 } catch (PackageParserException | IOException e) {
338 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
339 throw new IllegalArgumentException(
340 "Error: Failed to parse APK file: " + inPath, e);
341 } finally {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900342 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700343 fd.close();
344 } catch (IOException e) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900345 }
346 }
347 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700348 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700349 /**
350 * Displays the package file for a package.
351 * @param pckg
352 */
353 private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
354 PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId);
355 if (info != null && info.applicationInfo != null) {
356 final PrintWriter pw = getOutPrintWriter();
357 pw.print("package:");
358 pw.println(info.applicationInfo.sourceDir);
359 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
360 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
361 pw.print("package:");
362 pw.println(splitSourceDir);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800363 }
364 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700365 return 0;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800366 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700367 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800368 }
369
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700370 private int runPath() throws RemoteException {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000371 int userId = UserHandle.USER_SYSTEM;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700372 String option = getNextOption();
373 if (option != null && option.equals("--user")) {
374 userId = UserHandle.parseUserArg(getNextArgRequired());
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000375 }
376
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700377 String pkg = getNextArgRequired();
378 if (pkg == null) {
379 getErrPrintWriter().println("Error: no package specified");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000380 return 1;
381 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700382 return displayPackageFilePath(pkg, userId);
David Sehra8777082016-05-24 15:25:23 -0700383 }
384
Todd Kennedy60459ab2015-10-30 11:32:16 -0700385 private int runList() throws RemoteException {
386 final PrintWriter pw = getOutPrintWriter();
387 final String type = getNextArg();
388 if (type == null) {
389 pw.println("Error: didn't specify type of data to list");
390 return -1;
391 }
392 switch(type) {
393 case "features":
394 return runListFeatures();
395 case "instrumentation":
396 return runListInstrumentation();
397 case "libraries":
398 return runListLibraries();
399 case "package":
400 case "packages":
401 return runListPackages(false /*showSourceDir*/);
402 case "permission-groups":
403 return runListPermissionGroups();
404 case "permissions":
405 return runListPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700406 case "users":
407 ServiceManager.getService("user").shellCommand(
408 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
409 new String[] { "list" }, getShellCallback(), adoptResultReceiver());
410 return 0;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700411 }
412 pw.println("Error: unknown list type '" + type + "'");
413 return -1;
414 }
415
416 private int runListFeatures() throws RemoteException {
417 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700418 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700419
420 // sort by name
421 Collections.sort(list, new Comparator<FeatureInfo>() {
422 public int compare(FeatureInfo o1, FeatureInfo o2) {
423 if (o1.name == o2.name) return 0;
424 if (o1.name == null) return -1;
425 if (o2.name == null) return 1;
426 return o1.name.compareTo(o2.name);
427 }
428 });
429
430 final int count = (list != null) ? list.size() : 0;
431 for (int p = 0; p < count; p++) {
432 FeatureInfo fi = list.get(p);
433 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700434 if (fi.name != null) {
435 pw.print(fi.name);
436 if (fi.version > 0) {
437 pw.print("=");
438 pw.print(fi.version);
439 }
440 pw.println();
441 } else {
442 pw.println("reqGlEsVersion=0x"
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700443 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700444 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700445 }
446 return 0;
447 }
448
449 private int runListInstrumentation() throws RemoteException {
450 final PrintWriter pw = getOutPrintWriter();
451 boolean showSourceDir = false;
452 String targetPackage = null;
453
454 try {
455 String opt;
456 while ((opt = getNextArg()) != null) {
457 switch (opt) {
458 case "-f":
459 showSourceDir = true;
460 break;
461 default:
462 if (opt.charAt(0) != '-') {
463 targetPackage = opt;
464 } else {
465 pw.println("Error: Unknown option: " + opt);
466 return -1;
467 }
468 break;
469 }
470 }
471 } catch (RuntimeException ex) {
472 pw.println("Error: " + ex.toString());
473 return -1;
474 }
475
476 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700477 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700478
479 // sort by target package
480 Collections.sort(list, new Comparator<InstrumentationInfo>() {
481 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
482 return o1.targetPackage.compareTo(o2.targetPackage);
483 }
484 });
485
486 final int count = (list != null) ? list.size() : 0;
487 for (int p = 0; p < count; p++) {
488 final InstrumentationInfo ii = list.get(p);
489 pw.print("instrumentation:");
490 if (showSourceDir) {
491 pw.print(ii.sourceDir);
492 pw.print("=");
493 }
494 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
495 pw.print(cn.flattenToShortString());
496 pw.print(" (target=");
497 pw.print(ii.targetPackage);
498 pw.println(")");
499 }
500 return 0;
501 }
502
503 private int runListLibraries() throws RemoteException {
504 final PrintWriter pw = getOutPrintWriter();
505 final List<String> list = new ArrayList<String>();
506 final String[] rawList = mInterface.getSystemSharedLibraryNames();
507 for (int i = 0; i < rawList.length; i++) {
508 list.add(rawList[i]);
509 }
510
511 // sort by name
512 Collections.sort(list, new Comparator<String>() {
513 public int compare(String o1, String o2) {
514 if (o1 == o2) return 0;
515 if (o1 == null) return -1;
516 if (o2 == null) return 1;
517 return o1.compareTo(o2);
518 }
519 });
520
521 final int count = (list != null) ? list.size() : 0;
522 for (int p = 0; p < count; p++) {
523 String lib = list.get(p);
524 pw.print("library:");
525 pw.println(lib);
526 }
527 return 0;
528 }
529
530 private int runListPackages(boolean showSourceDir) throws RemoteException {
531 final PrintWriter pw = getOutPrintWriter();
532 int getFlags = 0;
533 boolean listDisabled = false, listEnabled = false;
534 boolean listSystem = false, listThirdParty = false;
535 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700536 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800537 boolean showVersionCode = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700538 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700539 int userId = UserHandle.USER_SYSTEM;
540 try {
541 String opt;
542 while ((opt = getNextOption()) != null) {
543 switch (opt) {
544 case "-d":
545 listDisabled = true;
546 break;
547 case "-e":
548 listEnabled = true;
549 break;
550 case "-f":
551 showSourceDir = true;
552 break;
553 case "-i":
554 listInstaller = true;
555 break;
556 case "-l":
557 // old compat
558 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700559 case "-s":
560 listSystem = true;
561 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700562 case "-U":
563 showUid = true;
564 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700565 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700566 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700567 break;
568 case "-3":
569 listThirdParty = true;
570 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800571 case "--show-versioncode":
572 showVersionCode = true;
573 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700574 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800575 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700576 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700577 case "--uid":
578 showUid = true;
579 uid = Integer.parseInt(getNextArgRequired());
580 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700581 default:
582 pw.println("Error: Unknown option: " + opt);
583 return -1;
584 }
585 }
586 } catch (RuntimeException ex) {
587 pw.println("Error: " + ex.toString());
588 return -1;
589 }
590
591 final String filter = getNextArg();
592
593 @SuppressWarnings("unchecked")
594 final ParceledListSlice<PackageInfo> slice =
595 mInterface.getInstalledPackages(getFlags, userId);
596 final List<PackageInfo> packages = slice.getList();
597
598 final int count = packages.size();
599 for (int p = 0; p < count; p++) {
600 final PackageInfo info = packages.get(p);
601 if (filter != null && !info.packageName.contains(filter)) {
602 continue;
603 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700604 if (uid != -1 && info.applicationInfo.uid != uid) {
605 continue;
606 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700607 final boolean isSystem =
608 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
609 if ((!listDisabled || !info.applicationInfo.enabled) &&
610 (!listEnabled || info.applicationInfo.enabled) &&
611 (!listSystem || isSystem) &&
612 (!listThirdParty || !isSystem)) {
613 pw.print("package:");
614 if (showSourceDir) {
615 pw.print(info.applicationInfo.sourceDir);
616 pw.print("=");
617 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800618 pw.print(info.packageName);
619 if (showVersionCode) {
620 pw.print(" versionCode:");
621 pw.print(info.applicationInfo.versionCode);
622 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700623 if (listInstaller) {
624 pw.print(" installer=");
625 pw.print(mInterface.getInstallerPackageName(info.packageName));
626 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700627 if (showUid) {
628 pw.print(" uid:");
629 pw.print(info.applicationInfo.uid);
630 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700631 pw.println();
632 }
633 }
634 return 0;
635 }
636
637 private int runListPermissionGroups() throws RemoteException {
638 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700639 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700640
641 final int count = pgs.size();
642 for (int p = 0; p < count ; p++) {
643 final PermissionGroupInfo pgi = pgs.get(p);
644 pw.print("permission group:");
645 pw.println(pgi.name);
646 }
647 return 0;
648 }
649
650 private int runListPermissions() throws RemoteException {
651 final PrintWriter pw = getOutPrintWriter();
652 boolean labels = false;
653 boolean groups = false;
654 boolean userOnly = false;
655 boolean summary = false;
656 boolean dangerousOnly = false;
657 String opt;
658 while ((opt = getNextOption()) != null) {
659 switch (opt) {
660 case "-d":
661 dangerousOnly = true;
662 break;
663 case "-f":
664 labels = true;
665 break;
666 case "-g":
667 groups = true;
668 break;
669 case "-s":
670 groups = true;
671 labels = true;
672 summary = true;
673 break;
674 case "-u":
675 userOnly = true;
676 break;
677 default:
678 pw.println("Error: Unknown option: " + opt);
679 return 1;
680 }
681 }
682
683 final ArrayList<String> groupList = new ArrayList<String>();
684 if (groups) {
685 final List<PermissionGroupInfo> infos =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700686 mInterface.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700687 final int count = infos.size();
688 for (int i = 0; i < count; i++) {
689 groupList.add(infos.get(i).name);
690 }
691 groupList.add(null);
692 } else {
693 final String grp = getNextArg();
694 groupList.add(grp);
695 }
696
697 if (dangerousOnly) {
698 pw.println("Dangerous Permissions:");
699 pw.println("");
700 doListPermissions(groupList, groups, labels, summary,
701 PermissionInfo.PROTECTION_DANGEROUS,
702 PermissionInfo.PROTECTION_DANGEROUS);
703 if (userOnly) {
704 pw.println("Normal Permissions:");
705 pw.println("");
706 doListPermissions(groupList, groups, labels, summary,
707 PermissionInfo.PROTECTION_NORMAL,
708 PermissionInfo.PROTECTION_NORMAL);
709 }
710 } else if (userOnly) {
711 pw.println("Dangerous and Normal Permissions:");
712 pw.println("");
713 doListPermissions(groupList, groups, labels, summary,
714 PermissionInfo.PROTECTION_NORMAL,
715 PermissionInfo.PROTECTION_DANGEROUS);
716 } else {
717 pw.println("All Permissions:");
718 pw.println("");
719 doListPermissions(groupList, groups, labels, summary,
720 -10000, 10000);
721 }
722 return 0;
723 }
724
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800725 private Intent parseIntentAndUser() throws URISyntaxException {
726 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700727 mBrief = false;
728 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800729 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
730 @Override
731 public boolean handleOption(String opt, ShellCommand cmd) {
732 if ("--user".equals(opt)) {
733 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
734 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700735 } else if ("--brief".equals(opt)) {
736 mBrief = true;
737 return true;
738 } else if ("--components".equals(opt)) {
739 mComponents = true;
740 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800741 }
742 return false;
743 }
744 });
745 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
746 Binder.getCallingUid(), mTargetUser, false, false, null, null);
747 return intent;
748 }
749
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700750 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
751 boolean brief, boolean components) {
752 if (brief || components) {
753 final ComponentName comp;
754 if (ri.activityInfo != null) {
755 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
756 } else if (ri.serviceInfo != null) {
757 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
758 } else if (ri.providerInfo != null) {
759 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
760 } else {
761 comp = null;
762 }
763 if (comp != null) {
764 if (!components) {
765 pr.println(prefix + "priority=" + ri.priority
766 + " preferredOrder=" + ri.preferredOrder
767 + " match=0x" + Integer.toHexString(ri.match)
768 + " specificIndex=" + ri.specificIndex
769 + " isDefault=" + ri.isDefault);
770 }
771 pr.println(prefix + comp.flattenToShortString());
772 return;
773 }
774 }
775 ri.dump(pr, prefix);
776 }
777
Dianne Hackborn99878e92015-12-02 16:27:41 -0800778 private int runResolveActivity() {
779 Intent intent;
780 try {
781 intent = parseIntentAndUser();
782 } catch (URISyntaxException e) {
783 throw new RuntimeException(e.getMessage(), e);
784 }
785 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700786 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800787 PrintWriter pw = getOutPrintWriter();
788 if (ri == null) {
789 pw.println("No activity found");
790 } else {
791 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700792 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800793 }
794 } catch (RemoteException e) {
795 throw new RuntimeException("Failed calling service", e);
796 }
797 return 0;
798 }
799
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800800 private int runQueryIntentActivities() {
801 Intent intent;
802 try {
803 intent = parseIntentAndUser();
804 } catch (URISyntaxException e) {
805 throw new RuntimeException(e.getMessage(), e);
806 }
807 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700808 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700809 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800810 PrintWriter pw = getOutPrintWriter();
811 if (result == null || result.size() <= 0) {
812 pw.println("No activities found");
813 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700814 if (!mComponents) {
815 pw.print(result.size()); pw.println(" activities found:");
816 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
817 for (int i = 0; i < result.size(); i++) {
818 pw.print(" Activity #"); pw.print(i); pw.println(":");
819 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
820 }
821 } else {
822 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
823 for (int i = 0; i < result.size(); i++) {
824 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
825 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800826 }
827 }
828 } catch (RemoteException e) {
829 throw new RuntimeException("Failed calling service", e);
830 }
831 return 0;
832 }
833
834 private int runQueryIntentServices() {
835 Intent intent;
836 try {
837 intent = parseIntentAndUser();
838 } catch (URISyntaxException e) {
839 throw new RuntimeException(e.getMessage(), e);
840 }
841 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700842 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700843 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800844 PrintWriter pw = getOutPrintWriter();
845 if (result == null || result.size() <= 0) {
846 pw.println("No services found");
847 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700848 if (!mComponents) {
849 pw.print(result.size()); pw.println(" services found:");
850 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
851 for (int i = 0; i < result.size(); i++) {
852 pw.print(" Service #"); pw.print(i); pw.println(":");
853 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
854 }
855 } else {
856 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
857 for (int i = 0; i < result.size(); i++) {
858 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
859 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800860 }
861 }
862 } catch (RemoteException e) {
863 throw new RuntimeException("Failed calling service", e);
864 }
865 return 0;
866 }
867
868 private int runQueryIntentReceivers() {
869 Intent intent;
870 try {
871 intent = parseIntentAndUser();
872 } catch (URISyntaxException e) {
873 throw new RuntimeException(e.getMessage(), e);
874 }
875 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700876 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700877 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800878 PrintWriter pw = getOutPrintWriter();
879 if (result == null || result.size() <= 0) {
880 pw.println("No receivers found");
881 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700882 if (!mComponents) {
883 pw.print(result.size()); pw.println(" receivers found:");
884 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
885 for (int i = 0; i < result.size(); i++) {
886 pw.print(" Receiver #"); pw.print(i); pw.println(":");
887 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
888 }
889 } else {
890 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
891 for (int i = 0; i < result.size(); i++) {
892 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
893 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800894 }
895 }
896 } catch (RemoteException e) {
897 throw new RuntimeException("Failed calling service", e);
898 }
899 return 0;
900 }
901
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700902 private int runInstall() throws RemoteException {
903 final PrintWriter pw = getOutPrintWriter();
904 final InstallParams params = makeInstallParams();
905 final String inPath = getNextArg();
906
907 setParamsSize(params, inPath);
908 final int sessionId = doCreateSession(params.sessionParams,
909 params.installerPackageName, params.userId);
910 boolean abandonSession = true;
911 try {
912 if (inPath == null && params.sessionParams.sizeBytes == -1) {
913 pw.println("Error: must either specify a package size or an APK file");
914 return 1;
915 }
916 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk",
917 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
918 return 1;
919 }
920 if (doCommitSession(sessionId, false /*logSuccess*/)
921 != PackageInstaller.STATUS_SUCCESS) {
922 return 1;
923 }
924 abandonSession = false;
925 pw.println("Success");
926 return 0;
927 } finally {
928 if (abandonSession) {
929 try {
930 doAbandonSession(sessionId, false /*logSuccess*/);
931 } catch (Exception ignore) {
932 }
933 }
934 }
935 }
936
937 private int runInstallAbandon() throws RemoteException {
938 final int sessionId = Integer.parseInt(getNextArg());
939 return doAbandonSession(sessionId, true /*logSuccess*/);
940 }
941
942 private int runInstallCommit() throws RemoteException {
943 final int sessionId = Integer.parseInt(getNextArg());
944 return doCommitSession(sessionId, true /*logSuccess*/);
945 }
946
947 private int runInstallCreate() throws RemoteException {
948 final PrintWriter pw = getOutPrintWriter();
949 final InstallParams installParams = makeInstallParams();
950 final int sessionId = doCreateSession(installParams.sessionParams,
951 installParams.installerPackageName, installParams.userId);
952
953 // NOTE: adb depends on parsing this string
954 pw.println("Success: created install session [" + sessionId + "]");
955 return 0;
956 }
957
958 private int runInstallWrite() throws RemoteException {
959 long sizeBytes = -1;
960
961 String opt;
962 while ((opt = getNextOption()) != null) {
963 if (opt.equals("-S")) {
964 sizeBytes = Long.parseLong(getNextArg());
965 } else {
966 throw new IllegalArgumentException("Unknown option: " + opt);
967 }
968 }
969
970 final int sessionId = Integer.parseInt(getNextArg());
971 final String splitName = getNextArg();
972 final String path = getNextArg();
973 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
974 }
975
976 private int runInstallRemove() throws RemoteException {
977 final PrintWriter pw = getOutPrintWriter();
978
979 final int sessionId = Integer.parseInt(getNextArg());
980
981 final String splitName = getNextArg();
982 if (splitName == null) {
983 pw.println("Error: split name not specified");
984 return 1;
985 }
986 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
987 }
988
989 private int runInstallExisting() throws RemoteException {
990 final PrintWriter pw = getOutPrintWriter();
991 int userId = UserHandle.USER_SYSTEM;
992 int installFlags = 0;
993 String opt;
994 while ((opt = getNextOption()) != null) {
995 switch (opt) {
996 case "--user":
997 userId = UserHandle.parseUserArg(getNextArgRequired());
998 break;
999 case "--ephemeral":
1000 case "--instant":
1001 installFlags |= PackageManager.INSTALL_INSTANT_APP;
1002 installFlags &= ~PackageManager.INSTALL_FULL_APP;
1003 break;
1004 case "--full":
1005 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1006 installFlags |= PackageManager.INSTALL_FULL_APP;
1007 break;
1008 default:
1009 pw.println("Error: Unknown option: " + opt);
1010 return 1;
1011 }
1012 }
1013
1014 final String packageName = getNextArg();
1015 if (packageName == null) {
1016 pw.println("Error: package name not specified");
1017 return 1;
1018 }
1019
1020 try {
1021 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
1022 installFlags, PackageManager.INSTALL_REASON_UNKNOWN);
1023 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
1024 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1025 }
1026 pw.println("Package " + packageName + " installed for user: " + userId);
1027 return 0;
1028 } catch (RemoteException | NameNotFoundException e) {
1029 pw.println(e.toString());
1030 return 1;
1031 }
1032 }
1033
1034 private int runSetInstallLocation() throws RemoteException {
1035 int loc;
1036
1037 String arg = getNextArg();
1038 if (arg == null) {
1039 getErrPrintWriter().println("Error: no install location specified.");
1040 return 1;
1041 }
1042 try {
1043 loc = Integer.parseInt(arg);
1044 } catch (NumberFormatException e) {
1045 getErrPrintWriter().println("Error: install location has to be a number.");
1046 return 1;
1047 }
1048 if (!mInterface.setInstallLocation(loc)) {
1049 getErrPrintWriter().println("Error: install location has to be a number.");
1050 return 1;
1051 }
1052 return 0;
1053 }
1054
1055 private int runGetInstallLocation() throws RemoteException {
1056 int loc = mInterface.getInstallLocation();
1057 String locStr = "invalid";
1058 if (loc == PackageHelper.APP_INSTALL_AUTO) {
1059 locStr = "auto";
1060 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
1061 locStr = "internal";
1062 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
1063 locStr = "external";
1064 }
1065 getOutPrintWriter().println(loc + "[" + locStr + "]");
1066 return 0;
1067 }
1068
1069 public int runMovePackage() throws RemoteException {
1070 final String packageName = getNextArg();
1071 if (packageName == null) {
1072 getErrPrintWriter().println("Error: package name not specified");
1073 return 1;
1074 }
1075 String volumeUuid = getNextArg();
1076 if ("internal".equals(volumeUuid)) {
1077 volumeUuid = null;
1078 }
1079
1080 final int moveId = mInterface.movePackage(packageName, volumeUuid);
1081
1082 int status = mInterface.getMoveStatus(moveId);
1083 while (!PackageManager.isMoveStatusFinished(status)) {
1084 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1085 status = mInterface.getMoveStatus(moveId);
1086 }
1087
1088 if (status == PackageManager.MOVE_SUCCEEDED) {
1089 getOutPrintWriter().println("Success");
1090 return 0;
1091 } else {
1092 getErrPrintWriter().println("Failure [" + status + "]");
1093 return 1;
1094 }
1095 }
1096
1097 public int runMovePrimaryStorage() throws RemoteException {
1098 String volumeUuid = getNextArg();
1099 if ("internal".equals(volumeUuid)) {
1100 volumeUuid = null;
1101 }
1102
1103 final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1104
1105 int status = mInterface.getMoveStatus(moveId);
1106 while (!PackageManager.isMoveStatusFinished(status)) {
1107 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1108 status = mInterface.getMoveStatus(moveId);
1109 }
1110
1111 if (status == PackageManager.MOVE_SUCCEEDED) {
1112 getOutPrintWriter().println("Success");
1113 return 0;
1114 } else {
1115 getErrPrintWriter().println("Failure [" + status + "]");
1116 return 1;
1117 }
1118 }
1119
1120 private int runCompile() throws RemoteException {
1121 final PrintWriter pw = getOutPrintWriter();
1122 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1123 boolean forceCompilation = false;
1124 boolean allPackages = false;
1125 boolean clearProfileData = false;
1126 String compilerFilter = null;
1127 String compilationReason = null;
1128 String checkProfilesRaw = null;
1129 boolean secondaryDex = false;
1130 String split = null;
1131
1132 String opt;
1133 while ((opt = getNextOption()) != null) {
1134 switch (opt) {
1135 case "-a":
1136 allPackages = true;
1137 break;
1138 case "-c":
1139 clearProfileData = true;
1140 break;
1141 case "-f":
1142 forceCompilation = true;
1143 break;
1144 case "-m":
1145 compilerFilter = getNextArgRequired();
1146 break;
1147 case "-r":
1148 compilationReason = getNextArgRequired();
1149 break;
1150 case "--check-prof":
1151 checkProfilesRaw = getNextArgRequired();
1152 break;
1153 case "--reset":
1154 forceCompilation = true;
1155 clearProfileData = true;
1156 compilationReason = "install";
1157 break;
1158 case "--secondary-dex":
1159 secondaryDex = true;
1160 break;
1161 case "--split":
1162 split = getNextArgRequired();
1163 break;
1164 default:
1165 pw.println("Error: Unknown option: " + opt);
1166 return 1;
1167 }
1168 }
1169
1170 if (checkProfilesRaw != null) {
1171 if ("true".equals(checkProfilesRaw)) {
1172 checkProfiles = true;
1173 } else if ("false".equals(checkProfilesRaw)) {
1174 checkProfiles = false;
1175 } else {
1176 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1177 return 1;
1178 }
1179 }
1180
1181 if (compilerFilter != null && compilationReason != null) {
1182 pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
1183 "at the same time");
1184 return 1;
1185 }
1186 if (compilerFilter == null && compilationReason == null) {
1187 pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " +
1188 "reason (\"-r\") at the same time");
1189 return 1;
1190 }
1191
1192 if (allPackages && split != null) {
1193 pw.println("-a cannot be specified together with --split");
1194 return 1;
1195 }
1196
1197 if (secondaryDex && split != null) {
1198 pw.println("--secondary-dex cannot be specified together with --split");
1199 return 1;
1200 }
1201
1202 String targetCompilerFilter;
1203 if (compilerFilter != null) {
1204 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1205 pw.println("Error: \"" + compilerFilter +
1206 "\" is not a valid compilation filter.");
1207 return 1;
1208 }
1209 targetCompilerFilter = compilerFilter;
1210 } else {
1211 int reason = -1;
1212 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1213 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1214 compilationReason)) {
1215 reason = i;
1216 break;
1217 }
1218 }
1219 if (reason == -1) {
1220 pw.println("Error: Unknown compilation reason: " + compilationReason);
1221 return 1;
1222 }
1223 targetCompilerFilter =
1224 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1225 }
1226
1227
1228 List<String> packageNames = null;
1229 if (allPackages) {
1230 packageNames = mInterface.getAllPackages();
1231 } else {
1232 String packageName = getNextArg();
1233 if (packageName == null) {
1234 pw.println("Error: package name not specified");
1235 return 1;
1236 }
1237 packageNames = Collections.singletonList(packageName);
1238 }
1239
1240 List<String> failedPackages = new ArrayList<>();
Andreas Gampecbd08d42017-11-20 17:03:17 -08001241 int index = 0;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001242 for (String packageName : packageNames) {
1243 if (clearProfileData) {
1244 mInterface.clearApplicationProfileData(packageName);
1245 }
1246
Andreas Gampecbd08d42017-11-20 17:03:17 -08001247 if (allPackages) {
1248 pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1249 pw.flush();
1250 }
1251
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001252 boolean result = secondaryDex
1253 ? mInterface.performDexOptSecondary(packageName,
1254 targetCompilerFilter, forceCompilation)
1255 : mInterface.performDexOptMode(packageName,
1256 checkProfiles, targetCompilerFilter, forceCompilation,
1257 true /* bootComplete */, split);
1258 if (!result) {
1259 failedPackages.add(packageName);
1260 }
1261 }
1262
1263 if (failedPackages.isEmpty()) {
1264 pw.println("Success");
1265 return 0;
1266 } else if (failedPackages.size() == 1) {
1267 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1268 return 1;
1269 } else {
1270 pw.print("Failure: the following packages could not be compiled: ");
1271 boolean is_first = true;
1272 for (String packageName : failedPackages) {
1273 if (is_first) {
1274 is_first = false;
1275 } else {
1276 pw.print(", ");
1277 }
1278 pw.print(packageName);
1279 }
1280 pw.println();
1281 return 1;
1282 }
1283 }
1284
1285 private int runreconcileSecondaryDexFiles() throws RemoteException {
1286 String packageName = getNextArg();
1287 mInterface.reconcileSecondaryDexFiles(packageName);
1288 return 0;
1289 }
1290
1291 public int runForceDexOpt() throws RemoteException {
1292 mInterface.forceDexOpt(getNextArgRequired());
1293 return 0;
1294 }
1295
1296 private int runDexoptJob() throws RemoteException {
Arthur Eubanks09dd1ec2017-09-15 09:28:51 -07001297 String arg;
1298 List<String> packageNames = new ArrayList<>();
1299 while ((arg = getNextArg()) != null) {
1300 packageNames.add(arg);
1301 }
1302 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1303 packageNames);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001304 return result ? 0 : -1;
1305 }
1306
1307 private int runDumpProfiles() throws RemoteException {
1308 String packageName = getNextArg();
1309 mInterface.dumpProfiles(packageName);
1310 return 0;
1311 }
1312
Calin Juravle21216c62018-05-04 17:35:29 -07001313 private int runSnapshotProfile() throws RemoteException {
1314 PrintWriter pw = getOutPrintWriter();
1315
1316 // Parse the arguments
1317 final String packageName = getNextArg();
1318 final boolean isBootImage = "android".equals(packageName);
1319
1320 String codePath = null;
1321 String opt;
1322 while ((opt = getNextArg()) != null) {
1323 switch (opt) {
1324 case "--code-path":
1325 if (isBootImage) {
1326 pw.write("--code-path cannot be used for the boot image.");
1327 return -1;
1328 }
1329 codePath = getNextArg();
1330 break;
1331 default:
1332 pw.write("Unknown arg: " + opt);
1333 return -1;
1334 }
1335 }
1336
1337 // If no code path was explicitly requested, select the base code path.
1338 String baseCodePath = null;
1339 if (!isBootImage) {
1340 PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
1341 /* userId */0);
1342 if (packageInfo == null) {
1343 pw.write("Package not found " + packageName);
1344 return -1;
1345 }
1346 baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
1347 if (codePath == null) {
1348 codePath = baseCodePath;
1349 }
1350 }
1351
1352 // Create the profile snapshot.
1353 final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
1354 // The calling package is needed to debug permission access.
1355 final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
1356 ? "root" : "com.android.shell";
1357 final int profileType = isBootImage
1358 ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
1359 if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
1360 pw.println("Error: Runtime profiling is not enabled");
1361 return -1;
1362 }
1363 mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
1364 codePath, callback, callingPackage);
1365 if (!callback.waitTillDone()) {
1366 pw.println("Error: callback not called");
1367 return callback.mErrCode;
1368 }
1369
1370 // Copy the snapshot profile to the output profile file.
1371 try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
1372 final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
1373 ? "" : ("-" + new File(codePath).getName());
1374 final String outputProfilePath =
1375 ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
1376 try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
1377 Streams.copy(inStream, outStream);
1378 }
Calin Juravlebdd94d92018-05-17 01:23:15 -07001379 // Give read permissions to the other group.
1380 Os.chmod(outputProfilePath, /*mode*/ 0644 );
1381 } catch (IOException | ErrnoException e) {
Calin Juravle21216c62018-05-04 17:35:29 -07001382 pw.println("Error when reading the profile fd: " + e.getMessage());
1383 e.printStackTrace(pw);
1384 return -1;
1385 }
1386 return 0;
1387 }
1388
1389 private static class SnapshotRuntimeProfileCallback
1390 extends ISnapshotRuntimeProfileCallback.Stub {
1391 private boolean mSuccess = false;
1392 private int mErrCode = -1;
1393 private ParcelFileDescriptor mProfileReadFd = null;
1394 private CountDownLatch mDoneSignal = new CountDownLatch(1);
1395
1396 @Override
1397 public void onSuccess(ParcelFileDescriptor profileReadFd) {
1398 mSuccess = true;
1399 try {
1400 // We need to dup the descriptor. We are in the same process as system server
1401 // and we will be receiving the same object (which will be closed on the
1402 // server side).
1403 mProfileReadFd = profileReadFd.dup();
1404 } catch (IOException e) {
1405 e.printStackTrace();
1406 }
1407 mDoneSignal.countDown();
1408 }
1409
1410 @Override
1411 public void onError(int errCode) {
1412 mSuccess = false;
1413 mErrCode = errCode;
1414 mDoneSignal.countDown();
1415 }
1416
1417 boolean waitTillDone() {
1418 boolean done = false;
1419 try {
1420 // The time-out is an arbitrary large value. Since this is a local call the result
1421 // will come very fast.
1422 done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS);
1423 } catch (InterruptedException ignored) {
1424 }
1425 return done && mSuccess;
1426 }
1427 }
1428
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001429 private int runUninstall() throws RemoteException {
1430 final PrintWriter pw = getOutPrintWriter();
1431 int flags = 0;
1432 int userId = UserHandle.USER_ALL;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001433 long versionCode = PackageManager.VERSION_CODE_HIGHEST;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001434
1435 String opt;
1436 while ((opt = getNextOption()) != null) {
1437 switch (opt) {
1438 case "-k":
1439 flags |= PackageManager.DELETE_KEEP_DATA;
1440 break;
1441 case "--user":
1442 userId = UserHandle.parseUserArg(getNextArgRequired());
1443 break;
1444 case "--versionCode":
Dianne Hackborn3accca02013-09-20 09:32:11 -07001445 versionCode = Long.parseLong(getNextArgRequired());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001446 break;
1447 default:
1448 pw.println("Error: Unknown option: " + opt);
1449 return 1;
1450 }
1451 }
1452
1453 final String packageName = getNextArg();
1454 if (packageName == null) {
1455 pw.println("Error: package name not specified");
1456 return 1;
1457 }
1458
1459 // if a split is specified, just remove it and not the whole package
1460 final String splitName = getNextArg();
1461 if (splitName != null) {
1462 return runRemoveSplit(packageName, splitName);
1463 }
1464
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08001465 userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001466 if (userId == UserHandle.USER_ALL) {
1467 userId = UserHandle.USER_SYSTEM;
1468 flags |= PackageManager.DELETE_ALL_USERS;
1469 } else {
1470 final PackageInfo info = mInterface.getPackageInfo(packageName,
1471 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1472 if (info == null) {
1473 pw.println("Failure [not installed for " + userId + "]");
1474 return 1;
1475 }
1476 final boolean isSystem =
1477 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1478 // If we are being asked to delete a system app for just one
1479 // user set flag so it disables rather than reverting to system
1480 // version of the app.
1481 if (isSystem) {
1482 flags |= PackageManager.DELETE_SYSTEM_APP;
1483 }
1484 }
1485
1486 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1487 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1488 versionCode), null /*callerPackageName*/, flags,
1489 receiver.getIntentSender(), userId);
1490
1491 final Intent result = receiver.getResult();
1492 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1493 PackageInstaller.STATUS_FAILURE);
1494 if (status == PackageInstaller.STATUS_SUCCESS) {
1495 pw.println("Success");
1496 return 0;
1497 } else {
1498 pw.println("Failure ["
1499 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1500 return 1;
1501 }
1502 }
1503
1504 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1505 final PrintWriter pw = getOutPrintWriter();
1506 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1507 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1508 sessionParams.appPackageName = packageName;
1509 final int sessionId =
1510 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1511 boolean abandonSession = true;
1512 try {
1513 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1514 != PackageInstaller.STATUS_SUCCESS) {
1515 return 1;
1516 }
1517 if (doCommitSession(sessionId, false /*logSuccess*/)
1518 != PackageInstaller.STATUS_SUCCESS) {
1519 return 1;
1520 }
1521 abandonSession = false;
1522 pw.println("Success");
1523 return 0;
1524 } finally {
1525 if (abandonSession) {
1526 try {
1527 doAbandonSession(sessionId, false /*logSuccess*/);
1528 } catch (Exception ignore) {
1529 }
1530 }
1531 }
1532 }
1533
1534 static class ClearDataObserver extends IPackageDataObserver.Stub {
1535 boolean finished;
1536 boolean result;
1537
1538 @Override
1539 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1540 synchronized (this) {
1541 finished = true;
1542 result = succeeded;
1543 notifyAll();
1544 }
1545 }
1546 }
1547
1548 private int runClear() throws RemoteException {
1549 int userId = UserHandle.USER_SYSTEM;
1550 String option = getNextOption();
1551 if (option != null && option.equals("--user")) {
1552 userId = UserHandle.parseUserArg(getNextArgRequired());
1553 }
1554
1555 String pkg = getNextArg();
1556 if (pkg == null) {
1557 getErrPrintWriter().println("Error: no package specified");
1558 return 1;
1559 }
1560
1561 ClearDataObserver obs = new ClearDataObserver();
Christopher Tate1d99c392017-12-07 16:54:04 -08001562 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001563 synchronized (obs) {
1564 while (!obs.finished) {
1565 try {
1566 obs.wait();
1567 } catch (InterruptedException e) {
1568 }
1569 }
1570 }
1571
1572 if (obs.result) {
1573 getOutPrintWriter().println("Success");
1574 return 0;
1575 } else {
1576 getErrPrintWriter().println("Failed");
1577 return 1;
1578 }
1579 }
1580
1581 private static String enabledSettingToString(int state) {
1582 switch (state) {
1583 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1584 return "default";
1585 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1586 return "enabled";
1587 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1588 return "disabled";
1589 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1590 return "disabled-user";
1591 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1592 return "disabled-until-used";
1593 }
1594 return "unknown";
1595 }
1596
1597 private int runSetEnabledSetting(int state) throws RemoteException {
1598 int userId = UserHandle.USER_SYSTEM;
1599 String option = getNextOption();
1600 if (option != null && option.equals("--user")) {
1601 userId = UserHandle.parseUserArg(getNextArgRequired());
1602 }
1603
1604 String pkg = getNextArg();
1605 if (pkg == null) {
1606 getErrPrintWriter().println("Error: no package or component specified");
1607 return 1;
1608 }
1609 ComponentName cn = ComponentName.unflattenFromString(pkg);
1610 if (cn == null) {
1611 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1612 "shell:" + android.os.Process.myUid());
1613 getOutPrintWriter().println("Package " + pkg + " new state: "
1614 + enabledSettingToString(
1615 mInterface.getApplicationEnabledSetting(pkg, userId)));
1616 return 0;
1617 } else {
1618 mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1619 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1620 + enabledSettingToString(
1621 mInterface.getComponentEnabledSetting(cn, userId)));
1622 return 0;
1623 }
1624 }
1625
1626 private int runSetHiddenSetting(boolean state) throws RemoteException {
1627 int userId = UserHandle.USER_SYSTEM;
1628 String option = getNextOption();
1629 if (option != null && option.equals("--user")) {
1630 userId = UserHandle.parseUserArg(getNextArgRequired());
1631 }
1632
1633 String pkg = getNextArg();
1634 if (pkg == null) {
1635 getErrPrintWriter().println("Error: no package or component specified");
1636 return 1;
1637 }
1638 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1639 getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1640 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1641 return 0;
1642 }
1643
1644 private int runSuspend(boolean suspendedState) {
1645 final PrintWriter pw = getOutPrintWriter();
1646 int userId = UserHandle.USER_SYSTEM;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001647 String dialogMessage = null;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001648 final PersistableBundle appExtras = new PersistableBundle();
1649 final PersistableBundle launcherExtras = new PersistableBundle();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001650 String opt;
1651 while ((opt = getNextOption()) != null) {
1652 switch (opt) {
1653 case "--user":
1654 userId = UserHandle.parseUserArg(getNextArgRequired());
1655 break;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001656 case "--dialogMessage":
1657 dialogMessage = getNextArgRequired();
1658 break;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001659 case "--ael":
1660 case "--aes":
1661 case "--aed":
1662 case "--lel":
1663 case "--les":
1664 case "--led":
1665 final String key = getNextArgRequired();
1666 final String val = getNextArgRequired();
1667 if (!suspendedState) {
1668 break;
1669 }
1670 final PersistableBundle bundleToInsert =
1671 opt.startsWith("--a") ? appExtras : launcherExtras;
1672 switch (opt.charAt(4)) {
1673 case 'l':
1674 bundleToInsert.putLong(key, Long.valueOf(val));
1675 break;
1676 case 'd':
1677 bundleToInsert.putDouble(key, Double.valueOf(val));
1678 break;
1679 case 's':
1680 bundleToInsert.putString(key, val);
1681 break;
1682 }
1683 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001684 default:
1685 pw.println("Error: Unknown option: " + opt);
1686 return 1;
1687 }
1688 }
1689
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001690 final String packageName = getNextArg();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001691 if (packageName == null) {
1692 pw.println("Error: package name not specified");
1693 return 1;
1694 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001695 final String callingPackage =
1696 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001697 try {
1698 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001699 appExtras, launcherExtras, dialogMessage, callingPackage, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001700 pw.println("Package " + packageName + " new suspended state: "
1701 + mInterface.isPackageSuspendedForUser(packageName, userId));
1702 return 0;
1703 } catch (RemoteException | IllegalArgumentException e) {
1704 pw.println(e.toString());
1705 return 1;
1706 }
1707 }
1708
1709 private int runGrantRevokePermission(boolean grant) throws RemoteException {
1710 int userId = UserHandle.USER_SYSTEM;
1711
1712 String opt = null;
1713 while ((opt = getNextOption()) != null) {
1714 if (opt.equals("--user")) {
1715 userId = UserHandle.parseUserArg(getNextArgRequired());
1716 }
1717 }
1718
1719 String pkg = getNextArg();
1720 if (pkg == null) {
1721 getErrPrintWriter().println("Error: no package specified");
1722 return 1;
1723 }
1724 String perm = getNextArg();
1725 if (perm == null) {
1726 getErrPrintWriter().println("Error: no permission specified");
1727 return 1;
1728 }
1729
1730 if (grant) {
1731 mInterface.grantRuntimePermission(pkg, perm, userId);
1732 } else {
1733 mInterface.revokeRuntimePermission(pkg, perm, userId);
1734 }
1735 return 0;
1736 }
1737
1738 private int runResetPermissions() throws RemoteException {
1739 mInterface.resetRuntimePermissions();
1740 return 0;
1741 }
1742
1743 private int runSetPermissionEnforced() throws RemoteException {
1744 final String permission = getNextArg();
1745 if (permission == null) {
1746 getErrPrintWriter().println("Error: no permission specified");
1747 return 1;
1748 }
1749 final String enforcedRaw = getNextArg();
1750 if (enforcedRaw == null) {
1751 getErrPrintWriter().println("Error: no enforcement specified");
1752 return 1;
1753 }
1754 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
1755 return 0;
1756 }
1757
Jiyong Park002fdbd2017-02-13 20:50:31 +09001758 private boolean isVendorApp(String pkg) {
1759 try {
1760 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1761 return info != null && info.applicationInfo.isVendor();
1762 } catch (RemoteException e) {
1763 return false;
1764 }
1765 }
1766
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001767 private boolean isProductApp(String pkg) {
1768 try {
1769 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1770 return info != null && info.applicationInfo.isProduct();
1771 } catch (RemoteException e) {
1772 return false;
1773 }
1774 }
1775
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001776 private int runGetPrivappPermissions() {
1777 final String pkg = getNextArg();
1778 if (pkg == null) {
1779 getErrPrintWriter().println("Error: no package specified.");
1780 return 1;
1781 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001782
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001783 ArraySet<String> privAppPermissions = null;
1784 if (isVendorApp(pkg)) {
1785 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
1786 } else if (isProductApp(pkg)) {
1787 privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
1788 } else {
1789 privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
1790 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001791
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001792 getOutPrintWriter().println(privAppPermissions == null
1793 ? "{}" : privAppPermissions.toString());
1794 return 0;
1795 }
1796
1797 private int runGetPrivappDenyPermissions() {
1798 final String pkg = getNextArg();
1799 if (pkg == null) {
1800 getErrPrintWriter().println("Error: no package specified.");
1801 return 1;
1802 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001803
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001804 ArraySet<String> privAppPermissions = null;
1805 if (isVendorApp(pkg)) {
1806 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
1807 } else if (isProductApp(pkg)) {
1808 privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
1809 } else {
1810 privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
1811 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001812
1813 getOutPrintWriter().println(privAppPermissions == null
1814 ? "{}" : privAppPermissions.toString());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001815 return 0;
1816 }
1817
1818 private int runGetOemPermissions() {
1819 final String pkg = getNextArg();
1820 if (pkg == null) {
1821 getErrPrintWriter().println("Error: no package specified.");
1822 return 1;
1823 }
1824 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
1825 .getOemPermissions(pkg);
1826 if (oemPermissions == null || oemPermissions.isEmpty()) {
1827 getOutPrintWriter().println("{}");
1828 } else {
1829 oemPermissions.forEach((permission, granted) ->
1830 getOutPrintWriter().println(permission + " granted:" + granted)
1831 );
1832 }
1833 return 0;
1834 }
1835
1836 private String linkStateToString(int state) {
1837 switch (state) {
1838 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
1839 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
1840 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
1841 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
1842 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
1843 }
1844 return "Unknown link state: " + state;
1845 }
1846
1847 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
1848 private int runSetAppLink() throws RemoteException {
1849 int userId = UserHandle.USER_SYSTEM;
1850
1851 String opt;
1852 while ((opt = getNextOption()) != null) {
1853 if (opt.equals("--user")) {
1854 userId = UserHandle.parseUserArg(getNextArgRequired());
1855 } else {
1856 getErrPrintWriter().println("Error: unknown option: " + opt);
1857 return 1;
1858 }
1859 }
1860
1861 // Package name to act on; required
1862 final String pkg = getNextArg();
1863 if (pkg == null) {
1864 getErrPrintWriter().println("Error: no package specified.");
1865 return 1;
1866 }
1867
1868 // State to apply; {always|ask|never|undefined}, required
1869 final String modeString = getNextArg();
1870 if (modeString == null) {
1871 getErrPrintWriter().println("Error: no app link state specified.");
1872 return 1;
1873 }
1874
1875 final int newMode;
1876 switch (modeString.toLowerCase()) {
1877 case "undefined":
1878 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1879 break;
1880
1881 case "always":
1882 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1883 break;
1884
1885 case "ask":
1886 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1887 break;
1888
1889 case "always-ask":
1890 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
1891 break;
1892
1893 case "never":
1894 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
1895 break;
1896
1897 default:
1898 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
1899 return 1;
1900 }
1901
1902 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1903 if (info == null) {
1904 getErrPrintWriter().println("Error: package " + pkg + " not found.");
1905 return 1;
1906 }
1907
1908 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1909 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1910 return 1;
1911 }
1912
1913 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
1914 getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
1915 return 1;
1916 }
1917
1918 return 0;
1919 }
1920
1921 // pm get-app-link [--user USER_ID] PACKAGE
1922 private int runGetAppLink() throws RemoteException {
1923 int userId = UserHandle.USER_SYSTEM;
1924
1925 String opt;
1926 while ((opt = getNextOption()) != null) {
1927 if (opt.equals("--user")) {
1928 userId = UserHandle.parseUserArg(getNextArgRequired());
1929 } else {
1930 getErrPrintWriter().println("Error: unknown option: " + opt);
1931 return 1;
1932 }
1933 }
1934
1935 // Package name to act on; required
1936 final String pkg = getNextArg();
1937 if (pkg == null) {
1938 getErrPrintWriter().println("Error: no package specified.");
1939 return 1;
1940 }
1941
1942 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1943 if (info == null) {
1944 getErrPrintWriter().println("Error: package " + pkg + " not found.");
1945 return 1;
1946 }
1947
1948 if ((info.applicationInfo.privateFlags
1949 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1950 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1951 return 1;
1952 }
1953
1954 getOutPrintWriter().println(linkStateToString(
1955 mInterface.getIntentVerificationStatus(pkg, userId)));
1956
1957 return 0;
1958 }
1959
1960 private int runTrimCaches() throws RemoteException {
1961 String size = getNextArg();
1962 if (size == null) {
1963 getErrPrintWriter().println("Error: no size specified");
1964 return 1;
1965 }
1966 long multiplier = 1;
1967 int len = size.length();
1968 char c = size.charAt(len - 1);
1969 if (c < '0' || c > '9') {
1970 if (c == 'K' || c == 'k') {
1971 multiplier = 1024L;
1972 } else if (c == 'M' || c == 'm') {
1973 multiplier = 1024L*1024L;
1974 } else if (c == 'G' || c == 'g') {
1975 multiplier = 1024L*1024L*1024L;
1976 } else {
1977 getErrPrintWriter().println("Invalid suffix: " + c);
1978 return 1;
1979 }
1980 size = size.substring(0, len-1);
1981 }
1982 long sizeVal;
1983 try {
1984 sizeVal = Long.parseLong(size) * multiplier;
1985 } catch (NumberFormatException e) {
1986 getErrPrintWriter().println("Error: expected number at: " + size);
1987 return 1;
1988 }
1989 String volumeUuid = getNextArg();
1990 if ("internal".equals(volumeUuid)) {
1991 volumeUuid = null;
1992 }
1993 ClearDataObserver obs = new ClearDataObserver();
1994 mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
1995 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
1996 synchronized (obs) {
1997 while (!obs.finished) {
1998 try {
1999 obs.wait();
2000 } catch (InterruptedException e) {
2001 }
2002 }
2003 }
2004 return 0;
2005 }
2006
2007 private static boolean isNumber(String s) {
2008 try {
2009 Integer.parseInt(s);
2010 } catch (NumberFormatException nfe) {
2011 return false;
2012 }
2013 return true;
2014 }
2015
2016 public int runCreateUser() throws RemoteException {
2017 String name;
2018 int userId = -1;
2019 int flags = 0;
2020 String opt;
2021 while ((opt = getNextOption()) != null) {
2022 if ("--profileOf".equals(opt)) {
2023 userId = UserHandle.parseUserArg(getNextArgRequired());
2024 } else if ("--managed".equals(opt)) {
2025 flags |= UserInfo.FLAG_MANAGED_PROFILE;
2026 } else if ("--restricted".equals(opt)) {
2027 flags |= UserInfo.FLAG_RESTRICTED;
2028 } else if ("--ephemeral".equals(opt)) {
2029 flags |= UserInfo.FLAG_EPHEMERAL;
2030 } else if ("--guest".equals(opt)) {
2031 flags |= UserInfo.FLAG_GUEST;
2032 } else if ("--demo".equals(opt)) {
2033 flags |= UserInfo.FLAG_DEMO;
2034 } else {
2035 getErrPrintWriter().println("Error: unknown option " + opt);
2036 return 1;
2037 }
2038 }
2039 String arg = getNextArg();
2040 if (arg == null) {
2041 getErrPrintWriter().println("Error: no user name specified.");
2042 return 1;
2043 }
2044 name = arg;
2045 UserInfo info;
2046 IUserManager um = IUserManager.Stub.asInterface(
2047 ServiceManager.getService(Context.USER_SERVICE));
2048 IAccountManager accm = IAccountManager.Stub.asInterface(
2049 ServiceManager.getService(Context.ACCOUNT_SERVICE));
2050 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
2051 // In non-split user mode, userId can only be SYSTEM
2052 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
2053 info = um.createRestrictedProfile(name, parentUserId);
2054 accm.addSharedAccountsFromParentUser(parentUserId, userId,
2055 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
2056 } else if (userId < 0) {
2057 info = um.createUser(name, flags);
2058 } else {
2059 info = um.createProfileForUser(name, flags, userId, null);
2060 }
2061
2062 if (info != null) {
2063 getOutPrintWriter().println("Success: created user id " + info.id);
2064 return 0;
2065 } else {
2066 getErrPrintWriter().println("Error: couldn't create User.");
2067 return 1;
2068 }
2069 }
2070
2071 public int runRemoveUser() throws RemoteException {
2072 int userId;
2073 String arg = getNextArg();
2074 if (arg == null) {
2075 getErrPrintWriter().println("Error: no user id specified.");
2076 return 1;
2077 }
2078 userId = UserHandle.parseUserArg(arg);
2079 IUserManager um = IUserManager.Stub.asInterface(
2080 ServiceManager.getService(Context.USER_SERVICE));
2081 if (um.removeUser(userId)) {
2082 getOutPrintWriter().println("Success: removed user");
2083 return 0;
2084 } else {
2085 getErrPrintWriter().println("Error: couldn't remove user id " + userId);
2086 return 1;
2087 }
2088 }
2089
2090 public int runSetUserRestriction() throws RemoteException {
2091 int userId = UserHandle.USER_SYSTEM;
2092 String opt = getNextOption();
2093 if (opt != null && "--user".equals(opt)) {
2094 userId = UserHandle.parseUserArg(getNextArgRequired());
2095 }
2096
2097 String restriction = getNextArg();
2098 String arg = getNextArg();
2099 boolean value;
2100 if ("1".equals(arg)) {
2101 value = true;
2102 } else if ("0".equals(arg)) {
2103 value = false;
2104 } else {
2105 getErrPrintWriter().println("Error: valid value not specified");
2106 return 1;
2107 }
2108 IUserManager um = IUserManager.Stub.asInterface(
2109 ServiceManager.getService(Context.USER_SERVICE));
2110 um.setUserRestriction(restriction, value, userId);
2111 return 0;
2112 }
2113
2114 public int runGetMaxUsers() {
2115 getOutPrintWriter().println("Maximum supported users: "
2116 + UserManager.getMaxSupportedUsers());
2117 return 0;
2118 }
2119
Alex Chauc12189b2018-01-16 15:01:15 +00002120 public int runGetMaxRunningUsers() {
2121 ActivityManagerInternal activityManagerInternal =
2122 LocalServices.getService(ActivityManagerInternal.class);
2123 getOutPrintWriter().println("Maximum supported running users: "
2124 + activityManagerInternal.getMaxRunningUsers());
2125 return 0;
2126 }
2127
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002128 private static class InstallParams {
2129 SessionParams sessionParams;
2130 String installerPackageName;
2131 int userId = UserHandle.USER_ALL;
2132 }
2133
2134 private InstallParams makeInstallParams() {
2135 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
2136 final InstallParams params = new InstallParams();
2137 params.sessionParams = sessionParams;
2138 String opt;
Patrick Baumanna9333492017-11-28 15:23:49 -08002139 boolean replaceExisting = true;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002140 while ((opt = getNextOption()) != null) {
2141 switch (opt) {
2142 case "-l":
2143 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
2144 break;
Patrick Baumanna9333492017-11-28 15:23:49 -08002145 case "-r": // ignore
2146 break;
2147 case "-R":
2148 replaceExisting = false;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002149 break;
2150 case "-i":
2151 params.installerPackageName = getNextArg();
2152 if (params.installerPackageName == null) {
2153 throw new IllegalArgumentException("Missing installer package");
2154 }
2155 break;
2156 case "-t":
2157 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
2158 break;
2159 case "-s":
2160 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL;
2161 break;
2162 case "-f":
2163 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
2164 break;
2165 case "-d":
2166 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
2167 break;
2168 case "-g":
2169 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
2170 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002171 case "--dont-kill":
2172 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
2173 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002174 case "--originating-uri":
2175 sessionParams.originatingUri = Uri.parse(getNextArg());
2176 break;
2177 case "--referrer":
2178 sessionParams.referrerUri = Uri.parse(getNextArg());
2179 break;
2180 case "-p":
2181 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
2182 sessionParams.appPackageName = getNextArg();
2183 if (sessionParams.appPackageName == null) {
2184 throw new IllegalArgumentException("Missing inherit package name");
2185 }
2186 break;
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002187 case "--pkg":
2188 sessionParams.appPackageName = getNextArg();
2189 if (sessionParams.appPackageName == null) {
2190 throw new IllegalArgumentException("Missing package name");
2191 }
2192 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002193 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002194 final long sizeBytes = Long.parseLong(getNextArg());
2195 if (sizeBytes <= 0) {
2196 throw new IllegalArgumentException("Size must be positive");
2197 }
2198 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002199 break;
2200 case "--abi":
2201 sessionParams.abiOverride = checkAbiArgument(getNextArg());
2202 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08002203 case "--ephemeral":
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002204 case "--instant":
Todd Kennedybe0b8892017-02-15 14:13:52 -08002205 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08002206 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08002207 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08002208 case "--full":
2209 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
2210 break;
Todd Kennedy78a72502017-07-19 12:49:30 -07002211 case "--preload":
2212 sessionParams.setInstallAsVirtualPreload();
2213 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002214 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002215 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002216 break;
2217 case "--install-location":
2218 sessionParams.installLocation = Integer.parseInt(getNextArg());
2219 break;
2220 case "--force-uuid":
2221 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
2222 sessionParams.volumeUuid = getNextArg();
2223 if ("internal".equals(sessionParams.volumeUuid)) {
2224 sessionParams.volumeUuid = null;
2225 }
2226 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002227 case "--force-sdk":
2228 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK;
2229 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002230 default:
2231 throw new IllegalArgumentException("Unknown option " + opt);
2232 }
Patrick Baumanna9333492017-11-28 15:23:49 -08002233 if (replaceExisting) {
2234 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
2235 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002236 }
2237 return params;
2238 }
2239
Makoto Onuki4828a592016-03-15 18:06:57 -07002240 private int runSetHomeActivity() {
2241 final PrintWriter pw = getOutPrintWriter();
2242 int userId = UserHandle.USER_SYSTEM;
2243 String opt;
2244 while ((opt = getNextOption()) != null) {
2245 switch (opt) {
2246 case "--user":
2247 userId = UserHandle.parseUserArg(getNextArgRequired());
2248 break;
2249 default:
2250 pw.println("Error: Unknown option: " + opt);
2251 return 1;
2252 }
2253 }
2254
2255 String component = getNextArg();
2256 ComponentName componentName =
2257 component != null ? ComponentName.unflattenFromString(component) : null;
2258
2259 if (componentName == null) {
2260 pw.println("Error: component name not specified or invalid");
2261 return 1;
2262 }
2263
2264 try {
2265 mInterface.setHomeActivity(componentName, userId);
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002266 pw.println("Success");
Makoto Onuki4828a592016-03-15 18:06:57 -07002267 return 0;
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002268 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07002269 pw.println(e.toString());
2270 return 1;
2271 }
2272 }
2273
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002274 private int runSetInstaller() throws RemoteException {
2275 final String targetPackage = getNextArg();
2276 final String installerPackageName = getNextArg();
Fyodor Kupolov51245c72016-12-01 11:34:10 -08002277
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002278 if (targetPackage == null || installerPackageName == null) {
2279 getErrPrintWriter().println("Must provide both target and installer package names");
Todd Kennedy74629e32017-08-15 14:48:07 -07002280 return 1;
2281 }
Todd Kennedy74629e32017-08-15 14:48:07 -07002282
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002283 mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2284 getOutPrintWriter().println("Success");
Svet Ganov087dce22017-09-07 15:42:16 -07002285 return 0;
2286 }
2287
Todd Kennedy0a3f0812017-05-08 14:43:15 -07002288 private int runGetInstantAppResolver() {
2289 final PrintWriter pw = getOutPrintWriter();
2290 try {
2291 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2292 if (instantAppsResolver == null) {
2293 return 1;
2294 }
2295 pw.println(instantAppsResolver.flattenToString());
2296 return 0;
2297 } catch (Exception e) {
2298 pw.println(e.toString());
2299 return 1;
2300 }
2301 }
2302
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09002303 private int runHasFeature() {
2304 final PrintWriter err = getErrPrintWriter();
2305 final String featureName = getNextArg();
2306 if (featureName == null) {
2307 err.println("Error: expected FEATURE name");
2308 return 1;
2309 }
2310 final String versionString = getNextArg();
2311 try {
2312 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2313 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2314 getOutPrintWriter().println(hasFeature);
2315 return hasFeature ? 0 : 1;
2316 } catch (NumberFormatException e) {
2317 err.println("Error: illegal version number " + versionString);
2318 return 1;
2319 } catch (RemoteException e) {
2320 err.println(e.toString());
2321 return 1;
2322 }
2323 }
2324
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002325 private int runDump() {
2326 String pkg = getNextArg();
2327 if (pkg == null) {
2328 getErrPrintWriter().println("Error: no package specified");
2329 return 1;
2330 }
2331 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2332 return 0;
2333 }
2334
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002335 private int runSetHarmfulAppWarning() throws RemoteException {
2336 int userId = UserHandle.USER_CURRENT;
2337
2338 String opt;
2339 while ((opt = getNextOption()) != null) {
2340 if (opt.equals("--user")) {
2341 userId = UserHandle.parseUserArg(getNextArgRequired());
2342 } else {
2343 getErrPrintWriter().println("Error: Unknown option: " + opt);
2344 return -1;
2345 }
2346 }
2347
2348 userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning");
2349
2350 final String packageName = getNextArgRequired();
2351 final String warning = getNextArg();
2352
2353 mInterface.setHarmfulAppWarning(packageName, warning, userId);
2354
2355 return 0;
2356 }
2357
Ben Gruver9ef60092018-01-10 11:32:30 -08002358 private int runGetHarmfulAppWarning() throws RemoteException {
2359 int userId = UserHandle.USER_CURRENT;
2360
2361 String opt;
2362 while ((opt = getNextOption()) != null) {
2363 if (opt.equals("--user")) {
2364 userId = UserHandle.parseUserArg(getNextArgRequired());
2365 } else {
2366 getErrPrintWriter().println("Error: Unknown option: " + opt);
2367 return -1;
2368 }
2369 }
2370
2371 userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning");
2372
2373 final String packageName = getNextArgRequired();
2374 final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId);
2375 if (!TextUtils.isEmpty(warning)) {
2376 getOutPrintWriter().println(warning);
2377 return 0;
2378 } else {
2379 return 1;
2380 }
2381 }
2382
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002383 private static String checkAbiArgument(String abi) {
2384 if (TextUtils.isEmpty(abi)) {
2385 throw new IllegalArgumentException("Missing ABI argument");
2386 }
2387
2388 if ("-".equals(abi)) {
2389 return abi;
2390 }
2391
2392 final String[] supportedAbis = Build.SUPPORTED_ABIS;
2393 for (String supportedAbi : supportedAbis) {
2394 if (supportedAbi.equals(abi)) {
2395 return abi;
2396 }
2397 }
2398
2399 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2400 }
2401
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002402 private int translateUserId(int userId, boolean allowAll, String logContext) {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002403 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002404 userId, allowAll, true, logContext, "pm command");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002405 }
2406
2407 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2408 throws RemoteException {
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002409 userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002410 if (userId == UserHandle.USER_ALL) {
2411 userId = UserHandle.USER_SYSTEM;
2412 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2413 }
2414
2415 final int sessionId = mInterface.getPackageInstaller()
2416 .createSession(params, installerPackageName, userId);
2417 return sessionId;
2418 }
2419
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002420 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002421 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002422 final PrintWriter pw = getOutPrintWriter();
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002423 final ParcelFileDescriptor fd;
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002424 if (STDIN_PATH.equals(inPath)) {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002425 fd = new ParcelFileDescriptor(getInFileDescriptor());
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002426 } else if (inPath != null) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002427 fd = openFileForSystem(inPath, "r");
2428 if (fd == null) {
2429 return -1;
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002430 }
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002431 sizeBytes = fd.getStatSize();
2432 if (sizeBytes < 0) {
2433 getErrPrintWriter().println("Unable to get size of: " + inPath);
2434 return -1;
2435 }
2436 } else {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002437 fd = new ParcelFileDescriptor(getInFileDescriptor());
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002438 }
Todd Kennedy63cc8b02016-09-22 13:25:46 -07002439 if (sizeBytes <= 0) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002440 getErrPrintWriter().println("Error: must specify a APK size");
Todd Kennedy63cc8b02016-09-22 13:25:46 -07002441 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002442 }
2443
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002444 PackageInstaller.Session session = null;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002445 try {
2446 session = new PackageInstaller.Session(
2447 mInterface.getPackageInstaller().openSession(sessionId));
Jeff Sharkey0451de62018-02-02 11:27:21 -07002448 session.write(splitName, 0, sizeBytes, fd);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002449
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002450 if (logSuccess) {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002451 pw.println("Success: streamed " + sizeBytes + " bytes");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002452 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002453 return 0;
2454 } catch (IOException e) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002455 getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002456 return 1;
2457 } finally {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002458 IoUtils.closeQuietly(session);
2459 }
2460 }
2461
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002462 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2463 throws RemoteException {
2464 final PrintWriter pw = getOutPrintWriter();
2465 PackageInstaller.Session session = null;
2466 try {
2467 session = new PackageInstaller.Session(
2468 mInterface.getPackageInstaller().openSession(sessionId));
2469 session.removeSplit(splitName);
2470
2471 if (logSuccess) {
2472 pw.println("Success");
2473 }
2474 return 0;
2475 } catch (IOException e) {
2476 pw.println("Error: failed to remove split; " + e.getMessage());
2477 return 1;
2478 } finally {
2479 IoUtils.closeQuietly(session);
2480 }
2481 }
2482
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002483 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002484 final PrintWriter pw = getOutPrintWriter();
2485 PackageInstaller.Session session = null;
2486 try {
2487 session = new PackageInstaller.Session(
2488 mInterface.getPackageInstaller().openSession(sessionId));
2489
Calin Juravle3fc56c32017-12-11 18:26:13 -08002490 // Sanity check that all .dm files match an apk.
2491 // (The installer does not support standalone .dm files and will not process them.)
2492 try {
2493 DexMetadataHelper.validateDexPaths(session.getNames());
2494 } catch (IllegalStateException | IOException e) {
2495 pw.println("Warning [Could not validate the dex paths: " + e.getMessage() + "]");
2496 }
2497
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002498 final LocalIntentReceiver receiver = new LocalIntentReceiver();
2499 session.commit(receiver.getIntentSender());
2500
2501 final Intent result = receiver.getResult();
2502 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2503 PackageInstaller.STATUS_FAILURE);
2504 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002505 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07002506 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002507 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002508 } else {
2509 pw.println("Failure ["
2510 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002511 }
2512 return status;
2513 } finally {
2514 IoUtils.closeQuietly(session);
2515 }
2516 }
2517
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002518 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002519 final PrintWriter pw = getOutPrintWriter();
2520 PackageInstaller.Session session = null;
2521 try {
2522 session = new PackageInstaller.Session(
2523 mInterface.getPackageInstaller().openSession(sessionId));
2524 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002525 if (logSuccess) {
2526 pw.println("Success");
2527 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002528 return 0;
2529 } finally {
2530 IoUtils.closeQuietly(session);
2531 }
2532 }
2533
Todd Kennedy60459ab2015-10-30 11:32:16 -07002534 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2535 boolean summary, int startProtectionLevel, int endProtectionLevel)
2536 throws RemoteException {
2537 final PrintWriter pw = getOutPrintWriter();
2538 final int groupCount = groupList.size();
2539 for (int i = 0; i < groupCount; i++) {
2540 String groupName = groupList.get(i);
2541 String prefix = "";
2542 if (groups) {
2543 if (i > 0) {
2544 pw.println("");
2545 }
2546 if (groupName != null) {
2547 PermissionGroupInfo pgi =
2548 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2549 if (summary) {
2550 Resources res = getResources(pgi);
2551 if (res != null) {
2552 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2553 } else {
2554 pw.print(pgi.name + ": ");
2555
2556 }
2557 } else {
2558 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2559 if (labels) {
2560 pw.println(" package:" + pgi.packageName);
2561 Resources res = getResources(pgi);
2562 if (res != null) {
2563 pw.println(" label:"
2564 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
2565 pw.println(" description:"
2566 + loadText(pgi, pgi.descriptionRes,
2567 pgi.nonLocalizedDescription));
2568 }
2569 }
2570 }
2571 } else {
2572 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
2573 }
2574 prefix = " ";
2575 }
2576 List<PermissionInfo> ps =
Jeff Sharkeyd5896632016-03-04 16:16:00 -07002577 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07002578 final int count = ps.size();
2579 boolean first = true;
2580 for (int p = 0 ; p < count ; p++) {
2581 PermissionInfo pi = ps.get(p);
2582 if (groups && groupName == null && pi.group != null) {
2583 continue;
2584 }
2585 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
2586 if (base < startProtectionLevel
2587 || base > endProtectionLevel) {
2588 continue;
2589 }
2590 if (summary) {
2591 if (first) {
2592 first = false;
2593 } else {
2594 pw.print(", ");
2595 }
2596 Resources res = getResources(pi);
2597 if (res != null) {
2598 pw.print(loadText(pi, pi.labelRes,
2599 pi.nonLocalizedLabel));
2600 } else {
2601 pw.print(pi.name);
2602 }
2603 } else {
2604 pw.println(prefix + (labels ? "+ " : "")
2605 + "permission:" + pi.name);
2606 if (labels) {
2607 pw.println(prefix + " package:" + pi.packageName);
2608 Resources res = getResources(pi);
2609 if (res != null) {
2610 pw.println(prefix + " label:"
2611 + loadText(pi, pi.labelRes,
2612 pi.nonLocalizedLabel));
2613 pw.println(prefix + " description:"
2614 + loadText(pi, pi.descriptionRes,
2615 pi.nonLocalizedDescription));
2616 }
2617 pw.println(prefix + " protectionLevel:"
2618 + PermissionInfo.protectionToString(pi.protectionLevel));
2619 }
2620 }
2621 }
2622
2623 if (summary) {
2624 pw.println("");
2625 }
2626 }
2627 }
2628
2629 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
2630 throws RemoteException {
2631 if (nonLocalized != null) {
2632 return nonLocalized.toString();
2633 }
2634 if (res != 0) {
2635 Resources r = getResources(pii);
2636 if (r != null) {
2637 try {
2638 return r.getString(res);
2639 } catch (Resources.NotFoundException e) {
2640 }
2641 }
2642 }
2643 return null;
2644 }
2645
2646 private Resources getResources(PackageItemInfo pii) throws RemoteException {
2647 Resources res = mResourceCache.get(pii.packageName);
2648 if (res != null) return res;
2649
2650 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
2651 AssetManager am = new AssetManager();
2652 am.addAssetPath(ai.publicSourceDir);
2653 res = new Resources(am, null, null);
2654 mResourceCache.put(pii.packageName, res);
2655 return res;
2656 }
2657
2658 @Override
2659 public void onHelp() {
2660 final PrintWriter pw = getOutPrintWriter();
2661 pw.println("Package manager (package) commands:");
2662 pw.println(" help");
2663 pw.println(" Print this help text.");
2664 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002665 pw.println(" path [--user USER_ID] PACKAGE");
2666 pw.println(" Print the path to the .apk of the given PACKAGE.");
2667 pw.println("");
2668 pw.println(" dump PACKAGE");
2669 pw.println(" Print various system state associated with the given PACKAGE.");
2670 pw.println("");
2671 pw.println(" list features");
2672 pw.println(" Prints all features of the system.");
2673 pw.println("");
2674 pw.println(" has-feature FEATURE_NAME [version]");
2675 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,");
2676 pw.println(" otherwise prints false and returns exit status 1");
2677 pw.println("");
2678 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
2679 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
2680 pw.println(" Options:");
2681 pw.println(" -f: dump the name of the .apk file containing the test package");
2682 pw.println("");
2683 pw.println(" list libraries");
2684 pw.println(" Prints all system libraries.");
2685 pw.println("");
2686 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
2687 pw.println(" [--uid UID] [--user USER_ID] [FILTER]");
2688 pw.println(" Prints all packages; optionally only those whose name contains");
2689 pw.println(" the text in FILTER. Options are:");
2690 pw.println(" -f: see their associated file");
2691 pw.println(" -d: filter to only show disabled packages");
2692 pw.println(" -e: filter to only show enabled packages");
2693 pw.println(" -s: filter to only show system packages");
2694 pw.println(" -3: filter to only show third party packages");
2695 pw.println(" -i: see the installer for the packages");
2696 pw.println(" -l: ignored (used for compatibility with older releases)");
2697 pw.println(" -U: also show the package UID");
2698 pw.println(" -u: also include uninstalled packages");
2699 pw.println(" --uid UID: filter to only show packages with the given UID");
2700 pw.println(" --user USER_ID: only list packages belonging to the given user");
2701 pw.println("");
2702 pw.println(" list permission-groups");
2703 pw.println(" Prints all known permission groups.");
2704 pw.println("");
2705 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
2706 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:");
2707 pw.println(" -g: organize by group");
2708 pw.println(" -f: print all information");
2709 pw.println(" -s: short summary");
2710 pw.println(" -d: only list dangerous permissions");
2711 pw.println(" -u: list only the permissions users will see");
2712 pw.println("");
2713 pw.println(" resolve-activity [--brief] [--components] [--user USER_ID] INTENT");
2714 pw.println(" Prints the activity that resolves to the given INTENT.");
2715 pw.println("");
2716 pw.println(" query-activities [--brief] [--components] [--user USER_ID] INTENT");
2717 pw.println(" Prints all activities that can handle the given INTENT.");
2718 pw.println("");
2719 pw.println(" query-services [--brief] [--components] [--user USER_ID] INTENT");
2720 pw.println(" Prints all services that can handle the given INTENT.");
2721 pw.println("");
2722 pw.println(" query-receivers [--brief] [--components] [--user USER_ID] INTENT");
2723 pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
2724 pw.println("");
2725 pw.println(" install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2726 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
2727 pw.println(" [--originating-uri URI] [---referrer URI]");
2728 pw.println(" [--abi ABI_NAME] [--force-sdk]");
2729 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
2730 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [PATH|-]");
2731 pw.println(" Install an application. Must provide the apk data to install, either as a");
2732 pw.println(" file path or '-' to read from stdin. Options are:");
2733 pw.println(" -l: forward lock application");
Patrick Baumanna9333492017-11-28 15:23:49 -08002734 pw.println(" -R: disallow replacement of existing application");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002735 pw.println(" -t: allow test packages");
2736 pw.println(" -i: specify package name of installer owning the app");
2737 pw.println(" -s: install application on sdcard");
2738 pw.println(" -f: install application on internal flash");
2739 pw.println(" -d: allow version code downgrade (debuggable packages only)");
2740 pw.println(" -p: partial application install (new split on top of existing pkg)");
2741 pw.println(" -g: grant all runtime permissions");
2742 pw.println(" -S: size in bytes of package, required for stdin");
2743 pw.println(" --user: install under the given user.");
2744 pw.println(" --dont-kill: installing a new feature split, don't kill running app");
2745 pw.println(" --originating-uri: set URI where app was downloaded from");
2746 pw.println(" --referrer: set URI that instigated the install of the app");
2747 pw.println(" --pkg: specify expected package name of app being installed");
2748 pw.println(" --abi: override the default ABI of the platform");
2749 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app");
2750 pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
2751 pw.println(" --install-location: force the install location:");
2752 pw.println(" 0=auto, 1=internal only, 2=prefer external");
2753 pw.println(" --force-uuid: force install on to disk volume with given UUID");
2754 pw.println(" --force-sdk: allow install even when existing app targets platform");
2755 pw.println(" codename but new one targets a final API level");
2756 pw.println("");
2757 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2758 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
2759 pw.println(" [--originating-uri URI] [---referrer URI]");
2760 pw.println(" [--abi ABI_NAME] [--force-sdk]");
2761 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
2762 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
2763 pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
2764 pw.println(" to push data into the session, and \"install-commit\" to finish.");
2765 pw.println("");
2766 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
2767 pw.println(" Write an apk into the given install session. If the path is '-', data");
2768 pw.println(" will be read from stdin. Options are:");
2769 pw.println(" -S: size in bytes of package, required for stdin");
2770 pw.println("");
2771 pw.println(" install-commit SESSION_ID");
2772 pw.println(" Commit the given active install session, installing the app.");
2773 pw.println("");
2774 pw.println(" install-abandon SESSION_ID");
2775 pw.println(" Delete the given active install session.");
2776 pw.println("");
2777 pw.println(" set-install-location LOCATION");
2778 pw.println(" Changes the default install location. NOTE this is only intended for debugging;");
2779 pw.println(" using this can cause applications to break and other undersireable behavior.");
2780 pw.println(" LOCATION is one of:");
2781 pw.println(" 0 [auto]: Let system decide the best location");
2782 pw.println(" 1 [internal]: Install on internal device storage");
2783 pw.println(" 2 [external]: Install on external media");
2784 pw.println("");
2785 pw.println(" get-install-location");
2786 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location.");
2787 pw.println("");
2788 pw.println(" move-package PACKAGE [internal|UUID]");
2789 pw.println("");
2790 pw.println(" move-primary-storage [internal|UUID]");
2791 pw.println("");
2792 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
2793 pw.println(" Remove the given package name from the system. May remove an entire app");
2794 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
2795 pw.println(" given app. Options are:");
2796 pw.println(" -k: keep the data and cache directories around after package removal.");
2797 pw.println(" --user: remove the app from the given user.");
2798 pw.println(" --versionCode: only uninstall if the app has the given version code.");
2799 pw.println("");
2800 pw.println(" clear [--user USER_ID] PACKAGE");
2801 pw.println(" Deletes all data associated with a package.");
2802 pw.println("");
2803 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT");
2804 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT");
2805 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
2806 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
2807 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
2808 pw.println(" These commands change the enabled state of a given package or");
2809 pw.println(" component (written as \"package/class\").");
2810 pw.println("");
2811 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT");
2812 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
2813 pw.println("");
2814 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
2815 pw.println(" Suspends the specified package (as user).");
2816 pw.println("");
2817 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
2818 pw.println(" Unsuspends the specified package (as user).");
2819 pw.println("");
2820 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
2821 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
2822 pw.println(" These commands either grant or revoke permissions to apps. The permissions");
2823 pw.println(" must be declared as used in the app's manifest, be runtime permissions");
2824 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
2825 pw.println("");
2826 pw.println(" reset-permissions");
2827 pw.println(" Revert all runtime permissions to their default state.");
2828 pw.println("");
2829 pw.println(" set-permission-enforced PERMISSION [true|false]");
2830 pw.println("");
2831 pw.println(" get-privapp-permissions TARGET-PACKAGE");
2832 pw.println(" Prints all privileged permissions for a package.");
2833 pw.println("");
2834 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE");
2835 pw.println(" Prints all privileged permissions that are denied for a package.");
2836 pw.println("");
2837 pw.println(" get-oem-permissions TARGET-PACKAGE");
2838 pw.println(" Prints all OEM permissions for a package.");
2839 pw.println("");
2840 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
2841 pw.println(" get-app-link [--user USER_ID] PACKAGE");
2842 pw.println("");
2843 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
2844 pw.println(" Trim cache files to reach the given free space.");
2845 pw.println("");
2846 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
2847 pw.println(" [--guest] USER_NAME");
2848 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
2849 pw.println(" of the user.");
2850 pw.println("");
2851 pw.println(" remove-user USER_ID");
2852 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data");
2853 pw.println(" associated with that user");
2854 pw.println("");
2855 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE");
2856 pw.println("");
2857 pw.println(" get-max-users");
2858 pw.println("");
Alex Chauc12189b2018-01-16 15:01:15 +00002859 pw.println(" get-max-running-users");
2860 pw.println("");
Calin Juravleb6f844d2017-07-17 15:23:21 -07002861 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
Richard Uhler568a9692016-05-03 16:02:52 -07002862 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002863 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
David Brazdil990fb6b2016-03-01 10:02:27 +00002864 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00002865 pw.println(" -c: clear profile data before compiling");
2866 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00002867 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07002868 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01002869 pw.println(" assume-verified");
2870 pw.println(" extract");
2871 pw.println(" verify");
2872 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07002873 pw.println(" space-profile");
2874 pw.println(" space");
2875 pw.println(" speed-profile");
2876 pw.println(" speed");
2877 pw.println(" everything");
2878 pw.println(" -r: select compilation reason");
2879 pw.println(" REASON is one of:");
2880 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
2881 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
2882 }
David Brazdilcf046952016-03-08 16:40:20 +00002883 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07002884 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08002885 pw.println(" --secondary-dex: compile app secondary dex files");
Calin Juravleb6f844d2017-07-17 15:23:21 -07002886 pw.println(" --split SPLIT: compile only the given split name");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002887 pw.println("");
2888 pw.println(" force-dex-opt PACKAGE");
2889 pw.println(" Force immediate execution of dex opt for the given PACKAGE.");
2890 pw.println("");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08002891 pw.println(" bg-dexopt-job");
2892 pw.println(" Execute the background optimizations immediately.");
2893 pw.println(" Note that the command only runs the background optimizer logic. It may");
2894 pw.println(" overlap with the actual job but the job scheduler will not be able to");
2895 pw.println(" cancel it. It will also run even if the device is not in the idle");
2896 pw.println(" maintenance mode.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002897 pw.println("");
Calin Juravle1aa5f882017-01-25 01:05:50 -08002898 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
2899 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002900 pw.println("");
David Sehrcae13b02016-06-07 09:11:27 -07002901 pw.println(" dump-profiles TARGET-PACKAGE");
2902 pw.println(" Dumps method/class profile files to");
Calin Juravle21216c62018-05-04 17:35:29 -07002903 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt");
2904 pw.println("");
2905 pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]");
2906 pw.println(" Take a snapshot of the package profiles to");
2907 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
2908 + "TARGET-PACKAGE[-code-path].prof");
2909 pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002910 pw.println("");
Makoto Onuki4828a592016-03-15 18:06:57 -07002911 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002912 pw.println(" Set the default home activity (aka launcher).");
2913 pw.println("");
2914 pw.println(" set-installer PACKAGE INSTALLER");
2915 pw.println(" Set installer package name");
2916 pw.println("");
2917 pw.println(" get-instantapp-resolver");
2918 pw.println(" Return the name of the component that is the current instant app installer.");
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002919 pw.println("");
2920 pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
2921 pw.println(" Mark the app as harmful with the given warning message.");
Ben Gruver9ef60092018-01-10 11:32:30 -08002922 pw.println("");
2923 pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
2924 pw.println(" Return the harmful app warning message for the given app, if present");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002925 pw.println();
Patrick Baumanna980e142018-02-12 11:45:23 -08002926 pw.println(" uninstall-system-updates");
2927 pw.println(" Remove updates to all system applications and fall back to their /system " +
2928 "version.");
2929 pw.println();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002930 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07002931 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002932
2933 private static class LocalIntentReceiver {
wangmingming155414292018-04-10 09:35:25 +08002934 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002935
2936 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
2937 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07002938 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002939 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
2940 try {
2941 mResult.offer(intent, 5, TimeUnit.SECONDS);
2942 } catch (InterruptedException e) {
2943 throw new RuntimeException(e);
2944 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002945 }
2946 };
2947
2948 public IntentSender getIntentSender() {
2949 return new IntentSender((IIntentSender) mLocalSender);
2950 }
2951
2952 public Intent getResult() {
2953 try {
2954 return mResult.take();
2955 } catch (InterruptedException e) {
2956 throw new RuntimeException(e);
2957 }
2958 }
2959 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07002960}