blob: 361416adc4efc10bbd7aeb6a668866a3ea113ae6 [file] [log] [blame]
Todd Kennedy72cfcd02015-11-03 17:08:55 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Todd Kennedy60459ab2015-10-30 11:32:16 -070017package com.android.server.pm;
18
Jeff Sharkey0451de62018-02-02 11:27:21 -070019import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
20import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
21import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
22import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
23import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
24
Dianne Hackbornc81983a2017-10-20 16:16:32 -070025import android.accounts.IAccountManager;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080026import android.app.ActivityManager;
Alex Chauc12189b2018-01-16 15:01:15 +000027import android.app.ActivityManagerInternal;
Todd Kennedy60459ab2015-10-30 11:32:16 -070028import android.content.ComponentName;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070029import android.content.Context;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080030import android.content.IIntentReceiver;
31import android.content.IIntentSender;
32import android.content.Intent;
33import android.content.IntentSender;
Todd Kennedy60459ab2015-10-30 11:32:16 -070034import android.content.pm.ApplicationInfo;
35import android.content.pm.FeatureInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070036import android.content.pm.IPackageDataObserver;
Patrick Baumanna980e142018-02-12 11:45:23 -080037import android.content.pm.IPackageInstaller;
Todd Kennedy60459ab2015-10-30 11:32:16 -070038import android.content.pm.IPackageManager;
39import android.content.pm.InstrumentationInfo;
40import android.content.pm.PackageInfo;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080041import android.content.pm.PackageInstaller;
Jeff Sharkey0451de62018-02-02 11:27:21 -070042import android.content.pm.PackageInstaller.SessionParams;
Todd Kennedy60459ab2015-10-30 11:32:16 -070043import android.content.pm.PackageItemInfo;
44import android.content.pm.PackageManager;
Jeff Sharkey0451de62018-02-02 11:27:21 -070045import android.content.pm.PackageManager.NameNotFoundException;
Shunta Sato4f26cb52016-06-28 09:29:19 +090046import android.content.pm.PackageParser;
47import android.content.pm.PackageParser.ApkLite;
48import android.content.pm.PackageParser.PackageLite;
49import android.content.pm.PackageParser.PackageParserException;
Todd Kennedy60459ab2015-10-30 11:32:16 -070050import android.content.pm.ParceledListSlice;
51import android.content.pm.PermissionGroupInfo;
52import android.content.pm.PermissionInfo;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080053import android.content.pm.ResolveInfo;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070054import android.content.pm.UserInfo;
Svet Ganov67882122016-12-11 16:36:34 -080055import android.content.pm.VersionedPackage;
Calin Juravle21216c62018-05-04 17:35:29 -070056import android.content.pm.dex.ArtManager;
Calin Juravle3fc56c32017-12-11 18:26:13 -080057import android.content.pm.dex.DexMetadataHelper;
Calin Juravle21216c62018-05-04 17:35:29 -070058import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
Todd Kennedy60459ab2015-10-30 11:32:16 -070059import android.content.res.AssetManager;
60import android.content.res.Resources;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080061import android.net.Uri;
62import android.os.Binder;
63import android.os.Build;
64import android.os.Bundle;
Dianne Hackborn98305522017-05-05 17:53:53 -070065import android.os.IBinder;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070066import android.os.IUserManager;
Dianne Hackbornca3872c2017-10-30 14:19:32 -070067import android.os.ParcelFileDescriptor;
Calin Juravle21216c62018-05-04 17:35:29 -070068import android.os.ParcelFileDescriptor.AutoCloseInputStream;
Suprabh Shukla021b57a2018-03-08 18:21:50 -080069import android.os.PersistableBundle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070070import android.os.Process;
Todd Kennedy60459ab2015-10-30 11:32:16 -070071import android.os.RemoteException;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070072import android.os.ServiceManager;
Todd Kennedy60459ab2015-10-30 11:32:16 -070073import android.os.ShellCommand;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070074import android.os.SystemClock;
Calin Juravle8bc758b2016-03-28 12:31:52 +010075import android.os.SystemProperties;
Todd Kennedy60459ab2015-10-30 11:32:16 -070076import android.os.UserHandle;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070077import android.os.UserManager;
78import android.os.storage.StorageManager;
Calin Juravlebdd94d92018-05-17 01:23:15 -070079import android.system.ErrnoException;
80import android.system.Os;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080081import android.text.TextUtils;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070082import android.text.format.DateUtils;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080083import android.util.ArraySet;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -080084import android.util.PrintWriterPrinter;
Dario Freni2bef1762018-06-01 14:02:08 +010085
Shunta Sato4f26cb52016-06-28 09:29:19 +090086import com.android.internal.content.PackageHelper;
Dianne Hackbornc81983a2017-10-20 16:16:32 -070087import com.android.internal.util.ArrayUtils;
Alex Chauc12189b2018-01-16 15:01:15 +000088import com.android.server.LocalServices;
Fyodor Kupolov51245c72016-12-01 11:34:10 -080089import com.android.server.SystemConfig;
Dario Freni2bef1762018-06-01 14:02:08 +010090
Andreas Gampebdd30d82016-03-20 11:32:11 -070091import dalvik.system.DexFile;
Dario Freni2bef1762018-06-01 14:02:08 +010092
93import libcore.io.IoUtils;
94import libcore.io.Streams;
95
Calin Juravle21216c62018-05-04 17:35:29 -070096import java.io.File;
97import java.io.FileOutputStream;
Todd Kennedy72cfcd02015-11-03 17:08:55 -080098import java.io.IOException;
Calin Juravle21216c62018-05-04 17:35:29 -070099import java.io.InputStream;
100import java.io.OutputStream;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700101import java.io.PrintWriter;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800102import java.net.URISyntaxException;
Calin Juravle21216c62018-05-04 17:35:29 -0700103import 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.TimeUnit;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700114
115class PackageManagerShellCommand extends ShellCommand {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700116 /** Path for streaming APK content */
117 private static final String STDIN_PATH = "-";
Calin Juravle21216c62018-05-04 17:35:29 -0700118 /** Path where ART profiles snapshots are dumped for the shell user */
119 private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700120
Todd Kennedy60459ab2015-10-30 11:32:16 -0700121 final IPackageManager mInterface;
122 final private WeakHashMap<String, Resources> mResourceCache =
123 new WeakHashMap<String, Resources>();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800124 int mTargetUser;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700125 boolean mBrief;
126 boolean mComponents;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700127
128 PackageManagerShellCommand(PackageManagerService service) {
129 mInterface = service;
130 }
131
132 @Override
133 public int onCommand(String cmd) {
134 if (cmd == null) {
135 return handleDefaultCommands(cmd);
136 }
137
138 final PrintWriter pw = getOutPrintWriter();
139 try {
140 switch(cmd) {
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700141 case "path":
142 return runPath();
143 case "dump":
144 return runDump();
145 case "list":
146 return runList();
147 case "resolve-activity":
148 return runResolveActivity();
149 case "query-activities":
150 return runQueryIntentActivities();
151 case "query-services":
152 return runQueryIntentServices();
153 case "query-receivers":
154 return runQueryIntentReceivers();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800155 case "install":
156 return runInstall();
157 case "install-abandon":
158 case "install-destroy":
159 return runInstallAbandon();
160 case "install-commit":
161 return runInstallCommit();
162 case "install-create":
163 return runInstallCreate();
Todd Kennedyeb9b0532016-03-08 10:10:54 -0800164 case "install-remove":
165 return runInstallRemove();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800166 case "install-write":
167 return runInstallWrite();
Todd Kennedybe0b8892017-02-15 14:13:52 -0800168 case "install-existing":
169 return runInstallExisting();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700170 case "set-install-location":
171 return runSetInstallLocation();
172 case "get-install-location":
173 return runGetInstallLocation();
174 case "move-package":
175 return runMovePackage();
176 case "move-primary-storage":
177 return runMovePrimaryStorage();
David Brazdil493411a2016-02-01 13:48:46 +0000178 case "compile":
179 return runCompile();
Calin Juravle1aa5f882017-01-25 01:05:50 -0800180 case "reconcile-secondary-dex-files":
181 return runreconcileSecondaryDexFiles();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700182 case "force-dex-opt":
183 return runForceDexOpt();
Calin Juravlecb5f41e2017-01-25 17:16:08 -0800184 case "bg-dexopt-job":
185 return runDexoptJob();
David Sehra8777082016-05-24 15:25:23 -0700186 case "dump-profiles":
187 return runDumpProfiles();
Calin Juravle21216c62018-05-04 17:35:29 -0700188 case "snapshot-profile":
189 return runSnapshotProfile();
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800190 case "uninstall":
191 return runUninstall();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700192 case "clear":
193 return runClear();
194 case "enable":
195 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
196 case "disable":
197 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
198 case "disable-user":
199 return runSetEnabledSetting(
200 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
201 case "disable-until-used":
202 return runSetEnabledSetting(
203 PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
204 case "default-state":
205 return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
206 case "hide":
207 return runSetHiddenSetting(true);
208 case "unhide":
209 return runSetHiddenSetting(false);
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000210 case "suspend":
211 return runSuspend(true);
212 case "unsuspend":
213 return runSuspend(false);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700214 case "grant":
215 return runGrantRevokePermission(true);
216 case "revoke":
217 return runGrantRevokePermission(false);
218 case "reset-permissions":
219 return runResetPermissions();
220 case "set-permission-enforced":
221 return runSetPermissionEnforced();
Fyodor Kupolov51245c72016-12-01 11:34:10 -0800222 case "get-privapp-permissions":
223 return runGetPrivappPermissions();
Todd Kennedy74629e32017-08-15 14:48:07 -0700224 case "get-privapp-deny-permissions":
225 return runGetPrivappDenyPermissions();
Svet Ganov087dce22017-09-07 15:42:16 -0700226 case "get-oem-permissions":
227 return runGetOemPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700228 case "set-app-link":
229 return runSetAppLink();
230 case "get-app-link":
231 return runGetAppLink();
232 case "trim-caches":
233 return runTrimCaches();
234 case "create-user":
235 return runCreateUser();
236 case "remove-user":
237 return runRemoveUser();
238 case "set-user-restriction":
239 return runSetUserRestriction();
240 case "get-max-users":
241 return runGetMaxUsers();
Alex Chauc12189b2018-01-16 15:01:15 +0000242 case "get-max-running-users":
243 return runGetMaxRunningUsers();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700244 case "set-home-activity":
245 return runSetHomeActivity();
246 case "set-installer":
247 return runSetInstaller();
Todd Kennedy0a3f0812017-05-08 14:43:15 -0700248 case "get-instantapp-resolver":
249 return runGetInstantAppResolver();
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +0900250 case "has-feature":
251 return runHasFeature();
Ben Gruver1ab3d6e2017-12-07 13:45:08 -0800252 case "set-harmful-app-warning":
253 return runSetHarmfulAppWarning();
Ben Gruver9ef60092018-01-10 11:32:30 -0800254 case "get-harmful-app-warning":
255 return runGetHarmfulAppWarning();
Patrick Baumanna980e142018-02-12 11:45:23 -0800256 case "uninstall-system-updates":
257 return uninstallSystemUpdates();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700258 default: {
259 String nextArg = getNextArg();
260 if (nextArg == null) {
261 if (cmd.equalsIgnoreCase("-l")) {
262 return runListPackages(false);
263 } else if (cmd.equalsIgnoreCase("-lf")) {
264 return runListPackages(true);
265 }
266 } else if (getNextArg() == null) {
267 if (cmd.equalsIgnoreCase("-p")) {
268 return displayPackageFilePath(nextArg, UserHandle.USER_SYSTEM);
269 }
270 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700271 return handleDefaultCommands(cmd);
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700272 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700273 }
274 } catch (RemoteException e) {
275 pw.println("Remote exception: " + e);
276 }
277 return -1;
278 }
279
Patrick Baumanna980e142018-02-12 11:45:23 -0800280 private int uninstallSystemUpdates() {
281 final PrintWriter pw = getOutPrintWriter();
282 List<String> failedUninstalls = new LinkedList<>();
283 try {
284 final ParceledListSlice<ApplicationInfo> packages =
285 mInterface.getInstalledApplications(
286 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
287 final IPackageInstaller installer = mInterface.getPackageInstaller();
288 List<ApplicationInfo> list = packages.getList();
289 for (ApplicationInfo info : list) {
290 if (info.isUpdatedSystemApp()) {
291 pw.println("Uninstalling updates to " + info.packageName + "...");
292 final LocalIntentReceiver receiver = new LocalIntentReceiver();
293 installer.uninstall(new VersionedPackage(info.packageName,
294 info.versionCode), null /*callerPackageName*/, 0 /* flags */,
295 receiver.getIntentSender(), 0);
296
297 final Intent result = receiver.getResult();
298 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
299 PackageInstaller.STATUS_FAILURE);
300 if (status != PackageInstaller.STATUS_SUCCESS) {
301 failedUninstalls.add(info.packageName);
302 }
303 }
304 }
305 } catch (RemoteException e) {
306 pw.println("Failure ["
307 + e.getClass().getName() + " - "
308 + e.getMessage() + "]");
309 return 0;
310 }
311 if (!failedUninstalls.isEmpty()) {
312 pw.println("Failure [Couldn't uninstall packages: "
313 + TextUtils.join(", ", failedUninstalls)
314 + "]");
315 return 0;
316 }
317 pw.println("Success");
318 return 1;
319 }
320
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700321 private void setParamsSize(InstallParams params, String inPath) {
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700322 if (params.sessionParams.sizeBytes == -1 && !STDIN_PATH.equals(inPath)) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700323 final ParcelFileDescriptor fd = openFileForSystem(inPath, "r");
324 if (fd == null) {
325 getErrPrintWriter().println("Error: Can't open file: " + inPath);
326 throw new IllegalArgumentException("Error: Can't open file: " + inPath);
327 }
328 try {
329 ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
330 PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
331 null, null);
332 params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
Dianne Hackborn1704e3c2017-10-31 19:55:42 +0000333 pkgLite, params.sessionParams.abiOverride, fd.getFileDescriptor()));
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700334 } catch (PackageParserException | IOException e) {
335 getErrPrintWriter().println("Error: Failed to parse APK file: " + inPath);
336 throw new IllegalArgumentException(
337 "Error: Failed to parse APK file: " + inPath, e);
338 } finally {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900339 try {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700340 fd.close();
341 } catch (IOException e) {
Shunta Sato4f26cb52016-06-28 09:29:19 +0900342 }
343 }
344 }
Todd Kennedy9caf94e2016-10-12 15:26:08 -0700345 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700346 /**
347 * Displays the package file for a package.
348 * @param pckg
349 */
350 private int displayPackageFilePath(String pckg, int userId) throws RemoteException {
351 PackageInfo info = mInterface.getPackageInfo(pckg, 0, userId);
352 if (info != null && info.applicationInfo != null) {
353 final PrintWriter pw = getOutPrintWriter();
354 pw.print("package:");
355 pw.println(info.applicationInfo.sourceDir);
356 if (!ArrayUtils.isEmpty(info.applicationInfo.splitSourceDirs)) {
357 for (String splitSourceDir : info.applicationInfo.splitSourceDirs) {
358 pw.print("package:");
359 pw.println(splitSourceDir);
Todd Kennedy8d9366c2015-12-16 13:47:14 -0800360 }
361 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700362 return 0;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800363 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700364 return 1;
Todd Kennedy72cfcd02015-11-03 17:08:55 -0800365 }
366
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700367 private int runPath() throws RemoteException {
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000368 int userId = UserHandle.USER_SYSTEM;
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700369 String option = getNextOption();
370 if (option != null && option.equals("--user")) {
371 userId = UserHandle.parseUserArg(getNextArgRequired());
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000372 }
373
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700374 String pkg = getNextArgRequired();
375 if (pkg == null) {
376 getErrPrintWriter().println("Error: no package specified");
Andrei Stingaceanu1e283912015-11-26 15:26:28 +0000377 return 1;
378 }
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700379 return displayPackageFilePath(pkg, userId);
David Sehra8777082016-05-24 15:25:23 -0700380 }
381
Todd Kennedy60459ab2015-10-30 11:32:16 -0700382 private int runList() throws RemoteException {
383 final PrintWriter pw = getOutPrintWriter();
384 final String type = getNextArg();
385 if (type == null) {
386 pw.println("Error: didn't specify type of data to list");
387 return -1;
388 }
389 switch(type) {
390 case "features":
391 return runListFeatures();
392 case "instrumentation":
393 return runListInstrumentation();
394 case "libraries":
395 return runListLibraries();
396 case "package":
397 case "packages":
398 return runListPackages(false /*showSourceDir*/);
399 case "permission-groups":
400 return runListPermissionGroups();
401 case "permissions":
402 return runListPermissions();
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700403 case "users":
404 ServiceManager.getService("user").shellCommand(
405 getInFileDescriptor(), getOutFileDescriptor(), getErrFileDescriptor(),
406 new String[] { "list" }, getShellCallback(), adoptResultReceiver());
407 return 0;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700408 }
409 pw.println("Error: unknown list type '" + type + "'");
410 return -1;
411 }
412
413 private int runListFeatures() throws RemoteException {
414 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700415 final List<FeatureInfo> list = mInterface.getSystemAvailableFeatures().getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700416
417 // sort by name
418 Collections.sort(list, new Comparator<FeatureInfo>() {
419 public int compare(FeatureInfo o1, FeatureInfo o2) {
420 if (o1.name == o2.name) return 0;
421 if (o1.name == null) return -1;
422 if (o2.name == null) return 1;
423 return o1.name.compareTo(o2.name);
424 }
425 });
426
427 final int count = (list != null) ? list.size() : 0;
428 for (int p = 0; p < count; p++) {
429 FeatureInfo fi = list.get(p);
430 pw.print("feature:");
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700431 if (fi.name != null) {
432 pw.print(fi.name);
433 if (fi.version > 0) {
434 pw.print("=");
435 pw.print(fi.version);
436 }
437 pw.println();
438 } else {
439 pw.println("reqGlEsVersion=0x"
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700440 + Integer.toHexString(fi.reqGlEsVersion));
Jeff Sharkey115d2c12016-02-15 17:25:57 -0700441 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700442 }
443 return 0;
444 }
445
446 private int runListInstrumentation() throws RemoteException {
447 final PrintWriter pw = getOutPrintWriter();
448 boolean showSourceDir = false;
449 String targetPackage = null;
450
451 try {
452 String opt;
453 while ((opt = getNextArg()) != null) {
454 switch (opt) {
455 case "-f":
456 showSourceDir = true;
457 break;
458 default:
459 if (opt.charAt(0) != '-') {
460 targetPackage = opt;
461 } else {
462 pw.println("Error: Unknown option: " + opt);
463 return -1;
464 }
465 break;
466 }
467 }
468 } catch (RuntimeException ex) {
469 pw.println("Error: " + ex.toString());
470 return -1;
471 }
472
473 final List<InstrumentationInfo> list =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700474 mInterface.queryInstrumentation(targetPackage, 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700475
476 // sort by target package
477 Collections.sort(list, new Comparator<InstrumentationInfo>() {
478 public int compare(InstrumentationInfo o1, InstrumentationInfo o2) {
479 return o1.targetPackage.compareTo(o2.targetPackage);
480 }
481 });
482
483 final int count = (list != null) ? list.size() : 0;
484 for (int p = 0; p < count; p++) {
485 final InstrumentationInfo ii = list.get(p);
486 pw.print("instrumentation:");
487 if (showSourceDir) {
488 pw.print(ii.sourceDir);
489 pw.print("=");
490 }
491 final ComponentName cn = new ComponentName(ii.packageName, ii.name);
492 pw.print(cn.flattenToShortString());
493 pw.print(" (target=");
494 pw.print(ii.targetPackage);
495 pw.println(")");
496 }
497 return 0;
498 }
499
500 private int runListLibraries() throws RemoteException {
501 final PrintWriter pw = getOutPrintWriter();
502 final List<String> list = new ArrayList<String>();
503 final String[] rawList = mInterface.getSystemSharedLibraryNames();
504 for (int i = 0; i < rawList.length; i++) {
505 list.add(rawList[i]);
506 }
507
508 // sort by name
509 Collections.sort(list, new Comparator<String>() {
510 public int compare(String o1, String o2) {
511 if (o1 == o2) return 0;
512 if (o1 == null) return -1;
513 if (o2 == null) return 1;
514 return o1.compareTo(o2);
515 }
516 });
517
518 final int count = (list != null) ? list.size() : 0;
519 for (int p = 0; p < count; p++) {
520 String lib = list.get(p);
521 pw.print("library:");
522 pw.println(lib);
523 }
524 return 0;
525 }
526
527 private int runListPackages(boolean showSourceDir) throws RemoteException {
528 final PrintWriter pw = getOutPrintWriter();
529 int getFlags = 0;
530 boolean listDisabled = false, listEnabled = false;
531 boolean listSystem = false, listThirdParty = false;
532 boolean listInstaller = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700533 boolean showUid = false;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800534 boolean showVersionCode = false;
Felipe Lemeeece9862016-06-29 11:45:03 -0700535 int uid = -1;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700536 int userId = UserHandle.USER_SYSTEM;
537 try {
538 String opt;
539 while ((opt = getNextOption()) != null) {
540 switch (opt) {
541 case "-d":
542 listDisabled = true;
543 break;
544 case "-e":
545 listEnabled = true;
546 break;
Andreas Gampe1f110452018-06-04 11:47:48 -0700547 case "-a":
548 getFlags |= PackageManager.MATCH_KNOWN_PACKAGES;
549 getFlags |= PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
550 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700551 case "-f":
552 showSourceDir = true;
553 break;
554 case "-i":
555 listInstaller = true;
556 break;
557 case "-l":
558 // old compat
559 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700560 case "-s":
561 listSystem = true;
562 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700563 case "-U":
564 showUid = true;
565 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700566 case "-u":
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -0700567 getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700568 break;
569 case "-3":
570 listThirdParty = true;
571 break;
Todd Kennedybadc69a2017-01-24 11:05:47 -0800572 case "--show-versioncode":
573 showVersionCode = true;
574 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700575 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800576 userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy60459ab2015-10-30 11:32:16 -0700577 break;
Felipe Lemeeece9862016-06-29 11:45:03 -0700578 case "--uid":
579 showUid = true;
580 uid = Integer.parseInt(getNextArgRequired());
581 break;
Todd Kennedy60459ab2015-10-30 11:32:16 -0700582 default:
583 pw.println("Error: Unknown option: " + opt);
584 return -1;
585 }
586 }
587 } catch (RuntimeException ex) {
588 pw.println("Error: " + ex.toString());
589 return -1;
590 }
591
592 final String filter = getNextArg();
593
594 @SuppressWarnings("unchecked")
595 final ParceledListSlice<PackageInfo> slice =
596 mInterface.getInstalledPackages(getFlags, userId);
597 final List<PackageInfo> packages = slice.getList();
598
599 final int count = packages.size();
600 for (int p = 0; p < count; p++) {
601 final PackageInfo info = packages.get(p);
602 if (filter != null && !info.packageName.contains(filter)) {
603 continue;
604 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700605 if (uid != -1 && info.applicationInfo.uid != uid) {
606 continue;
607 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700608 final boolean isSystem =
609 (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
610 if ((!listDisabled || !info.applicationInfo.enabled) &&
611 (!listEnabled || info.applicationInfo.enabled) &&
612 (!listSystem || isSystem) &&
613 (!listThirdParty || !isSystem)) {
614 pw.print("package:");
615 if (showSourceDir) {
616 pw.print(info.applicationInfo.sourceDir);
617 pw.print("=");
618 }
Todd Kennedybadc69a2017-01-24 11:05:47 -0800619 pw.print(info.packageName);
620 if (showVersionCode) {
621 pw.print(" versionCode:");
622 pw.print(info.applicationInfo.versionCode);
623 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700624 if (listInstaller) {
625 pw.print(" installer=");
626 pw.print(mInterface.getInstallerPackageName(info.packageName));
627 }
Felipe Lemeeece9862016-06-29 11:45:03 -0700628 if (showUid) {
629 pw.print(" uid:");
630 pw.print(info.applicationInfo.uid);
631 }
Todd Kennedy60459ab2015-10-30 11:32:16 -0700632 pw.println();
633 }
634 }
635 return 0;
636 }
637
638 private int runListPermissionGroups() throws RemoteException {
639 final PrintWriter pw = getOutPrintWriter();
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700640 final List<PermissionGroupInfo> pgs = mInterface.getAllPermissionGroups(0).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700641
642 final int count = pgs.size();
643 for (int p = 0; p < count ; p++) {
644 final PermissionGroupInfo pgi = pgs.get(p);
645 pw.print("permission group:");
646 pw.println(pgi.name);
647 }
648 return 0;
649 }
650
651 private int runListPermissions() throws RemoteException {
652 final PrintWriter pw = getOutPrintWriter();
653 boolean labels = false;
654 boolean groups = false;
655 boolean userOnly = false;
656 boolean summary = false;
657 boolean dangerousOnly = false;
658 String opt;
659 while ((opt = getNextOption()) != null) {
660 switch (opt) {
661 case "-d":
662 dangerousOnly = true;
663 break;
664 case "-f":
665 labels = true;
666 break;
667 case "-g":
668 groups = true;
669 break;
670 case "-s":
671 groups = true;
672 labels = true;
673 summary = true;
674 break;
675 case "-u":
676 userOnly = true;
677 break;
678 default:
679 pw.println("Error: Unknown option: " + opt);
680 return 1;
681 }
682 }
683
684 final ArrayList<String> groupList = new ArrayList<String>();
685 if (groups) {
686 final List<PermissionGroupInfo> infos =
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700687 mInterface.getAllPermissionGroups(0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -0700688 final int count = infos.size();
689 for (int i = 0; i < count; i++) {
690 groupList.add(infos.get(i).name);
691 }
692 groupList.add(null);
693 } else {
694 final String grp = getNextArg();
695 groupList.add(grp);
696 }
697
698 if (dangerousOnly) {
699 pw.println("Dangerous Permissions:");
700 pw.println("");
701 doListPermissions(groupList, groups, labels, summary,
702 PermissionInfo.PROTECTION_DANGEROUS,
703 PermissionInfo.PROTECTION_DANGEROUS);
704 if (userOnly) {
705 pw.println("Normal Permissions:");
706 pw.println("");
707 doListPermissions(groupList, groups, labels, summary,
708 PermissionInfo.PROTECTION_NORMAL,
709 PermissionInfo.PROTECTION_NORMAL);
710 }
711 } else if (userOnly) {
712 pw.println("Dangerous and Normal Permissions:");
713 pw.println("");
714 doListPermissions(groupList, groups, labels, summary,
715 PermissionInfo.PROTECTION_NORMAL,
716 PermissionInfo.PROTECTION_DANGEROUS);
717 } else {
718 pw.println("All Permissions:");
719 pw.println("");
720 doListPermissions(groupList, groups, labels, summary,
721 -10000, 10000);
722 }
723 return 0;
724 }
725
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800726 private Intent parseIntentAndUser() throws URISyntaxException {
727 mTargetUser = UserHandle.USER_CURRENT;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700728 mBrief = false;
729 mComponents = false;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800730 Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
731 @Override
732 public boolean handleOption(String opt, ShellCommand cmd) {
733 if ("--user".equals(opt)) {
734 mTargetUser = UserHandle.parseUserArg(cmd.getNextArgRequired());
735 return true;
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700736 } else if ("--brief".equals(opt)) {
737 mBrief = true;
738 return true;
739 } else if ("--components".equals(opt)) {
740 mComponents = true;
741 return true;
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800742 }
743 return false;
744 }
745 });
746 mTargetUser = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
747 Binder.getCallingUid(), mTargetUser, false, false, null, null);
748 return intent;
749 }
750
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700751 private void printResolveInfo(PrintWriterPrinter pr, String prefix, ResolveInfo ri,
752 boolean brief, boolean components) {
753 if (brief || components) {
754 final ComponentName comp;
755 if (ri.activityInfo != null) {
756 comp = new ComponentName(ri.activityInfo.packageName, ri.activityInfo.name);
757 } else if (ri.serviceInfo != null) {
758 comp = new ComponentName(ri.serviceInfo.packageName, ri.serviceInfo.name);
759 } else if (ri.providerInfo != null) {
760 comp = new ComponentName(ri.providerInfo.packageName, ri.providerInfo.name);
761 } else {
762 comp = null;
763 }
764 if (comp != null) {
765 if (!components) {
766 pr.println(prefix + "priority=" + ri.priority
767 + " preferredOrder=" + ri.preferredOrder
768 + " match=0x" + Integer.toHexString(ri.match)
769 + " specificIndex=" + ri.specificIndex
770 + " isDefault=" + ri.isDefault);
771 }
772 pr.println(prefix + comp.flattenToShortString());
773 return;
774 }
775 }
776 ri.dump(pr, prefix);
777 }
778
Dianne Hackborn99878e92015-12-02 16:27:41 -0800779 private int runResolveActivity() {
780 Intent intent;
781 try {
782 intent = parseIntentAndUser();
783 } catch (URISyntaxException e) {
784 throw new RuntimeException(e.getMessage(), e);
785 }
786 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700787 ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800788 PrintWriter pw = getOutPrintWriter();
789 if (ri == null) {
790 pw.println("No activity found");
791 } else {
792 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700793 printResolveInfo(pr, "", ri, mBrief, mComponents);
Dianne Hackborn99878e92015-12-02 16:27:41 -0800794 }
795 } catch (RemoteException e) {
796 throw new RuntimeException("Failed calling service", e);
797 }
798 return 0;
799 }
800
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800801 private int runQueryIntentActivities() {
802 Intent intent;
803 try {
804 intent = parseIntentAndUser();
805 } catch (URISyntaxException e) {
806 throw new RuntimeException(e.getMessage(), e);
807 }
808 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700809 List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700810 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800811 PrintWriter pw = getOutPrintWriter();
812 if (result == null || result.size() <= 0) {
813 pw.println("No activities found");
814 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700815 if (!mComponents) {
816 pw.print(result.size()); pw.println(" activities found:");
817 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
818 for (int i = 0; i < result.size(); i++) {
819 pw.print(" Activity #"); pw.print(i); pw.println(":");
820 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
821 }
822 } else {
823 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
824 for (int i = 0; i < result.size(); i++) {
825 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
826 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800827 }
828 }
829 } catch (RemoteException e) {
830 throw new RuntimeException("Failed calling service", e);
831 }
832 return 0;
833 }
834
835 private int runQueryIntentServices() {
836 Intent intent;
837 try {
838 intent = parseIntentAndUser();
839 } catch (URISyntaxException e) {
840 throw new RuntimeException(e.getMessage(), e);
841 }
842 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700843 List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700844 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800845 PrintWriter pw = getOutPrintWriter();
846 if (result == null || result.size() <= 0) {
847 pw.println("No services found");
848 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700849 if (!mComponents) {
850 pw.print(result.size()); pw.println(" services found:");
851 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
852 for (int i = 0; i < result.size(); i++) {
853 pw.print(" Service #"); pw.print(i); pw.println(":");
854 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
855 }
856 } else {
857 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
858 for (int i = 0; i < result.size(); i++) {
859 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
860 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800861 }
862 }
863 } catch (RemoteException e) {
864 throw new RuntimeException("Failed calling service", e);
865 }
866 return 0;
867 }
868
869 private int runQueryIntentReceivers() {
870 Intent intent;
871 try {
872 intent = parseIntentAndUser();
873 } catch (URISyntaxException e) {
874 throw new RuntimeException(e.getMessage(), e);
875 }
876 try {
Todd Kennedy0e2a75d2017-06-26 15:57:06 -0700877 List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
Jeff Sharkeyd5896632016-03-04 16:16:00 -0700878 mTargetUser).getList();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800879 PrintWriter pw = getOutPrintWriter();
880 if (result == null || result.size() <= 0) {
881 pw.println("No receivers found");
882 } else {
Dianne Hackbornd6e4aa42016-04-26 13:51:07 -0700883 if (!mComponents) {
884 pw.print(result.size()); pw.println(" receivers found:");
885 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
886 for (int i = 0; i < result.size(); i++) {
887 pw.print(" Receiver #"); pw.print(i); pw.println(":");
888 printResolveInfo(pr, " ", result.get(i), mBrief, mComponents);
889 }
890 } else {
891 PrintWriterPrinter pr = new PrintWriterPrinter(pw);
892 for (int i = 0; i < result.size(); i++) {
893 printResolveInfo(pr, "", result.get(i), mBrief, mComponents);
894 }
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800895 }
896 }
897 } catch (RemoteException e) {
898 throw new RuntimeException("Failed calling service", e);
899 }
900 return 0;
901 }
902
Dianne Hackbornc81983a2017-10-20 16:16:32 -0700903 private int runInstall() throws RemoteException {
904 final PrintWriter pw = getOutPrintWriter();
905 final InstallParams params = makeInstallParams();
906 final String inPath = getNextArg();
907
908 setParamsSize(params, inPath);
909 final int sessionId = doCreateSession(params.sessionParams,
910 params.installerPackageName, params.userId);
911 boolean abandonSession = true;
912 try {
913 if (inPath == null && params.sessionParams.sizeBytes == -1) {
914 pw.println("Error: must either specify a package size or an APK file");
915 return 1;
916 }
917 if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk",
918 false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
919 return 1;
920 }
921 if (doCommitSession(sessionId, false /*logSuccess*/)
922 != PackageInstaller.STATUS_SUCCESS) {
923 return 1;
924 }
925 abandonSession = false;
926 pw.println("Success");
927 return 0;
928 } finally {
929 if (abandonSession) {
930 try {
931 doAbandonSession(sessionId, false /*logSuccess*/);
932 } catch (Exception ignore) {
933 }
934 }
935 }
936 }
937
938 private int runInstallAbandon() throws RemoteException {
939 final int sessionId = Integer.parseInt(getNextArg());
940 return doAbandonSession(sessionId, true /*logSuccess*/);
941 }
942
943 private int runInstallCommit() throws RemoteException {
944 final int sessionId = Integer.parseInt(getNextArg());
945 return doCommitSession(sessionId, true /*logSuccess*/);
946 }
947
948 private int runInstallCreate() throws RemoteException {
949 final PrintWriter pw = getOutPrintWriter();
950 final InstallParams installParams = makeInstallParams();
951 final int sessionId = doCreateSession(installParams.sessionParams,
952 installParams.installerPackageName, installParams.userId);
953
954 // NOTE: adb depends on parsing this string
955 pw.println("Success: created install session [" + sessionId + "]");
956 return 0;
957 }
958
959 private int runInstallWrite() throws RemoteException {
960 long sizeBytes = -1;
961
962 String opt;
963 while ((opt = getNextOption()) != null) {
964 if (opt.equals("-S")) {
965 sizeBytes = Long.parseLong(getNextArg());
966 } else {
967 throw new IllegalArgumentException("Unknown option: " + opt);
968 }
969 }
970
971 final int sessionId = Integer.parseInt(getNextArg());
972 final String splitName = getNextArg();
973 final String path = getNextArg();
974 return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/);
975 }
976
977 private int runInstallRemove() throws RemoteException {
978 final PrintWriter pw = getOutPrintWriter();
979
980 final int sessionId = Integer.parseInt(getNextArg());
981
982 final String splitName = getNextArg();
983 if (splitName == null) {
984 pw.println("Error: split name not specified");
985 return 1;
986 }
987 return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
988 }
989
990 private int runInstallExisting() throws RemoteException {
991 final PrintWriter pw = getOutPrintWriter();
992 int userId = UserHandle.USER_SYSTEM;
993 int installFlags = 0;
994 String opt;
995 while ((opt = getNextOption()) != null) {
996 switch (opt) {
997 case "--user":
998 userId = UserHandle.parseUserArg(getNextArgRequired());
999 break;
1000 case "--ephemeral":
1001 case "--instant":
1002 installFlags |= PackageManager.INSTALL_INSTANT_APP;
1003 installFlags &= ~PackageManager.INSTALL_FULL_APP;
1004 break;
1005 case "--full":
1006 installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
1007 installFlags |= PackageManager.INSTALL_FULL_APP;
1008 break;
1009 default:
1010 pw.println("Error: Unknown option: " + opt);
1011 return 1;
1012 }
1013 }
1014
1015 final String packageName = getNextArg();
1016 if (packageName == null) {
1017 pw.println("Error: package name not specified");
1018 return 1;
1019 }
1020
1021 try {
1022 final int res = mInterface.installExistingPackageAsUser(packageName, userId,
1023 installFlags, PackageManager.INSTALL_REASON_UNKNOWN);
1024 if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
1025 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1026 }
1027 pw.println("Package " + packageName + " installed for user: " + userId);
1028 return 0;
1029 } catch (RemoteException | NameNotFoundException e) {
1030 pw.println(e.toString());
1031 return 1;
1032 }
1033 }
1034
1035 private int runSetInstallLocation() throws RemoteException {
1036 int loc;
1037
1038 String arg = getNextArg();
1039 if (arg == null) {
1040 getErrPrintWriter().println("Error: no install location specified.");
1041 return 1;
1042 }
1043 try {
1044 loc = Integer.parseInt(arg);
1045 } catch (NumberFormatException e) {
1046 getErrPrintWriter().println("Error: install location has to be a number.");
1047 return 1;
1048 }
1049 if (!mInterface.setInstallLocation(loc)) {
1050 getErrPrintWriter().println("Error: install location has to be a number.");
1051 return 1;
1052 }
1053 return 0;
1054 }
1055
1056 private int runGetInstallLocation() throws RemoteException {
1057 int loc = mInterface.getInstallLocation();
1058 String locStr = "invalid";
1059 if (loc == PackageHelper.APP_INSTALL_AUTO) {
1060 locStr = "auto";
1061 } else if (loc == PackageHelper.APP_INSTALL_INTERNAL) {
1062 locStr = "internal";
1063 } else if (loc == PackageHelper.APP_INSTALL_EXTERNAL) {
1064 locStr = "external";
1065 }
1066 getOutPrintWriter().println(loc + "[" + locStr + "]");
1067 return 0;
1068 }
1069
1070 public int runMovePackage() throws RemoteException {
1071 final String packageName = getNextArg();
1072 if (packageName == null) {
1073 getErrPrintWriter().println("Error: package name not specified");
1074 return 1;
1075 }
1076 String volumeUuid = getNextArg();
1077 if ("internal".equals(volumeUuid)) {
1078 volumeUuid = null;
1079 }
1080
1081 final int moveId = mInterface.movePackage(packageName, volumeUuid);
1082
1083 int status = mInterface.getMoveStatus(moveId);
1084 while (!PackageManager.isMoveStatusFinished(status)) {
1085 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1086 status = mInterface.getMoveStatus(moveId);
1087 }
1088
1089 if (status == PackageManager.MOVE_SUCCEEDED) {
1090 getOutPrintWriter().println("Success");
1091 return 0;
1092 } else {
1093 getErrPrintWriter().println("Failure [" + status + "]");
1094 return 1;
1095 }
1096 }
1097
1098 public int runMovePrimaryStorage() throws RemoteException {
1099 String volumeUuid = getNextArg();
1100 if ("internal".equals(volumeUuid)) {
1101 volumeUuid = null;
1102 }
1103
1104 final int moveId = mInterface.movePrimaryStorage(volumeUuid);
1105
1106 int status = mInterface.getMoveStatus(moveId);
1107 while (!PackageManager.isMoveStatusFinished(status)) {
1108 SystemClock.sleep(DateUtils.SECOND_IN_MILLIS);
1109 status = mInterface.getMoveStatus(moveId);
1110 }
1111
1112 if (status == PackageManager.MOVE_SUCCEEDED) {
1113 getOutPrintWriter().println("Success");
1114 return 0;
1115 } else {
1116 getErrPrintWriter().println("Failure [" + status + "]");
1117 return 1;
1118 }
1119 }
1120
1121 private int runCompile() throws RemoteException {
1122 final PrintWriter pw = getOutPrintWriter();
1123 boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
1124 boolean forceCompilation = false;
1125 boolean allPackages = false;
1126 boolean clearProfileData = false;
1127 String compilerFilter = null;
1128 String compilationReason = null;
1129 String checkProfilesRaw = null;
1130 boolean secondaryDex = false;
1131 String split = null;
1132
1133 String opt;
1134 while ((opt = getNextOption()) != null) {
1135 switch (opt) {
1136 case "-a":
1137 allPackages = true;
1138 break;
1139 case "-c":
1140 clearProfileData = true;
1141 break;
1142 case "-f":
1143 forceCompilation = true;
1144 break;
1145 case "-m":
1146 compilerFilter = getNextArgRequired();
1147 break;
1148 case "-r":
1149 compilationReason = getNextArgRequired();
1150 break;
1151 case "--check-prof":
1152 checkProfilesRaw = getNextArgRequired();
1153 break;
1154 case "--reset":
1155 forceCompilation = true;
1156 clearProfileData = true;
1157 compilationReason = "install";
1158 break;
1159 case "--secondary-dex":
1160 secondaryDex = true;
1161 break;
1162 case "--split":
1163 split = getNextArgRequired();
1164 break;
1165 default:
1166 pw.println("Error: Unknown option: " + opt);
1167 return 1;
1168 }
1169 }
1170
1171 if (checkProfilesRaw != null) {
1172 if ("true".equals(checkProfilesRaw)) {
1173 checkProfiles = true;
1174 } else if ("false".equals(checkProfilesRaw)) {
1175 checkProfiles = false;
1176 } else {
1177 pw.println("Invalid value for \"--check-prof\". Expected \"true\" or \"false\".");
1178 return 1;
1179 }
1180 }
1181
1182 if (compilerFilter != null && compilationReason != null) {
1183 pw.println("Cannot use compilation filter (\"-m\") and compilation reason (\"-r\") " +
1184 "at the same time");
1185 return 1;
1186 }
1187 if (compilerFilter == null && compilationReason == null) {
1188 pw.println("Cannot run without any of compilation filter (\"-m\") and compilation " +
1189 "reason (\"-r\") at the same time");
1190 return 1;
1191 }
1192
1193 if (allPackages && split != null) {
1194 pw.println("-a cannot be specified together with --split");
1195 return 1;
1196 }
1197
1198 if (secondaryDex && split != null) {
1199 pw.println("--secondary-dex cannot be specified together with --split");
1200 return 1;
1201 }
1202
1203 String targetCompilerFilter;
1204 if (compilerFilter != null) {
1205 if (!DexFile.isValidCompilerFilter(compilerFilter)) {
1206 pw.println("Error: \"" + compilerFilter +
1207 "\" is not a valid compilation filter.");
1208 return 1;
1209 }
1210 targetCompilerFilter = compilerFilter;
1211 } else {
1212 int reason = -1;
1213 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
1214 if (PackageManagerServiceCompilerMapping.REASON_STRINGS[i].equals(
1215 compilationReason)) {
1216 reason = i;
1217 break;
1218 }
1219 }
1220 if (reason == -1) {
1221 pw.println("Error: Unknown compilation reason: " + compilationReason);
1222 return 1;
1223 }
1224 targetCompilerFilter =
1225 PackageManagerServiceCompilerMapping.getCompilerFilterForReason(reason);
1226 }
1227
1228
1229 List<String> packageNames = null;
1230 if (allPackages) {
1231 packageNames = mInterface.getAllPackages();
1232 } else {
1233 String packageName = getNextArg();
1234 if (packageName == null) {
1235 pw.println("Error: package name not specified");
1236 return 1;
1237 }
1238 packageNames = Collections.singletonList(packageName);
1239 }
1240
1241 List<String> failedPackages = new ArrayList<>();
Andreas Gampecbd08d42017-11-20 17:03:17 -08001242 int index = 0;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001243 for (String packageName : packageNames) {
1244 if (clearProfileData) {
1245 mInterface.clearApplicationProfileData(packageName);
1246 }
1247
Andreas Gampecbd08d42017-11-20 17:03:17 -08001248 if (allPackages) {
1249 pw.println(++index + "/" + packageNames.size() + ": " + packageName);
1250 pw.flush();
1251 }
1252
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001253 boolean result = secondaryDex
1254 ? mInterface.performDexOptSecondary(packageName,
1255 targetCompilerFilter, forceCompilation)
1256 : mInterface.performDexOptMode(packageName,
1257 checkProfiles, targetCompilerFilter, forceCompilation,
1258 true /* bootComplete */, split);
1259 if (!result) {
1260 failedPackages.add(packageName);
1261 }
1262 }
1263
1264 if (failedPackages.isEmpty()) {
1265 pw.println("Success");
1266 return 0;
1267 } else if (failedPackages.size() == 1) {
1268 pw.println("Failure: package " + failedPackages.get(0) + " could not be compiled");
1269 return 1;
1270 } else {
1271 pw.print("Failure: the following packages could not be compiled: ");
1272 boolean is_first = true;
1273 for (String packageName : failedPackages) {
1274 if (is_first) {
1275 is_first = false;
1276 } else {
1277 pw.print(", ");
1278 }
1279 pw.print(packageName);
1280 }
1281 pw.println();
1282 return 1;
1283 }
1284 }
1285
1286 private int runreconcileSecondaryDexFiles() throws RemoteException {
1287 String packageName = getNextArg();
1288 mInterface.reconcileSecondaryDexFiles(packageName);
1289 return 0;
1290 }
1291
1292 public int runForceDexOpt() throws RemoteException {
1293 mInterface.forceDexOpt(getNextArgRequired());
1294 return 0;
1295 }
1296
1297 private int runDexoptJob() throws RemoteException {
Arthur Eubanks09dd1ec2017-09-15 09:28:51 -07001298 String arg;
1299 List<String> packageNames = new ArrayList<>();
1300 while ((arg = getNextArg()) != null) {
1301 packageNames.add(arg);
1302 }
1303 boolean result = mInterface.runBackgroundDexoptJob(packageNames.isEmpty() ? null :
1304 packageNames);
Andreas Gampefa8b57d2018-08-31 15:47:01 -07001305 getOutPrintWriter().println(result ? "Success" : "Failure");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001306 return result ? 0 : -1;
1307 }
1308
1309 private int runDumpProfiles() throws RemoteException {
1310 String packageName = getNextArg();
1311 mInterface.dumpProfiles(packageName);
1312 return 0;
1313 }
1314
Calin Juravle21216c62018-05-04 17:35:29 -07001315 private int runSnapshotProfile() throws RemoteException {
1316 PrintWriter pw = getOutPrintWriter();
1317
1318 // Parse the arguments
1319 final String packageName = getNextArg();
1320 final boolean isBootImage = "android".equals(packageName);
1321
1322 String codePath = null;
1323 String opt;
1324 while ((opt = getNextArg()) != null) {
1325 switch (opt) {
1326 case "--code-path":
1327 if (isBootImage) {
1328 pw.write("--code-path cannot be used for the boot image.");
1329 return -1;
1330 }
1331 codePath = getNextArg();
1332 break;
1333 default:
1334 pw.write("Unknown arg: " + opt);
1335 return -1;
1336 }
1337 }
1338
1339 // If no code path was explicitly requested, select the base code path.
1340 String baseCodePath = null;
1341 if (!isBootImage) {
1342 PackageInfo packageInfo = mInterface.getPackageInfo(packageName, /* flags */ 0,
1343 /* userId */0);
1344 if (packageInfo == null) {
1345 pw.write("Package not found " + packageName);
1346 return -1;
1347 }
1348 baseCodePath = packageInfo.applicationInfo.getBaseCodePath();
1349 if (codePath == null) {
1350 codePath = baseCodePath;
1351 }
1352 }
1353
1354 // Create the profile snapshot.
1355 final SnapshotRuntimeProfileCallback callback = new SnapshotRuntimeProfileCallback();
1356 // The calling package is needed to debug permission access.
1357 final String callingPackage = (Binder.getCallingUid() == Process.ROOT_UID)
1358 ? "root" : "com.android.shell";
1359 final int profileType = isBootImage
1360 ? ArtManager.PROFILE_BOOT_IMAGE : ArtManager.PROFILE_APPS;
1361 if (!mInterface.getArtManager().isRuntimeProfilingEnabled(profileType, callingPackage)) {
1362 pw.println("Error: Runtime profiling is not enabled");
1363 return -1;
1364 }
1365 mInterface.getArtManager().snapshotRuntimeProfile(profileType, packageName,
1366 codePath, callback, callingPackage);
1367 if (!callback.waitTillDone()) {
1368 pw.println("Error: callback not called");
1369 return callback.mErrCode;
1370 }
1371
1372 // Copy the snapshot profile to the output profile file.
1373 try (InputStream inStream = new AutoCloseInputStream(callback.mProfileReadFd)) {
1374 final String outputFileSuffix = isBootImage || Objects.equals(baseCodePath, codePath)
1375 ? "" : ("-" + new File(codePath).getName());
1376 final String outputProfilePath =
1377 ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + packageName + outputFileSuffix + ".prof";
1378 try (OutputStream outStream = new FileOutputStream(outputProfilePath)) {
1379 Streams.copy(inStream, outStream);
1380 }
Calin Juravlebdd94d92018-05-17 01:23:15 -07001381 // Give read permissions to the other group.
1382 Os.chmod(outputProfilePath, /*mode*/ 0644 );
1383 } catch (IOException | ErrnoException e) {
Calin Juravle21216c62018-05-04 17:35:29 -07001384 pw.println("Error when reading the profile fd: " + e.getMessage());
1385 e.printStackTrace(pw);
1386 return -1;
1387 }
1388 return 0;
1389 }
1390
1391 private static class SnapshotRuntimeProfileCallback
1392 extends ISnapshotRuntimeProfileCallback.Stub {
1393 private boolean mSuccess = false;
1394 private int mErrCode = -1;
1395 private ParcelFileDescriptor mProfileReadFd = null;
1396 private CountDownLatch mDoneSignal = new CountDownLatch(1);
1397
1398 @Override
1399 public void onSuccess(ParcelFileDescriptor profileReadFd) {
1400 mSuccess = true;
1401 try {
1402 // We need to dup the descriptor. We are in the same process as system server
1403 // and we will be receiving the same object (which will be closed on the
1404 // server side).
1405 mProfileReadFd = profileReadFd.dup();
1406 } catch (IOException e) {
1407 e.printStackTrace();
1408 }
1409 mDoneSignal.countDown();
1410 }
1411
1412 @Override
1413 public void onError(int errCode) {
1414 mSuccess = false;
1415 mErrCode = errCode;
1416 mDoneSignal.countDown();
1417 }
1418
1419 boolean waitTillDone() {
1420 boolean done = false;
1421 try {
1422 // The time-out is an arbitrary large value. Since this is a local call the result
1423 // will come very fast.
1424 done = mDoneSignal.await(10000000, TimeUnit.MILLISECONDS);
1425 } catch (InterruptedException ignored) {
1426 }
1427 return done && mSuccess;
1428 }
1429 }
1430
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001431 private int runUninstall() throws RemoteException {
1432 final PrintWriter pw = getOutPrintWriter();
1433 int flags = 0;
1434 int userId = UserHandle.USER_ALL;
Dianne Hackborn3accca02013-09-20 09:32:11 -07001435 long versionCode = PackageManager.VERSION_CODE_HIGHEST;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001436
1437 String opt;
1438 while ((opt = getNextOption()) != null) {
1439 switch (opt) {
1440 case "-k":
1441 flags |= PackageManager.DELETE_KEEP_DATA;
1442 break;
1443 case "--user":
1444 userId = UserHandle.parseUserArg(getNextArgRequired());
1445 break;
1446 case "--versionCode":
Dianne Hackborn3accca02013-09-20 09:32:11 -07001447 versionCode = Long.parseLong(getNextArgRequired());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001448 break;
1449 default:
1450 pw.println("Error: Unknown option: " + opt);
1451 return 1;
1452 }
1453 }
1454
1455 final String packageName = getNextArg();
1456 if (packageName == null) {
1457 pw.println("Error: package name not specified");
1458 return 1;
1459 }
1460
1461 // if a split is specified, just remove it and not the whole package
1462 final String splitName = getNextArg();
1463 if (splitName != null) {
1464 return runRemoveSplit(packageName, splitName);
1465 }
1466
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08001467 userId = translateUserId(userId, true /*allowAll*/, "runUninstall");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001468 if (userId == UserHandle.USER_ALL) {
1469 userId = UserHandle.USER_SYSTEM;
1470 flags |= PackageManager.DELETE_ALL_USERS;
1471 } else {
1472 final PackageInfo info = mInterface.getPackageInfo(packageName,
1473 PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
1474 if (info == null) {
1475 pw.println("Failure [not installed for " + userId + "]");
1476 return 1;
1477 }
1478 final boolean isSystem =
1479 (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
1480 // If we are being asked to delete a system app for just one
1481 // user set flag so it disables rather than reverting to system
1482 // version of the app.
1483 if (isSystem) {
1484 flags |= PackageManager.DELETE_SYSTEM_APP;
1485 }
1486 }
1487
1488 final LocalIntentReceiver receiver = new LocalIntentReceiver();
1489 mInterface.getPackageInstaller().uninstall(new VersionedPackage(packageName,
1490 versionCode), null /*callerPackageName*/, flags,
1491 receiver.getIntentSender(), userId);
1492
1493 final Intent result = receiver.getResult();
1494 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
1495 PackageInstaller.STATUS_FAILURE);
1496 if (status == PackageInstaller.STATUS_SUCCESS) {
1497 pw.println("Success");
1498 return 0;
1499 } else {
1500 pw.println("Failure ["
1501 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
1502 return 1;
1503 }
1504 }
1505
1506 private int runRemoveSplit(String packageName, String splitName) throws RemoteException {
1507 final PrintWriter pw = getOutPrintWriter();
1508 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING);
1509 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
1510 sessionParams.appPackageName = packageName;
1511 final int sessionId =
1512 doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL);
1513 boolean abandonSession = true;
1514 try {
1515 if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/)
1516 != PackageInstaller.STATUS_SUCCESS) {
1517 return 1;
1518 }
1519 if (doCommitSession(sessionId, false /*logSuccess*/)
1520 != PackageInstaller.STATUS_SUCCESS) {
1521 return 1;
1522 }
1523 abandonSession = false;
1524 pw.println("Success");
1525 return 0;
1526 } finally {
1527 if (abandonSession) {
1528 try {
1529 doAbandonSession(sessionId, false /*logSuccess*/);
1530 } catch (Exception ignore) {
1531 }
1532 }
1533 }
1534 }
1535
1536 static class ClearDataObserver extends IPackageDataObserver.Stub {
1537 boolean finished;
1538 boolean result;
1539
1540 @Override
1541 public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
1542 synchronized (this) {
1543 finished = true;
1544 result = succeeded;
1545 notifyAll();
1546 }
1547 }
1548 }
1549
1550 private int runClear() throws RemoteException {
1551 int userId = UserHandle.USER_SYSTEM;
1552 String option = getNextOption();
1553 if (option != null && option.equals("--user")) {
1554 userId = UserHandle.parseUserArg(getNextArgRequired());
1555 }
1556
1557 String pkg = getNextArg();
1558 if (pkg == null) {
1559 getErrPrintWriter().println("Error: no package specified");
1560 return 1;
1561 }
1562
1563 ClearDataObserver obs = new ClearDataObserver();
Christopher Tate1d99c392017-12-07 16:54:04 -08001564 ActivityManager.getService().clearApplicationUserData(pkg, false, obs, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001565 synchronized (obs) {
1566 while (!obs.finished) {
1567 try {
1568 obs.wait();
1569 } catch (InterruptedException e) {
1570 }
1571 }
1572 }
1573
1574 if (obs.result) {
1575 getOutPrintWriter().println("Success");
1576 return 0;
1577 } else {
1578 getErrPrintWriter().println("Failed");
1579 return 1;
1580 }
1581 }
1582
1583 private static String enabledSettingToString(int state) {
1584 switch (state) {
1585 case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
1586 return "default";
1587 case PackageManager.COMPONENT_ENABLED_STATE_ENABLED:
1588 return "enabled";
1589 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
1590 return "disabled";
1591 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
1592 return "disabled-user";
1593 case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
1594 return "disabled-until-used";
1595 }
1596 return "unknown";
1597 }
1598
1599 private int runSetEnabledSetting(int state) throws RemoteException {
1600 int userId = UserHandle.USER_SYSTEM;
1601 String option = getNextOption();
1602 if (option != null && option.equals("--user")) {
1603 userId = UserHandle.parseUserArg(getNextArgRequired());
1604 }
1605
1606 String pkg = getNextArg();
1607 if (pkg == null) {
1608 getErrPrintWriter().println("Error: no package or component specified");
1609 return 1;
1610 }
1611 ComponentName cn = ComponentName.unflattenFromString(pkg);
1612 if (cn == null) {
1613 mInterface.setApplicationEnabledSetting(pkg, state, 0, userId,
1614 "shell:" + android.os.Process.myUid());
1615 getOutPrintWriter().println("Package " + pkg + " new state: "
1616 + enabledSettingToString(
1617 mInterface.getApplicationEnabledSetting(pkg, userId)));
1618 return 0;
1619 } else {
1620 mInterface.setComponentEnabledSetting(cn, state, 0, userId);
1621 getOutPrintWriter().println("Component " + cn.toShortString() + " new state: "
1622 + enabledSettingToString(
1623 mInterface.getComponentEnabledSetting(cn, userId)));
1624 return 0;
1625 }
1626 }
1627
1628 private int runSetHiddenSetting(boolean state) throws RemoteException {
1629 int userId = UserHandle.USER_SYSTEM;
1630 String option = getNextOption();
1631 if (option != null && option.equals("--user")) {
1632 userId = UserHandle.parseUserArg(getNextArgRequired());
1633 }
1634
1635 String pkg = getNextArg();
1636 if (pkg == null) {
1637 getErrPrintWriter().println("Error: no package or component specified");
1638 return 1;
1639 }
1640 mInterface.setApplicationHiddenSettingAsUser(pkg, state, userId);
1641 getOutPrintWriter().println("Package " + pkg + " new hidden state: "
1642 + mInterface.getApplicationHiddenSettingAsUser(pkg, userId));
1643 return 0;
1644 }
1645
1646 private int runSuspend(boolean suspendedState) {
1647 final PrintWriter pw = getOutPrintWriter();
1648 int userId = UserHandle.USER_SYSTEM;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001649 String dialogMessage = null;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001650 final PersistableBundle appExtras = new PersistableBundle();
1651 final PersistableBundle launcherExtras = new PersistableBundle();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001652 String opt;
1653 while ((opt = getNextOption()) != null) {
1654 switch (opt) {
1655 case "--user":
1656 userId = UserHandle.parseUserArg(getNextArgRequired());
1657 break;
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001658 case "--dialogMessage":
1659 dialogMessage = getNextArgRequired();
1660 break;
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001661 case "--ael":
1662 case "--aes":
1663 case "--aed":
1664 case "--lel":
1665 case "--les":
1666 case "--led":
1667 final String key = getNextArgRequired();
1668 final String val = getNextArgRequired();
1669 if (!suspendedState) {
1670 break;
1671 }
1672 final PersistableBundle bundleToInsert =
1673 opt.startsWith("--a") ? appExtras : launcherExtras;
1674 switch (opt.charAt(4)) {
1675 case 'l':
1676 bundleToInsert.putLong(key, Long.valueOf(val));
1677 break;
1678 case 'd':
1679 bundleToInsert.putDouble(key, Double.valueOf(val));
1680 break;
1681 case 's':
1682 bundleToInsert.putString(key, val);
1683 break;
1684 }
1685 break;
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001686 default:
1687 pw.println("Error: Unknown option: " + opt);
1688 return 1;
1689 }
1690 }
1691
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001692 final String packageName = getNextArg();
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001693 if (packageName == null) {
1694 pw.println("Error: package name not specified");
1695 return 1;
1696 }
Suprabh Shukla021b57a2018-03-08 18:21:50 -08001697 final String callingPackage =
1698 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001699 try {
1700 mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
Suprabh Shukla3c3af142018-03-30 00:28:37 -07001701 appExtras, launcherExtras, dialogMessage, callingPackage, userId);
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001702 pw.println("Package " + packageName + " new suspended state: "
1703 + mInterface.isPackageSuspendedForUser(packageName, userId));
1704 return 0;
1705 } catch (RemoteException | IllegalArgumentException e) {
1706 pw.println(e.toString());
1707 return 1;
1708 }
1709 }
1710
1711 private int runGrantRevokePermission(boolean grant) throws RemoteException {
1712 int userId = UserHandle.USER_SYSTEM;
1713
1714 String opt = null;
1715 while ((opt = getNextOption()) != null) {
1716 if (opt.equals("--user")) {
1717 userId = UserHandle.parseUserArg(getNextArgRequired());
1718 }
1719 }
1720
1721 String pkg = getNextArg();
1722 if (pkg == null) {
1723 getErrPrintWriter().println("Error: no package specified");
1724 return 1;
1725 }
1726 String perm = getNextArg();
1727 if (perm == null) {
1728 getErrPrintWriter().println("Error: no permission specified");
1729 return 1;
1730 }
1731
1732 if (grant) {
1733 mInterface.grantRuntimePermission(pkg, perm, userId);
1734 } else {
1735 mInterface.revokeRuntimePermission(pkg, perm, userId);
1736 }
1737 return 0;
1738 }
1739
1740 private int runResetPermissions() throws RemoteException {
1741 mInterface.resetRuntimePermissions();
1742 return 0;
1743 }
1744
1745 private int runSetPermissionEnforced() throws RemoteException {
1746 final String permission = getNextArg();
1747 if (permission == null) {
1748 getErrPrintWriter().println("Error: no permission specified");
1749 return 1;
1750 }
1751 final String enforcedRaw = getNextArg();
1752 if (enforcedRaw == null) {
1753 getErrPrintWriter().println("Error: no enforcement specified");
1754 return 1;
1755 }
1756 mInterface.setPermissionEnforced(permission, Boolean.parseBoolean(enforcedRaw));
1757 return 0;
1758 }
1759
Jiyong Park002fdbd2017-02-13 20:50:31 +09001760 private boolean isVendorApp(String pkg) {
1761 try {
1762 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1763 return info != null && info.applicationInfo.isVendor();
1764 } catch (RemoteException e) {
1765 return false;
1766 }
1767 }
1768
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001769 private boolean isProductApp(String pkg) {
1770 try {
1771 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1772 return info != null && info.applicationInfo.isProduct();
1773 } catch (RemoteException e) {
1774 return false;
1775 }
1776 }
1777
Dario Freni2bef1762018-06-01 14:02:08 +01001778 private boolean isProductServicesApp(String pkg) {
1779 try {
1780 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
1781 return info != null && info.applicationInfo.isProductServices();
1782 } catch (RemoteException e) {
1783 return false;
1784 }
1785 }
1786
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001787 private int runGetPrivappPermissions() {
1788 final String pkg = getNextArg();
1789 if (pkg == null) {
1790 getErrPrintWriter().println("Error: no package specified.");
1791 return 1;
1792 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001793
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001794 ArraySet<String> privAppPermissions = null;
1795 if (isVendorApp(pkg)) {
1796 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
1797 } else if (isProductApp(pkg)) {
1798 privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
Dario Freni2bef1762018-06-01 14:02:08 +01001799 } else if (isProductServicesApp(pkg)) {
1800 privAppPermissions = SystemConfig.getInstance()
1801 .getProductServicesPrivAppPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001802 } else {
1803 privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
1804 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001805
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001806 getOutPrintWriter().println(privAppPermissions == null
1807 ? "{}" : privAppPermissions.toString());
1808 return 0;
1809 }
1810
1811 private int runGetPrivappDenyPermissions() {
1812 final String pkg = getNextArg();
1813 if (pkg == null) {
1814 getErrPrintWriter().println("Error: no package specified.");
1815 return 1;
1816 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001817
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001818 ArraySet<String> privAppPermissions = null;
1819 if (isVendorApp(pkg)) {
1820 privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
1821 } else if (isProductApp(pkg)) {
1822 privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
Dario Freni2bef1762018-06-01 14:02:08 +01001823 } else if (isProductServicesApp(pkg)) {
1824 privAppPermissions = SystemConfig.getInstance()
1825 .getProductServicesPrivAppDenyPermissions(pkg);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001826 } else {
1827 privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
1828 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001829
1830 getOutPrintWriter().println(privAppPermissions == null
1831 ? "{}" : privAppPermissions.toString());
Dianne Hackbornc81983a2017-10-20 16:16:32 -07001832 return 0;
1833 }
1834
1835 private int runGetOemPermissions() {
1836 final String pkg = getNextArg();
1837 if (pkg == null) {
1838 getErrPrintWriter().println("Error: no package specified.");
1839 return 1;
1840 }
1841 final Map<String, Boolean> oemPermissions = SystemConfig.getInstance()
1842 .getOemPermissions(pkg);
1843 if (oemPermissions == null || oemPermissions.isEmpty()) {
1844 getOutPrintWriter().println("{}");
1845 } else {
1846 oemPermissions.forEach((permission, granted) ->
1847 getOutPrintWriter().println(permission + " granted:" + granted)
1848 );
1849 }
1850 return 0;
1851 }
1852
1853 private String linkStateToString(int state) {
1854 switch (state) {
1855 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: return "undefined";
1856 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: return "ask";
1857 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: return "always";
1858 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: return "never";
1859 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK : return "always ask";
1860 }
1861 return "Unknown link state: " + state;
1862 }
1863
1864 // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
1865 private int runSetAppLink() throws RemoteException {
1866 int userId = UserHandle.USER_SYSTEM;
1867
1868 String opt;
1869 while ((opt = getNextOption()) != null) {
1870 if (opt.equals("--user")) {
1871 userId = UserHandle.parseUserArg(getNextArgRequired());
1872 } else {
1873 getErrPrintWriter().println("Error: unknown option: " + opt);
1874 return 1;
1875 }
1876 }
1877
1878 // Package name to act on; required
1879 final String pkg = getNextArg();
1880 if (pkg == null) {
1881 getErrPrintWriter().println("Error: no package specified.");
1882 return 1;
1883 }
1884
1885 // State to apply; {always|ask|never|undefined}, required
1886 final String modeString = getNextArg();
1887 if (modeString == null) {
1888 getErrPrintWriter().println("Error: no app link state specified.");
1889 return 1;
1890 }
1891
1892 final int newMode;
1893 switch (modeString.toLowerCase()) {
1894 case "undefined":
1895 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1896 break;
1897
1898 case "always":
1899 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1900 break;
1901
1902 case "ask":
1903 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1904 break;
1905
1906 case "always-ask":
1907 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
1908 break;
1909
1910 case "never":
1911 newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
1912 break;
1913
1914 default:
1915 getErrPrintWriter().println("Error: unknown app link state '" + modeString + "'");
1916 return 1;
1917 }
1918
1919 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1920 if (info == null) {
1921 getErrPrintWriter().println("Error: package " + pkg + " not found.");
1922 return 1;
1923 }
1924
1925 if ((info.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1926 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1927 return 1;
1928 }
1929
1930 if (!mInterface.updateIntentVerificationStatus(pkg, newMode, userId)) {
1931 getErrPrintWriter().println("Error: unable to update app link status for " + pkg);
1932 return 1;
1933 }
1934
1935 return 0;
1936 }
1937
1938 // pm get-app-link [--user USER_ID] PACKAGE
1939 private int runGetAppLink() throws RemoteException {
1940 int userId = UserHandle.USER_SYSTEM;
1941
1942 String opt;
1943 while ((opt = getNextOption()) != null) {
1944 if (opt.equals("--user")) {
1945 userId = UserHandle.parseUserArg(getNextArgRequired());
1946 } else {
1947 getErrPrintWriter().println("Error: unknown option: " + opt);
1948 return 1;
1949 }
1950 }
1951
1952 // Package name to act on; required
1953 final String pkg = getNextArg();
1954 if (pkg == null) {
1955 getErrPrintWriter().println("Error: no package specified.");
1956 return 1;
1957 }
1958
1959 final PackageInfo info = mInterface.getPackageInfo(pkg, 0, userId);
1960 if (info == null) {
1961 getErrPrintWriter().println("Error: package " + pkg + " not found.");
1962 return 1;
1963 }
1964
1965 if ((info.applicationInfo.privateFlags
1966 & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) == 0) {
1967 getErrPrintWriter().println("Error: package " + pkg + " does not handle web links.");
1968 return 1;
1969 }
1970
1971 getOutPrintWriter().println(linkStateToString(
1972 mInterface.getIntentVerificationStatus(pkg, userId)));
1973
1974 return 0;
1975 }
1976
1977 private int runTrimCaches() throws RemoteException {
1978 String size = getNextArg();
1979 if (size == null) {
1980 getErrPrintWriter().println("Error: no size specified");
1981 return 1;
1982 }
1983 long multiplier = 1;
1984 int len = size.length();
1985 char c = size.charAt(len - 1);
1986 if (c < '0' || c > '9') {
1987 if (c == 'K' || c == 'k') {
1988 multiplier = 1024L;
1989 } else if (c == 'M' || c == 'm') {
1990 multiplier = 1024L*1024L;
1991 } else if (c == 'G' || c == 'g') {
1992 multiplier = 1024L*1024L*1024L;
1993 } else {
1994 getErrPrintWriter().println("Invalid suffix: " + c);
1995 return 1;
1996 }
1997 size = size.substring(0, len-1);
1998 }
1999 long sizeVal;
2000 try {
2001 sizeVal = Long.parseLong(size) * multiplier;
2002 } catch (NumberFormatException e) {
2003 getErrPrintWriter().println("Error: expected number at: " + size);
2004 return 1;
2005 }
2006 String volumeUuid = getNextArg();
2007 if ("internal".equals(volumeUuid)) {
2008 volumeUuid = null;
2009 }
2010 ClearDataObserver obs = new ClearDataObserver();
2011 mInterface.freeStorageAndNotify(volumeUuid, sizeVal,
2012 StorageManager.FLAG_ALLOCATE_DEFY_ALL_RESERVED, obs);
2013 synchronized (obs) {
2014 while (!obs.finished) {
2015 try {
2016 obs.wait();
2017 } catch (InterruptedException e) {
2018 }
2019 }
2020 }
2021 return 0;
2022 }
2023
2024 private static boolean isNumber(String s) {
2025 try {
2026 Integer.parseInt(s);
2027 } catch (NumberFormatException nfe) {
2028 return false;
2029 }
2030 return true;
2031 }
2032
2033 public int runCreateUser() throws RemoteException {
2034 String name;
2035 int userId = -1;
2036 int flags = 0;
2037 String opt;
2038 while ((opt = getNextOption()) != null) {
2039 if ("--profileOf".equals(opt)) {
2040 userId = UserHandle.parseUserArg(getNextArgRequired());
2041 } else if ("--managed".equals(opt)) {
2042 flags |= UserInfo.FLAG_MANAGED_PROFILE;
2043 } else if ("--restricted".equals(opt)) {
2044 flags |= UserInfo.FLAG_RESTRICTED;
2045 } else if ("--ephemeral".equals(opt)) {
2046 flags |= UserInfo.FLAG_EPHEMERAL;
2047 } else if ("--guest".equals(opt)) {
2048 flags |= UserInfo.FLAG_GUEST;
2049 } else if ("--demo".equals(opt)) {
2050 flags |= UserInfo.FLAG_DEMO;
2051 } else {
2052 getErrPrintWriter().println("Error: unknown option " + opt);
2053 return 1;
2054 }
2055 }
2056 String arg = getNextArg();
2057 if (arg == null) {
2058 getErrPrintWriter().println("Error: no user name specified.");
2059 return 1;
2060 }
2061 name = arg;
2062 UserInfo info;
2063 IUserManager um = IUserManager.Stub.asInterface(
2064 ServiceManager.getService(Context.USER_SERVICE));
2065 IAccountManager accm = IAccountManager.Stub.asInterface(
2066 ServiceManager.getService(Context.ACCOUNT_SERVICE));
2067 if ((flags & UserInfo.FLAG_RESTRICTED) != 0) {
2068 // In non-split user mode, userId can only be SYSTEM
2069 int parentUserId = userId >= 0 ? userId : UserHandle.USER_SYSTEM;
2070 info = um.createRestrictedProfile(name, parentUserId);
2071 accm.addSharedAccountsFromParentUser(parentUserId, userId,
2072 (Process.myUid() == Process.ROOT_UID) ? "root" : "com.android.shell");
2073 } else if (userId < 0) {
2074 info = um.createUser(name, flags);
2075 } else {
2076 info = um.createProfileForUser(name, flags, userId, null);
2077 }
2078
2079 if (info != null) {
2080 getOutPrintWriter().println("Success: created user id " + info.id);
2081 return 0;
2082 } else {
2083 getErrPrintWriter().println("Error: couldn't create User.");
2084 return 1;
2085 }
2086 }
2087
2088 public int runRemoveUser() throws RemoteException {
2089 int userId;
2090 String arg = getNextArg();
2091 if (arg == null) {
2092 getErrPrintWriter().println("Error: no user id specified.");
2093 return 1;
2094 }
2095 userId = UserHandle.parseUserArg(arg);
2096 IUserManager um = IUserManager.Stub.asInterface(
2097 ServiceManager.getService(Context.USER_SERVICE));
2098 if (um.removeUser(userId)) {
2099 getOutPrintWriter().println("Success: removed user");
2100 return 0;
2101 } else {
2102 getErrPrintWriter().println("Error: couldn't remove user id " + userId);
2103 return 1;
2104 }
2105 }
2106
2107 public int runSetUserRestriction() throws RemoteException {
2108 int userId = UserHandle.USER_SYSTEM;
2109 String opt = getNextOption();
2110 if (opt != null && "--user".equals(opt)) {
2111 userId = UserHandle.parseUserArg(getNextArgRequired());
2112 }
2113
2114 String restriction = getNextArg();
2115 String arg = getNextArg();
2116 boolean value;
2117 if ("1".equals(arg)) {
2118 value = true;
2119 } else if ("0".equals(arg)) {
2120 value = false;
2121 } else {
2122 getErrPrintWriter().println("Error: valid value not specified");
2123 return 1;
2124 }
2125 IUserManager um = IUserManager.Stub.asInterface(
2126 ServiceManager.getService(Context.USER_SERVICE));
2127 um.setUserRestriction(restriction, value, userId);
2128 return 0;
2129 }
2130
2131 public int runGetMaxUsers() {
2132 getOutPrintWriter().println("Maximum supported users: "
2133 + UserManager.getMaxSupportedUsers());
2134 return 0;
2135 }
2136
Alex Chauc12189b2018-01-16 15:01:15 +00002137 public int runGetMaxRunningUsers() {
2138 ActivityManagerInternal activityManagerInternal =
2139 LocalServices.getService(ActivityManagerInternal.class);
2140 getOutPrintWriter().println("Maximum supported running users: "
2141 + activityManagerInternal.getMaxRunningUsers());
2142 return 0;
2143 }
2144
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002145 private static class InstallParams {
2146 SessionParams sessionParams;
2147 String installerPackageName;
2148 int userId = UserHandle.USER_ALL;
2149 }
2150
2151 private InstallParams makeInstallParams() {
2152 final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
2153 final InstallParams params = new InstallParams();
2154 params.sessionParams = sessionParams;
2155 String opt;
Patrick Baumanna9333492017-11-28 15:23:49 -08002156 boolean replaceExisting = true;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002157 while ((opt = getNextOption()) != null) {
2158 switch (opt) {
2159 case "-l":
2160 sessionParams.installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
2161 break;
Patrick Baumanna9333492017-11-28 15:23:49 -08002162 case "-r": // ignore
2163 break;
2164 case "-R":
2165 replaceExisting = false;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002166 break;
2167 case "-i":
2168 params.installerPackageName = getNextArg();
2169 if (params.installerPackageName == null) {
2170 throw new IllegalArgumentException("Missing installer package");
2171 }
2172 break;
2173 case "-t":
2174 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_TEST;
2175 break;
2176 case "-s":
2177 sessionParams.installFlags |= PackageManager.INSTALL_EXTERNAL;
2178 break;
2179 case "-f":
2180 sessionParams.installFlags |= PackageManager.INSTALL_INTERNAL;
2181 break;
2182 case "-d":
2183 sessionParams.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE;
2184 break;
2185 case "-g":
2186 sessionParams.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
2187 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002188 case "--dont-kill":
2189 sessionParams.installFlags |= PackageManager.INSTALL_DONT_KILL_APP;
2190 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002191 case "--originating-uri":
2192 sessionParams.originatingUri = Uri.parse(getNextArg());
2193 break;
2194 case "--referrer":
2195 sessionParams.referrerUri = Uri.parse(getNextArg());
2196 break;
2197 case "-p":
2198 sessionParams.mode = SessionParams.MODE_INHERIT_EXISTING;
2199 sessionParams.appPackageName = getNextArg();
2200 if (sessionParams.appPackageName == null) {
2201 throw new IllegalArgumentException("Missing inherit package name");
2202 }
2203 break;
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002204 case "--pkg":
2205 sessionParams.appPackageName = getNextArg();
2206 if (sessionParams.appPackageName == null) {
2207 throw new IllegalArgumentException("Missing package name");
2208 }
2209 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002210 case "-S":
Todd Kennedy9caf94e2016-10-12 15:26:08 -07002211 final long sizeBytes = Long.parseLong(getNextArg());
2212 if (sizeBytes <= 0) {
2213 throw new IllegalArgumentException("Size must be positive");
2214 }
2215 sessionParams.setSize(sizeBytes);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002216 break;
2217 case "--abi":
2218 sessionParams.abiOverride = checkAbiArgument(getNextArg());
2219 break;
Todd Kennedy2699f062015-11-20 13:07:17 -08002220 case "--ephemeral":
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002221 case "--instant":
Todd Kennedybe0b8892017-02-15 14:13:52 -08002222 case "--instantapp":
Todd Kennedyb7717682016-11-30 15:41:21 -08002223 sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
Todd Kennedy2699f062015-11-20 13:07:17 -08002224 break;
Todd Kennedybe0b8892017-02-15 14:13:52 -08002225 case "--full":
2226 sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
2227 break;
Todd Kennedy78a72502017-07-19 12:49:30 -07002228 case "--preload":
2229 sessionParams.setInstallAsVirtualPreload();
2230 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002231 case "--user":
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002232 params.userId = UserHandle.parseUserArg(getNextArgRequired());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002233 break;
2234 case "--install-location":
2235 sessionParams.installLocation = Integer.parseInt(getNextArg());
2236 break;
2237 case "--force-uuid":
2238 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_VOLUME_UUID;
2239 sessionParams.volumeUuid = getNextArg();
2240 if ("internal".equals(sessionParams.volumeUuid)) {
2241 sessionParams.volumeUuid = null;
2242 }
2243 break;
Todd Kennedyb1072712016-04-26 15:41:20 -07002244 case "--force-sdk":
2245 sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK;
2246 break;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002247 default:
2248 throw new IllegalArgumentException("Unknown option " + opt);
2249 }
Patrick Baumanna9333492017-11-28 15:23:49 -08002250 if (replaceExisting) {
2251 sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
2252 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002253 }
2254 return params;
2255 }
2256
Makoto Onuki4828a592016-03-15 18:06:57 -07002257 private int runSetHomeActivity() {
2258 final PrintWriter pw = getOutPrintWriter();
2259 int userId = UserHandle.USER_SYSTEM;
2260 String opt;
2261 while ((opt = getNextOption()) != null) {
2262 switch (opt) {
2263 case "--user":
2264 userId = UserHandle.parseUserArg(getNextArgRequired());
2265 break;
2266 default:
2267 pw.println("Error: Unknown option: " + opt);
2268 return 1;
2269 }
2270 }
2271
2272 String component = getNextArg();
2273 ComponentName componentName =
2274 component != null ? ComponentName.unflattenFromString(component) : null;
2275
2276 if (componentName == null) {
2277 pw.println("Error: component name not specified or invalid");
2278 return 1;
2279 }
2280
2281 try {
2282 mInterface.setHomeActivity(componentName, userId);
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002283 pw.println("Success");
Makoto Onuki4828a592016-03-15 18:06:57 -07002284 return 0;
Makoto Onuki3bdbf982016-06-23 16:56:35 -07002285 } catch (Exception e) {
Makoto Onuki4828a592016-03-15 18:06:57 -07002286 pw.println(e.toString());
2287 return 1;
2288 }
2289 }
2290
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002291 private int runSetInstaller() throws RemoteException {
2292 final String targetPackage = getNextArg();
2293 final String installerPackageName = getNextArg();
Fyodor Kupolov51245c72016-12-01 11:34:10 -08002294
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002295 if (targetPackage == null || installerPackageName == null) {
2296 getErrPrintWriter().println("Must provide both target and installer package names");
Todd Kennedy74629e32017-08-15 14:48:07 -07002297 return 1;
2298 }
Todd Kennedy74629e32017-08-15 14:48:07 -07002299
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002300 mInterface.setInstallerPackageName(targetPackage, installerPackageName);
2301 getOutPrintWriter().println("Success");
Svet Ganov087dce22017-09-07 15:42:16 -07002302 return 0;
2303 }
2304
Todd Kennedy0a3f0812017-05-08 14:43:15 -07002305 private int runGetInstantAppResolver() {
2306 final PrintWriter pw = getOutPrintWriter();
2307 try {
2308 final ComponentName instantAppsResolver = mInterface.getInstantAppResolverComponent();
2309 if (instantAppsResolver == null) {
2310 return 1;
2311 }
2312 pw.println(instantAppsResolver.flattenToString());
2313 return 0;
2314 } catch (Exception e) {
2315 pw.println(e.toString());
2316 return 1;
2317 }
2318 }
2319
Tadashi G. Takaokabe5782f2017-02-14 16:41:49 +09002320 private int runHasFeature() {
2321 final PrintWriter err = getErrPrintWriter();
2322 final String featureName = getNextArg();
2323 if (featureName == null) {
2324 err.println("Error: expected FEATURE name");
2325 return 1;
2326 }
2327 final String versionString = getNextArg();
2328 try {
2329 final int version = (versionString == null) ? 0 : Integer.parseInt(versionString);
2330 final boolean hasFeature = mInterface.hasSystemFeature(featureName, version);
2331 getOutPrintWriter().println(hasFeature);
2332 return hasFeature ? 0 : 1;
2333 } catch (NumberFormatException e) {
2334 err.println("Error: illegal version number " + versionString);
2335 return 1;
2336 } catch (RemoteException e) {
2337 err.println(e.toString());
2338 return 1;
2339 }
2340 }
2341
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002342 private int runDump() {
2343 String pkg = getNextArg();
2344 if (pkg == null) {
2345 getErrPrintWriter().println("Error: no package specified");
2346 return 1;
2347 }
2348 ActivityManager.dumpPackageStateStatic(getOutFileDescriptor(), pkg);
2349 return 0;
2350 }
2351
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002352 private int runSetHarmfulAppWarning() throws RemoteException {
2353 int userId = UserHandle.USER_CURRENT;
2354
2355 String opt;
2356 while ((opt = getNextOption()) != null) {
2357 if (opt.equals("--user")) {
2358 userId = UserHandle.parseUserArg(getNextArgRequired());
2359 } else {
2360 getErrPrintWriter().println("Error: Unknown option: " + opt);
2361 return -1;
2362 }
2363 }
2364
2365 userId = translateUserId(userId, false /*allowAll*/, "runSetHarmfulAppWarning");
2366
2367 final String packageName = getNextArgRequired();
2368 final String warning = getNextArg();
2369
2370 mInterface.setHarmfulAppWarning(packageName, warning, userId);
2371
2372 return 0;
2373 }
2374
Ben Gruver9ef60092018-01-10 11:32:30 -08002375 private int runGetHarmfulAppWarning() throws RemoteException {
2376 int userId = UserHandle.USER_CURRENT;
2377
2378 String opt;
2379 while ((opt = getNextOption()) != null) {
2380 if (opt.equals("--user")) {
2381 userId = UserHandle.parseUserArg(getNextArgRequired());
2382 } else {
2383 getErrPrintWriter().println("Error: Unknown option: " + opt);
2384 return -1;
2385 }
2386 }
2387
2388 userId = translateUserId(userId, false /*allowAll*/, "runGetHarmfulAppWarning");
2389
2390 final String packageName = getNextArgRequired();
2391 final CharSequence warning = mInterface.getHarmfulAppWarning(packageName, userId);
2392 if (!TextUtils.isEmpty(warning)) {
2393 getOutPrintWriter().println(warning);
2394 return 0;
2395 } else {
2396 return 1;
2397 }
2398 }
2399
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002400 private static String checkAbiArgument(String abi) {
2401 if (TextUtils.isEmpty(abi)) {
2402 throw new IllegalArgumentException("Missing ABI argument");
2403 }
2404
2405 if ("-".equals(abi)) {
2406 return abi;
2407 }
2408
2409 final String[] supportedAbis = Build.SUPPORTED_ABIS;
2410 for (String supportedAbi : supportedAbis) {
2411 if (supportedAbi.equals(abi)) {
2412 return abi;
2413 }
2414 }
2415
2416 throw new IllegalArgumentException("ABI " + abi + " not supported on this device");
2417 }
2418
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002419 private int translateUserId(int userId, boolean allowAll, String logContext) {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002420 return ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002421 userId, allowAll, true, logContext, "pm command");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002422 }
2423
2424 private int doCreateSession(SessionParams params, String installerPackageName, int userId)
2425 throws RemoteException {
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002426 userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002427 if (userId == UserHandle.USER_ALL) {
2428 userId = UserHandle.USER_SYSTEM;
2429 params.installFlags |= PackageManager.INSTALL_ALL_USERS;
2430 }
2431
2432 final int sessionId = mInterface.getPackageInstaller()
2433 .createSession(params, installerPackageName, userId);
2434 return sessionId;
2435 }
2436
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002437 private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName,
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002438 boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002439 PackageInstaller.Session session = null;
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002440 try {
Jeff Sharkeya651b782018-07-23 13:45:28 -06002441 final PrintWriter pw = getOutPrintWriter();
2442 final ParcelFileDescriptor fd;
2443 if (STDIN_PATH.equals(inPath)) {
2444 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2445 } else if (inPath != null) {
2446 fd = openFileForSystem(inPath, "r");
2447 if (fd == null) {
2448 return -1;
2449 }
2450 sizeBytes = fd.getStatSize();
2451 if (sizeBytes < 0) {
2452 getErrPrintWriter().println("Unable to get size of: " + inPath);
2453 return -1;
2454 }
2455 } else {
2456 fd = ParcelFileDescriptor.dup(getInFileDescriptor());
2457 }
2458 if (sizeBytes <= 0) {
2459 getErrPrintWriter().println("Error: must specify a APK size");
2460 return 1;
2461 }
2462
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002463 session = new PackageInstaller.Session(
2464 mInterface.getPackageInstaller().openSession(sessionId));
Jeff Sharkey0451de62018-02-02 11:27:21 -07002465 session.write(splitName, 0, sizeBytes, fd);
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002466
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002467 if (logSuccess) {
Jeff Sharkey0451de62018-02-02 11:27:21 -07002468 pw.println("Success: streamed " + sizeBytes + " bytes");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002469 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002470 return 0;
2471 } catch (IOException e) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -07002472 getErrPrintWriter().println("Error: failed to write; " + e.getMessage());
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002473 return 1;
2474 } finally {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002475 IoUtils.closeQuietly(session);
2476 }
2477 }
2478
Todd Kennedyeb9b0532016-03-08 10:10:54 -08002479 private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess)
2480 throws RemoteException {
2481 final PrintWriter pw = getOutPrintWriter();
2482 PackageInstaller.Session session = null;
2483 try {
2484 session = new PackageInstaller.Session(
2485 mInterface.getPackageInstaller().openSession(sessionId));
2486 session.removeSplit(splitName);
2487
2488 if (logSuccess) {
2489 pw.println("Success");
2490 }
2491 return 0;
2492 } catch (IOException e) {
2493 pw.println("Error: failed to remove split; " + e.getMessage());
2494 return 1;
2495 } finally {
2496 IoUtils.closeQuietly(session);
2497 }
2498 }
2499
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002500 private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002501 final PrintWriter pw = getOutPrintWriter();
2502 PackageInstaller.Session session = null;
2503 try {
2504 session = new PackageInstaller.Session(
2505 mInterface.getPackageInstaller().openSession(sessionId));
2506
Calin Juravle3fc56c32017-12-11 18:26:13 -08002507 // Sanity check that all .dm files match an apk.
2508 // (The installer does not support standalone .dm files and will not process them.)
2509 try {
2510 DexMetadataHelper.validateDexPaths(session.getNames());
2511 } catch (IllegalStateException | IOException e) {
2512 pw.println("Warning [Could not validate the dex paths: " + e.getMessage() + "]");
2513 }
2514
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002515 final LocalIntentReceiver receiver = new LocalIntentReceiver();
2516 session.commit(receiver.getIntentSender());
2517
2518 final Intent result = receiver.getResult();
2519 final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
2520 PackageInstaller.STATUS_FAILURE);
2521 if (status == PackageInstaller.STATUS_SUCCESS) {
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002522 if (logSuccess) {
Todd Kennedyb6e96e52016-07-20 16:27:39 -07002523 pw.println("Success");
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002524 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002525 } else {
2526 pw.println("Failure ["
2527 + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002528 }
2529 return status;
2530 } finally {
2531 IoUtils.closeQuietly(session);
2532 }
2533 }
2534
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002535 private int doAbandonSession(int sessionId, boolean logSuccess) throws RemoteException {
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002536 final PrintWriter pw = getOutPrintWriter();
2537 PackageInstaller.Session session = null;
2538 try {
2539 session = new PackageInstaller.Session(
2540 mInterface.getPackageInstaller().openSession(sessionId));
2541 session.abandon();
Todd Kennedy8d9366c2015-12-16 13:47:14 -08002542 if (logSuccess) {
2543 pw.println("Success");
2544 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002545 return 0;
2546 } finally {
2547 IoUtils.closeQuietly(session);
2548 }
2549 }
2550
Todd Kennedy60459ab2015-10-30 11:32:16 -07002551 private void doListPermissions(ArrayList<String> groupList, boolean groups, boolean labels,
2552 boolean summary, int startProtectionLevel, int endProtectionLevel)
2553 throws RemoteException {
2554 final PrintWriter pw = getOutPrintWriter();
2555 final int groupCount = groupList.size();
2556 for (int i = 0; i < groupCount; i++) {
2557 String groupName = groupList.get(i);
2558 String prefix = "";
2559 if (groups) {
2560 if (i > 0) {
2561 pw.println("");
2562 }
2563 if (groupName != null) {
2564 PermissionGroupInfo pgi =
2565 mInterface.getPermissionGroupInfo(groupName, 0 /*flags*/);
2566 if (summary) {
2567 Resources res = getResources(pgi);
2568 if (res != null) {
2569 pw.print(loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel) + ": ");
2570 } else {
2571 pw.print(pgi.name + ": ");
2572
2573 }
2574 } else {
2575 pw.println((labels ? "+ " : "") + "group:" + pgi.name);
2576 if (labels) {
2577 pw.println(" package:" + pgi.packageName);
2578 Resources res = getResources(pgi);
2579 if (res != null) {
2580 pw.println(" label:"
2581 + loadText(pgi, pgi.labelRes, pgi.nonLocalizedLabel));
2582 pw.println(" description:"
2583 + loadText(pgi, pgi.descriptionRes,
2584 pgi.nonLocalizedDescription));
2585 }
2586 }
2587 }
2588 } else {
2589 pw.println(((labels && !summary) ? "+ " : "") + "ungrouped:");
2590 }
2591 prefix = " ";
2592 }
2593 List<PermissionInfo> ps =
Jeff Sharkeyd5896632016-03-04 16:16:00 -07002594 mInterface.queryPermissionsByGroup(groupList.get(i), 0 /*flags*/).getList();
Todd Kennedy60459ab2015-10-30 11:32:16 -07002595 final int count = ps.size();
2596 boolean first = true;
2597 for (int p = 0 ; p < count ; p++) {
2598 PermissionInfo pi = ps.get(p);
2599 if (groups && groupName == null && pi.group != null) {
2600 continue;
2601 }
2602 final int base = pi.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
2603 if (base < startProtectionLevel
2604 || base > endProtectionLevel) {
2605 continue;
2606 }
2607 if (summary) {
2608 if (first) {
2609 first = false;
2610 } else {
2611 pw.print(", ");
2612 }
2613 Resources res = getResources(pi);
2614 if (res != null) {
2615 pw.print(loadText(pi, pi.labelRes,
2616 pi.nonLocalizedLabel));
2617 } else {
2618 pw.print(pi.name);
2619 }
2620 } else {
2621 pw.println(prefix + (labels ? "+ " : "")
2622 + "permission:" + pi.name);
2623 if (labels) {
2624 pw.println(prefix + " package:" + pi.packageName);
2625 Resources res = getResources(pi);
2626 if (res != null) {
2627 pw.println(prefix + " label:"
2628 + loadText(pi, pi.labelRes,
2629 pi.nonLocalizedLabel));
2630 pw.println(prefix + " description:"
2631 + loadText(pi, pi.descriptionRes,
2632 pi.nonLocalizedDescription));
2633 }
2634 pw.println(prefix + " protectionLevel:"
2635 + PermissionInfo.protectionToString(pi.protectionLevel));
2636 }
2637 }
2638 }
2639
2640 if (summary) {
2641 pw.println("");
2642 }
2643 }
2644 }
2645
2646 private String loadText(PackageItemInfo pii, int res, CharSequence nonLocalized)
2647 throws RemoteException {
2648 if (nonLocalized != null) {
2649 return nonLocalized.toString();
2650 }
2651 if (res != 0) {
2652 Resources r = getResources(pii);
2653 if (r != null) {
2654 try {
2655 return r.getString(res);
2656 } catch (Resources.NotFoundException e) {
2657 }
2658 }
2659 }
2660 return null;
2661 }
2662
2663 private Resources getResources(PackageItemInfo pii) throws RemoteException {
2664 Resources res = mResourceCache.get(pii.packageName);
2665 if (res != null) return res;
2666
2667 ApplicationInfo ai = mInterface.getApplicationInfo(pii.packageName, 0, 0);
2668 AssetManager am = new AssetManager();
2669 am.addAssetPath(ai.publicSourceDir);
2670 res = new Resources(am, null, null);
2671 mResourceCache.put(pii.packageName, res);
2672 return res;
2673 }
2674
2675 @Override
2676 public void onHelp() {
2677 final PrintWriter pw = getOutPrintWriter();
2678 pw.println("Package manager (package) commands:");
2679 pw.println(" help");
2680 pw.println(" Print this help text.");
2681 pw.println("");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002682 pw.println(" path [--user USER_ID] PACKAGE");
2683 pw.println(" Print the path to the .apk of the given PACKAGE.");
2684 pw.println("");
2685 pw.println(" dump PACKAGE");
2686 pw.println(" Print various system state associated with the given PACKAGE.");
2687 pw.println("");
2688 pw.println(" list features");
2689 pw.println(" Prints all features of the system.");
2690 pw.println("");
2691 pw.println(" has-feature FEATURE_NAME [version]");
2692 pw.println(" Prints true and returns exit status 0 when system has a FEATURE_NAME,");
2693 pw.println(" otherwise prints false and returns exit status 1");
2694 pw.println("");
2695 pw.println(" list instrumentation [-f] [TARGET-PACKAGE]");
2696 pw.println(" Prints all test packages; optionally only those targeting TARGET-PACKAGE");
2697 pw.println(" Options:");
2698 pw.println(" -f: dump the name of the .apk file containing the test package");
2699 pw.println("");
2700 pw.println(" list libraries");
2701 pw.println(" Prints all system libraries.");
2702 pw.println("");
2703 pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
2704 pw.println(" [--uid UID] [--user USER_ID] [FILTER]");
2705 pw.println(" Prints all packages; optionally only those whose name contains");
2706 pw.println(" the text in FILTER. Options are:");
2707 pw.println(" -f: see their associated file");
Andreas Gampe1f110452018-06-04 11:47:48 -07002708 pw.println(" -a: all known packages");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002709 pw.println(" -d: filter to only show disabled packages");
2710 pw.println(" -e: filter to only show enabled packages");
2711 pw.println(" -s: filter to only show system packages");
2712 pw.println(" -3: filter to only show third party packages");
2713 pw.println(" -i: see the installer for the packages");
2714 pw.println(" -l: ignored (used for compatibility with older releases)");
2715 pw.println(" -U: also show the package UID");
2716 pw.println(" -u: also include uninstalled packages");
2717 pw.println(" --uid UID: filter to only show packages with the given UID");
2718 pw.println(" --user USER_ID: only list packages belonging to the given user");
2719 pw.println("");
2720 pw.println(" list permission-groups");
2721 pw.println(" Prints all known permission groups.");
2722 pw.println("");
2723 pw.println(" list permissions [-g] [-f] [-d] [-u] [GROUP]");
2724 pw.println(" Prints all known permissions; optionally only those in GROUP. Options are:");
2725 pw.println(" -g: organize by group");
2726 pw.println(" -f: print all information");
2727 pw.println(" -s: short summary");
2728 pw.println(" -d: only list dangerous permissions");
2729 pw.println(" -u: list only the permissions users will see");
2730 pw.println("");
2731 pw.println(" resolve-activity [--brief] [--components] [--user USER_ID] INTENT");
2732 pw.println(" Prints the activity that resolves to the given INTENT.");
2733 pw.println("");
2734 pw.println(" query-activities [--brief] [--components] [--user USER_ID] INTENT");
2735 pw.println(" Prints all activities that can handle the given INTENT.");
2736 pw.println("");
2737 pw.println(" query-services [--brief] [--components] [--user USER_ID] INTENT");
2738 pw.println(" Prints all services that can handle the given INTENT.");
2739 pw.println("");
2740 pw.println(" query-receivers [--brief] [--components] [--user USER_ID] INTENT");
2741 pw.println(" Prints all broadcast receivers that can handle the given INTENT.");
2742 pw.println("");
2743 pw.println(" install [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2744 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
2745 pw.println(" [--originating-uri URI] [---referrer URI]");
2746 pw.println(" [--abi ABI_NAME] [--force-sdk]");
2747 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
2748 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES] [PATH|-]");
2749 pw.println(" Install an application. Must provide the apk data to install, either as a");
2750 pw.println(" file path or '-' to read from stdin. Options are:");
2751 pw.println(" -l: forward lock application");
Patrick Baumanna9333492017-11-28 15:23:49 -08002752 pw.println(" -R: disallow replacement of existing application");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002753 pw.println(" -t: allow test packages");
2754 pw.println(" -i: specify package name of installer owning the app");
2755 pw.println(" -s: install application on sdcard");
2756 pw.println(" -f: install application on internal flash");
2757 pw.println(" -d: allow version code downgrade (debuggable packages only)");
2758 pw.println(" -p: partial application install (new split on top of existing pkg)");
2759 pw.println(" -g: grant all runtime permissions");
2760 pw.println(" -S: size in bytes of package, required for stdin");
2761 pw.println(" --user: install under the given user.");
2762 pw.println(" --dont-kill: installing a new feature split, don't kill running app");
2763 pw.println(" --originating-uri: set URI where app was downloaded from");
2764 pw.println(" --referrer: set URI that instigated the install of the app");
2765 pw.println(" --pkg: specify expected package name of app being installed");
2766 pw.println(" --abi: override the default ABI of the platform");
2767 pw.println(" --instantapp: cause the app to be installed as an ephemeral install app");
2768 pw.println(" --full: cause the app to be installed as a non-ephemeral full app");
2769 pw.println(" --install-location: force the install location:");
2770 pw.println(" 0=auto, 1=internal only, 2=prefer external");
2771 pw.println(" --force-uuid: force install on to disk volume with given UUID");
2772 pw.println(" --force-sdk: allow install even when existing app targets platform");
2773 pw.println(" codename but new one targets a final API level");
2774 pw.println("");
2775 pw.println(" install-create [-lrtsfdg] [-i PACKAGE] [--user USER_ID|all|current]");
2776 pw.println(" [-p INHERIT_PACKAGE] [--install-location 0/1/2]");
2777 pw.println(" [--originating-uri URI] [---referrer URI]");
2778 pw.println(" [--abi ABI_NAME] [--force-sdk]");
2779 pw.println(" [--preload] [--instantapp] [--full] [--dont-kill]");
2780 pw.println(" [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
2781 pw.println(" Like \"install\", but starts an install session. Use \"install-write\"");
2782 pw.println(" to push data into the session, and \"install-commit\" to finish.");
2783 pw.println("");
2784 pw.println(" install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH|-]");
2785 pw.println(" Write an apk into the given install session. If the path is '-', data");
2786 pw.println(" will be read from stdin. Options are:");
2787 pw.println(" -S: size in bytes of package, required for stdin");
2788 pw.println("");
2789 pw.println(" install-commit SESSION_ID");
2790 pw.println(" Commit the given active install session, installing the app.");
2791 pw.println("");
2792 pw.println(" install-abandon SESSION_ID");
2793 pw.println(" Delete the given active install session.");
2794 pw.println("");
2795 pw.println(" set-install-location LOCATION");
2796 pw.println(" Changes the default install location. NOTE this is only intended for debugging;");
2797 pw.println(" using this can cause applications to break and other undersireable behavior.");
2798 pw.println(" LOCATION is one of:");
2799 pw.println(" 0 [auto]: Let system decide the best location");
2800 pw.println(" 1 [internal]: Install on internal device storage");
2801 pw.println(" 2 [external]: Install on external media");
2802 pw.println("");
2803 pw.println(" get-install-location");
2804 pw.println(" Returns the current install location: 0, 1 or 2 as per set-install-location.");
2805 pw.println("");
2806 pw.println(" move-package PACKAGE [internal|UUID]");
2807 pw.println("");
2808 pw.println(" move-primary-storage [internal|UUID]");
2809 pw.println("");
2810 pw.println(" pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE [SPLIT]");
2811 pw.println(" Remove the given package name from the system. May remove an entire app");
2812 pw.println(" if no SPLIT name is specified, otherwise will remove only the split of the");
2813 pw.println(" given app. Options are:");
2814 pw.println(" -k: keep the data and cache directories around after package removal.");
2815 pw.println(" --user: remove the app from the given user.");
2816 pw.println(" --versionCode: only uninstall if the app has the given version code.");
2817 pw.println("");
2818 pw.println(" clear [--user USER_ID] PACKAGE");
2819 pw.println(" Deletes all data associated with a package.");
2820 pw.println("");
2821 pw.println(" enable [--user USER_ID] PACKAGE_OR_COMPONENT");
2822 pw.println(" disable [--user USER_ID] PACKAGE_OR_COMPONENT");
2823 pw.println(" disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
2824 pw.println(" disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
2825 pw.println(" default-state [--user USER_ID] PACKAGE_OR_COMPONENT");
2826 pw.println(" These commands change the enabled state of a given package or");
2827 pw.println(" component (written as \"package/class\").");
2828 pw.println("");
2829 pw.println(" hide [--user USER_ID] PACKAGE_OR_COMPONENT");
2830 pw.println(" unhide [--user USER_ID] PACKAGE_OR_COMPONENT");
2831 pw.println("");
2832 pw.println(" suspend [--user USER_ID] TARGET-PACKAGE");
2833 pw.println(" Suspends the specified package (as user).");
2834 pw.println("");
2835 pw.println(" unsuspend [--user USER_ID] TARGET-PACKAGE");
2836 pw.println(" Unsuspends the specified package (as user).");
2837 pw.println("");
2838 pw.println(" grant [--user USER_ID] PACKAGE PERMISSION");
2839 pw.println(" revoke [--user USER_ID] PACKAGE PERMISSION");
2840 pw.println(" These commands either grant or revoke permissions to apps. The permissions");
2841 pw.println(" must be declared as used in the app's manifest, be runtime permissions");
2842 pw.println(" (protection level dangerous), and the app targeting SDK greater than Lollipop MR1.");
2843 pw.println("");
2844 pw.println(" reset-permissions");
2845 pw.println(" Revert all runtime permissions to their default state.");
2846 pw.println("");
2847 pw.println(" set-permission-enforced PERMISSION [true|false]");
2848 pw.println("");
2849 pw.println(" get-privapp-permissions TARGET-PACKAGE");
2850 pw.println(" Prints all privileged permissions for a package.");
2851 pw.println("");
2852 pw.println(" get-privapp-deny-permissions TARGET-PACKAGE");
2853 pw.println(" Prints all privileged permissions that are denied for a package.");
2854 pw.println("");
2855 pw.println(" get-oem-permissions TARGET-PACKAGE");
2856 pw.println(" Prints all OEM permissions for a package.");
2857 pw.println("");
2858 pw.println(" set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}");
2859 pw.println(" get-app-link [--user USER_ID] PACKAGE");
2860 pw.println("");
2861 pw.println(" trim-caches DESIRED_FREE_SPACE [internal|UUID]");
2862 pw.println(" Trim cache files to reach the given free space.");
2863 pw.println("");
2864 pw.println(" create-user [--profileOf USER_ID] [--managed] [--restricted] [--ephemeral]");
2865 pw.println(" [--guest] USER_NAME");
2866 pw.println(" Create a new user with the given USER_NAME, printing the new user identifier");
2867 pw.println(" of the user.");
2868 pw.println("");
2869 pw.println(" remove-user USER_ID");
2870 pw.println(" Remove the user with the given USER_IDENTIFIER, deleting all data");
2871 pw.println(" associated with that user");
2872 pw.println("");
2873 pw.println(" set-user-restriction [--user USER_ID] RESTRICTION VALUE");
2874 pw.println("");
2875 pw.println(" get-max-users");
2876 pw.println("");
Alex Chauc12189b2018-01-16 15:01:15 +00002877 pw.println(" get-max-running-users");
2878 pw.println("");
Calin Juravleb6f844d2017-07-17 15:23:21 -07002879 pw.println(" compile [-m MODE | -r REASON] [-f] [-c] [--split SPLIT_NAME]");
Richard Uhler568a9692016-05-03 16:02:52 -07002880 pw.println(" [--reset] [--check-prof (true | false)] (-a | TARGET-PACKAGE)");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002881 pw.println(" Trigger compilation of TARGET-PACKAGE or all packages if \"-a\". Options are:");
David Brazdil990fb6b2016-03-01 10:02:27 +00002882 pw.println(" -a: compile all packages");
David Brazdil9aa6db02016-03-08 12:57:12 +00002883 pw.println(" -c: clear profile data before compiling");
2884 pw.println(" -f: force compilation even if not needed");
David Brazdil493411a2016-02-01 13:48:46 +00002885 pw.println(" -m: select compilation mode");
Richard Uhler568a9692016-05-03 16:02:52 -07002886 pw.println(" MODE is one of the dex2oat compiler filters:");
Nicolas Geoffrayd1326522017-04-25 12:29:07 +01002887 pw.println(" assume-verified");
2888 pw.println(" extract");
2889 pw.println(" verify");
2890 pw.println(" quicken");
Richard Uhler568a9692016-05-03 16:02:52 -07002891 pw.println(" space-profile");
2892 pw.println(" space");
2893 pw.println(" speed-profile");
2894 pw.println(" speed");
2895 pw.println(" everything");
2896 pw.println(" -r: select compilation reason");
2897 pw.println(" REASON is one of:");
2898 for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
2899 pw.println(" " + PackageManagerServiceCompilerMapping.REASON_STRINGS[i]);
2900 }
David Brazdilcf046952016-03-08 16:40:20 +00002901 pw.println(" --reset: restore package to its post-install state");
Richard Uhler568a9692016-05-03 16:02:52 -07002902 pw.println(" --check-prof (true | false): look at profiles when doing dexopt?");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08002903 pw.println(" --secondary-dex: compile app secondary dex files");
Calin Juravleb6f844d2017-07-17 15:23:21 -07002904 pw.println(" --split SPLIT: compile only the given split name");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002905 pw.println("");
2906 pw.println(" force-dex-opt PACKAGE");
2907 pw.println(" Force immediate execution of dex opt for the given PACKAGE.");
2908 pw.println("");
Calin Juravlecb5f41e2017-01-25 17:16:08 -08002909 pw.println(" bg-dexopt-job");
2910 pw.println(" Execute the background optimizations immediately.");
2911 pw.println(" Note that the command only runs the background optimizer logic. It may");
2912 pw.println(" overlap with the actual job but the job scheduler will not be able to");
2913 pw.println(" cancel it. It will also run even if the device is not in the idle");
2914 pw.println(" maintenance mode.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002915 pw.println("");
Calin Juravle1aa5f882017-01-25 01:05:50 -08002916 pw.println(" reconcile-secondary-dex-files TARGET-PACKAGE");
2917 pw.println(" Reconciles the package secondary dex files with the generated oat files.");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002918 pw.println("");
David Sehrcae13b02016-06-07 09:11:27 -07002919 pw.println(" dump-profiles TARGET-PACKAGE");
2920 pw.println(" Dumps method/class profile files to");
Calin Juravle21216c62018-05-04 17:35:29 -07002921 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION + "TARGET-PACKAGE.txt");
2922 pw.println("");
2923 pw.println(" snapshot-profile TARGET-PACKAGE [--code-path path]");
2924 pw.println(" Take a snapshot of the package profiles to");
2925 pw.println(" " + ART_PROFILE_SNAPSHOT_DEBUG_LOCATION
2926 + "TARGET-PACKAGE[-code-path].prof");
2927 pw.println(" If TARGET-PACKAGE=android it will take a snapshot of the boot image");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002928 pw.println("");
Makoto Onuki4828a592016-03-15 18:06:57 -07002929 pw.println(" set-home-activity [--user USER_ID] TARGET-COMPONENT");
Dianne Hackbornc81983a2017-10-20 16:16:32 -07002930 pw.println(" Set the default home activity (aka launcher).");
2931 pw.println("");
2932 pw.println(" set-installer PACKAGE INSTALLER");
2933 pw.println(" Set installer package name");
2934 pw.println("");
2935 pw.println(" get-instantapp-resolver");
2936 pw.println(" Return the name of the component that is the current instant app installer.");
Ben Gruver1ab3d6e2017-12-07 13:45:08 -08002937 pw.println("");
2938 pw.println(" set-harmful-app-warning [--user <USER_ID>] <PACKAGE> [<WARNING>]");
2939 pw.println(" Mark the app as harmful with the given warning message.");
Ben Gruver9ef60092018-01-10 11:32:30 -08002940 pw.println("");
2941 pw.println(" get-harmful-app-warning [--user <USER_ID>] <PACKAGE>");
2942 pw.println(" Return the harmful app warning message for the given app, if present");
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002943 pw.println();
Patrick Baumanna980e142018-02-12 11:45:23 -08002944 pw.println(" uninstall-system-updates");
2945 pw.println(" Remove updates to all system applications and fall back to their /system " +
2946 "version.");
2947 pw.println();
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08002948 Intent.printIntentArgsHelp(pw , "");
Todd Kennedy60459ab2015-10-30 11:32:16 -07002949 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002950
2951 private static class LocalIntentReceiver {
wangmingming155414292018-04-10 09:35:25 +08002952 private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>();
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002953
2954 private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
2955 @Override
Dianne Hackborn98305522017-05-05 17:53:53 -07002956 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002957 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
2958 try {
2959 mResult.offer(intent, 5, TimeUnit.SECONDS);
2960 } catch (InterruptedException e) {
2961 throw new RuntimeException(e);
2962 }
Todd Kennedy72cfcd02015-11-03 17:08:55 -08002963 }
2964 };
2965
2966 public IntentSender getIntentSender() {
2967 return new IntentSender((IIntentSender) mLocalSender);
2968 }
2969
2970 public Intent getResult() {
2971 try {
2972 return mResult.take();
2973 } catch (InterruptedException e) {
2974 throw new RuntimeException(e);
2975 }
2976 }
2977 }
Todd Kennedy60459ab2015-10-30 11:32:16 -07002978}