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