1 /* 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 17 package com.android.server.am; 18 19 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; 20 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; 21 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; 22 import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; 23 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; 24 import static android.app.ActivityTaskManager.INVALID_TASK_ID; 25 import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM; 26 import static android.app.ActivityTaskManager.RESIZE_MODE_USER; 27 import static android.app.WaitResult.launchStateToString; 28 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 29 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 30 import static android.app.usage.UsageStatsManager.REASON_MAIN_FORCED_BY_USER; 31 import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED; 32 import static android.content.pm.PackageManager.MATCH_ANY_USER; 33 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; 34 import static android.os.Process.INVALID_UID; 35 import static android.view.Display.INVALID_DISPLAY; 36 import static android.window.DisplayAreaOrganizer.FEATURE_UNDEFINED; 37 38 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 39 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW; 40 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE; 41 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL; 42 import static com.android.media.flags.Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange; 43 import static com.android.media.flags.Flags.FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE; 44 import static com.android.server.am.ActivityManagerDebugConfig.LOG_WRITER_INFO; 45 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 46 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 47 import static com.android.server.am.AppBatteryTracker.BatteryUsage.BATTERY_USAGE_COUNT; 48 import static com.android.server.am.LowMemDetector.ADJ_MEM_FACTOR_NOTHING; 49 50 import android.annotation.UserIdInt; 51 import android.app.Activity; 52 import android.app.ActivityManager; 53 import android.app.ActivityManagerInternal; 54 import android.app.ActivityOptions; 55 import android.app.ActivityTaskManager; 56 import android.app.ActivityTaskManager.RootTaskInfo; 57 import android.app.AppGlobals; 58 import android.app.BroadcastOptions; 59 import android.app.ForegroundServiceDelegationOptions; 60 import android.app.IActivityController; 61 import android.app.IActivityManager; 62 import android.app.IActivityTaskManager; 63 import android.app.IProcessObserver; 64 import android.app.IStopUserCallback; 65 import android.app.IUserSwitchObserver; 66 import android.app.KeyguardManager; 67 import android.app.ProcessStateEnum; 68 import android.app.ProfilerInfo; 69 import android.app.RemoteServiceException.CrashedByAdbException; 70 import android.app.UidObserver; 71 import android.app.UserSwitchObserver; 72 import android.app.WaitResult; 73 import android.app.usage.AppStandbyInfo; 74 import android.app.usage.ConfigurationStats; 75 import android.app.usage.IUsageStatsManager; 76 import android.app.usage.UsageStatsManager; 77 import android.compat.Compatibility; 78 import android.content.ComponentCallbacks2; 79 import android.content.ComponentName; 80 import android.content.Context; 81 import android.content.DeviceConfigurationProto; 82 import android.content.GlobalConfigurationProto; 83 import android.content.IIntentReceiver; 84 import android.content.Intent; 85 import android.content.pm.ConfigurationInfo; 86 import android.content.pm.FeatureInfo; 87 import android.content.pm.IPackageManager; 88 import android.content.pm.PackageManager; 89 import android.content.pm.ParceledListSlice; 90 import android.content.pm.ResolveInfo; 91 import android.content.pm.SharedLibraryInfo; 92 import android.content.pm.UserInfo; 93 import android.content.res.AssetManager; 94 import android.content.res.Configuration; 95 import android.content.res.Resources; 96 import android.graphics.Rect; 97 import android.hardware.display.DisplayManager; 98 import android.opengl.GLES10; 99 import android.os.Binder; 100 import android.os.Build; 101 import android.os.Bundle; 102 import android.os.Debug; 103 import android.os.IProgressListener; 104 import android.os.ParcelFileDescriptor; 105 import android.os.RemoteCallback; 106 import android.os.RemoteCallback.OnResultListener; 107 import android.os.RemoteException; 108 import android.os.ServiceManager; 109 import android.os.ShellCommand; 110 import android.os.StrictMode; 111 import android.os.SystemClock; 112 import android.os.Trace; 113 import android.os.UserHandle; 114 import android.os.UserManager; 115 import android.os.ZygoteProcess; 116 import android.text.TextUtils; 117 import android.util.ArrayMap; 118 import android.util.ArraySet; 119 import android.util.DebugUtils; 120 import android.util.DisplayMetrics; 121 import android.util.SparseArray; 122 import android.util.TeeWriter; 123 import android.util.proto.ProtoOutputStream; 124 import android.view.Choreographer; 125 import android.view.Display; 126 import android.window.SplashScreen; 127 128 import com.android.internal.compat.CompatibilityChangeConfig; 129 import com.android.internal.util.MemInfoReader; 130 import com.android.server.LocalServices; 131 import com.android.server.am.LowMemDetector.MemFactor; 132 import com.android.server.am.nano.Capabilities; 133 import com.android.server.am.nano.Capability; 134 import com.android.server.am.nano.FrameworkCapability; 135 import com.android.server.am.nano.VMCapability; 136 import com.android.server.am.nano.VMInfo; 137 import com.android.server.compat.PlatformCompat; 138 import com.android.server.pm.UserManagerInternal; 139 import com.android.server.utils.AnrTimer; 140 import com.android.server.utils.Slogf; 141 142 import dalvik.annotation.optimization.NeverCompile; 143 144 import java.io.BufferedReader; 145 import java.io.IOException; 146 import java.io.InputStream; 147 import java.io.InputStreamReader; 148 import java.io.PrintWriter; 149 import java.net.URISyntaxException; 150 import java.time.Clock; 151 import java.time.LocalDateTime; 152 import java.time.format.DateTimeFormatter; 153 import java.util.ArrayList; 154 import java.util.Arrays; 155 import java.util.Collections; 156 import java.util.Comparator; 157 import java.util.HashSet; 158 import java.util.List; 159 import java.util.Locale; 160 import java.util.Set; 161 import java.util.concurrent.CountDownLatch; 162 import java.util.concurrent.TimeUnit; 163 164 import javax.microedition.khronos.egl.EGL10; 165 import javax.microedition.khronos.egl.EGLConfig; 166 import javax.microedition.khronos.egl.EGLContext; 167 import javax.microedition.khronos.egl.EGLDisplay; 168 import javax.microedition.khronos.egl.EGLSurface; 169 170 final class ActivityManagerShellCommand extends ShellCommand { 171 172 static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerShellCommand" : TAG_AM; 173 174 175 public static final String NO_CLASS_ERROR_CODE = "Error type 3"; 176 177 private static final String SHELL_PACKAGE_NAME = "com.android.shell"; 178 179 private static final int USER_OPERATION_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes 180 181 private static final DateTimeFormatter LOG_NAME_TIME_FORMATTER = 182 DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss", Locale.ROOT); 183 184 private static final String PROFILER_OUTPUT_VERSION_FLAG = "--profiler-output-version"; 185 186 // IPC interface to activity manager -- don't need to do additional security checks. 187 final IActivityManager mInterface; 188 final IActivityTaskManager mTaskInterface; 189 190 // Internal service impl -- must perform security checks before touching. 191 final ActivityManagerService mInternal; 192 193 // Convenience for interacting with package manager. 194 final IPackageManager mPm; 195 196 private int mStartFlags = 0; 197 private boolean mWaitOption = false; 198 private boolean mStopOption = false; 199 200 private int mRepeat = 0; 201 private int mUserId; 202 private String mReceiverPermission; 203 204 private String mProfileFile; 205 private int mSamplingInterval; 206 private boolean mAutoStop; 207 private boolean mStreaming; // Streaming the profiling output to a file. 208 private String mAgent; // Agent to attach on startup. 209 private boolean mAttachAgentDuringBind; // Whether agent should be attached late. 210 private int mClockType; // Whether we need thread cpu / wall clock / both. 211 private int mProfilerOutputVersion; // The version of the profiler output. 212 private int mDisplayId; 213 private int mTaskDisplayAreaFeatureId; 214 private int mWindowingMode; 215 private int mActivityType; 216 private int mTaskId; 217 private boolean mIsTaskOverlay; 218 private boolean mIsLockTask; 219 private boolean mAsync; 220 private BroadcastOptions mBroadcastOptions; 221 private boolean mShowSplashScreen; 222 private boolean mDismissKeyguardIfInsecure; 223 224 final boolean mDumping; 225 226 private static final String[] CAPABILITIES = {"start.suspend"}; 227 228 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping)229 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) { 230 mInterface = service; 231 mTaskInterface = service.mActivityTaskManager; 232 mInternal = service; 233 mPm = AppGlobals.getPackageManager(); 234 mDumping = dumping; 235 } 236 237 @Override onCommand(String cmd)238 public int onCommand(String cmd) { 239 if (cmd == null) { 240 return handleDefaultCommands(cmd); 241 } 242 final PrintWriter pw = getOutPrintWriter(); 243 try { 244 switch (cmd) { 245 case "help": 246 onHelp(); 247 return 0; 248 case "start": 249 case "start-activity": 250 return runStartActivity(pw); 251 case "start-in-vsync": 252 final ProgressWaiter waiter = new ProgressWaiter(0); 253 final int[] startResult = new int[1]; 254 startResult[0] = -1; 255 mInternal.mUiHandler.runWithScissors( 256 () -> Choreographer.getInstance().postFrameCallback(frameTimeNanos -> { 257 try { 258 startResult[0] = runStartActivity(pw); 259 waiter.onFinished(0, null /* extras */); 260 } catch (Exception ex) { 261 getErrPrintWriter().println( 262 "Error: unable to start activity, " + ex); 263 } 264 }), 265 USER_OPERATION_TIMEOUT_MS / 2); 266 waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS); 267 return startResult[0]; 268 case "startservice": 269 case "start-service": 270 return runStartService(pw, false); 271 case "startforegroundservice": 272 case "startfgservice": 273 case "start-foreground-service": 274 case "start-fg-service": 275 return runStartService(pw, true); 276 case "stopservice": 277 case "stop-service": 278 return runStopService(pw); 279 case "broadcast": 280 return runSendBroadcast(pw); 281 case "compact": 282 return runCompact(pw); 283 case "freeze": 284 return runFreeze(pw, true); 285 case "unfreeze": 286 return runFreeze(pw, false); 287 case "instrument": 288 getOutPrintWriter().println("Error: must be invoked through 'am instrument'."); 289 return -1; 290 case "trace-ipc": 291 return runTraceIpc(pw); 292 case "trace-timer": 293 return runTraceTimer(pw); 294 case "profile": 295 return runProfile(pw); 296 case "dumpheap": 297 return runDumpHeap(pw); 298 case "set-debug-app": 299 return runSetDebugApp(pw); 300 case "set-agent-app": 301 return runSetAgentApp(pw); 302 case "clear-debug-app": 303 return runClearDebugApp(pw); 304 case "set-watch-heap": 305 return runSetWatchHeap(pw); 306 case "clear-watch-heap": 307 return runClearWatchHeap(pw); 308 case "clear-start-info": 309 return runClearStartInfo(pw); 310 case "start-info-detailed-monitoring": 311 return runStartInfoDetailedMonitoring(pw); 312 case "clear-exit-info": 313 return runClearExitInfo(pw); 314 case "bug-report": 315 return runBugReport(pw); 316 case "force-stop": 317 return runForceStop(pw); 318 case "stop-app": 319 return runStopApp(pw); 320 case "clear-recent-apps": 321 return runClearRecentApps(pw); 322 case "fgs-notification-rate-limit": 323 return runFgsNotificationRateLimit(pw); 324 case "crash": 325 return runCrash(pw); 326 case "kill": 327 return runKill(pw); 328 case "kill-all": 329 return runKillAll(pw); 330 case "make-uid-idle": 331 return runMakeIdle(pw); 332 case "set-deterministic-uid-idle": 333 return runSetDeterministicUidIdle(pw); 334 case "monitor": 335 return runMonitor(pw); 336 case "watch-uids": 337 return runWatchUids(pw); 338 case "hang": 339 return runHang(pw); 340 case "restart": 341 return runRestart(pw); 342 case "idle-maintenance": 343 return runIdleMaintenance(pw); 344 case "screen-compat": 345 return runScreenCompat(pw); 346 case "package-importance": 347 return runPackageImportance(pw); 348 case "to-uri": 349 return runToUri(pw, 0); 350 case "to-intent-uri": 351 return runToUri(pw, Intent.URI_INTENT_SCHEME); 352 case "to-app-uri": 353 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME); 354 case "switch-user": 355 return runSwitchUser(pw); 356 case "get-current-user": 357 return runGetCurrentUser(pw); 358 case "start-user": 359 return runStartUser(pw); 360 case "unlock-user": 361 return runUnlockUser(pw); 362 case "stop-user": 363 return runStopUser(pw); 364 case "is-user-stopped": 365 return runIsUserStopped(pw); 366 case "get-started-user-state": 367 return runGetStartedUserState(pw); 368 case "track-associations": 369 return runTrackAssociations(pw); 370 case "untrack-associations": 371 return runUntrackAssociations(pw); 372 case "get-uid-state": 373 return getUidState(pw); 374 case "get-config": 375 return runGetConfig(pw); 376 case "suppress-resize-config-changes": 377 return runSuppressResizeConfigChanges(pw); 378 case "set-inactive": 379 return runSetInactive(pw); 380 case "get-inactive": 381 return runGetInactive(pw); 382 case "set-standby-bucket": 383 return runSetStandbyBucket(pw); 384 case "get-standby-bucket": 385 return runGetStandbyBucket(pw); 386 case "send-trim-memory": 387 return runSendTrimMemory(pw); 388 case "display": 389 return runDisplay(pw); 390 case "stack": 391 return runStack(pw); 392 case "task": 393 return runTask(pw); 394 case "write": 395 return runWrite(pw); 396 case "attach-agent": 397 return runAttachAgent(pw); 398 case "supports-multiwindow": 399 return runSupportsMultiwindow(pw); 400 case "supports-split-screen-multi-window": 401 return runSupportsSplitScreenMultiwindow(pw); 402 case "update-appinfo": 403 return runUpdateApplicationInfo(pw); 404 case "no-home-screen": 405 return runNoHomeScreen(pw); 406 case "wait-for-broadcast-idle": 407 return runWaitForBroadcastIdle(pw); 408 case "wait-for-broadcast-barrier": 409 return runWaitForBroadcastBarrier(pw); 410 case "wait-for-application-barrier": 411 return runWaitForApplicationBarrier(pw); 412 case "wait-for-broadcast-dispatch": 413 return runWaitForBroadcastDispatch(pw); 414 case "set-ignore-delivery-group-policy": 415 return runSetIgnoreDeliveryGroupPolicy(pw); 416 case "clear-ignore-delivery-group-policy": 417 return runClearIgnoreDeliveryGroupPolicy(pw); 418 case "compat": 419 return runCompat(pw); 420 case "refresh-settings-cache": 421 return runRefreshSettingsCache(); 422 case "memory-factor": 423 return runMemoryFactor(pw); 424 case "service-restart-backoff": 425 return runServiceRestartBackoff(pw); 426 case "get-isolated-pids": 427 return runGetIsolatedProcesses(pw); 428 case "set-stop-user-on-switch": 429 return runSetStopUserOnSwitch(pw); 430 case "set-bg-abusive-uids": 431 return runSetBgAbusiveUids(pw); 432 case "list-bg-exemptions-config": 433 return runListBgExemptionsConfig(pw); 434 case "set-bg-restriction-level": 435 return runSetBgRestrictionLevel(pw); 436 case "get-bg-restriction-level": 437 return runGetBgRestrictionLevel(pw); 438 case "observe-foreground-process": 439 return runGetCurrentForegroundProcess(pw, mInternal); 440 case "reset-dropbox-rate-limiter": 441 return runResetDropboxRateLimiter(); 442 case "list-displays-for-starting-users": 443 return runListDisplaysForStartingUsers(pw); 444 case "set-foreground-service-delegate": 445 return runSetForegroundServiceDelegate(pw); 446 case "capabilities": 447 return runCapabilities(pw); 448 case "set-app-zygote-preload-timeout": 449 return runSetAppZygotePreloadTimeout(pw); 450 case "set-media-foreground-service": 451 return runSetMediaForegroundService(pw); 452 case "clear-bad-process": 453 return runClearBadProcess(pw); 454 default: 455 return handleDefaultCommands(cmd); 456 } 457 } catch (RemoteException e) { 458 pw.println("Remote exception: " + e); 459 } 460 return -1; 461 } 462 runSetMediaForegroundService(PrintWriter pw)463 int runSetMediaForegroundService(PrintWriter pw) throws RemoteException { 464 mInternal.enforceCallingPermission( 465 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE, 466 "runSetMediaForegroundService()"); 467 final PrintWriter err = getErrPrintWriter(); 468 if (!enableNotifyingActivityManagerWithMediaSessionStatusChange()) { 469 err.println("Error: flag " 470 + FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE 471 + " not enabled"); 472 return -1; 473 } 474 int userId = UserHandle.USER_CURRENT; 475 final String cmd = getNextArgRequired(); 476 if ("inactive".equals(cmd) || "active".equals(cmd)) { 477 String opt; 478 while ((opt = getNextOption()) != null) { 479 if (opt.equals("--user")) { 480 userId = UserHandle.parseUserArg(getNextArgRequired()); 481 if (userId == UserHandle.USER_ALL) { 482 err.println( 483 "Error: Can't set media fgs with user 'all'"); 484 return -1; 485 } 486 } else { 487 err.println("Error: Unknown option: " + opt); 488 return -1; 489 } 490 } 491 final String pkgName = getNextArgRequired(); 492 final int notificationId = Integer.parseInt(getNextArgRequired()); 493 if (notificationId == 0) { 494 err.println("Error: notification id cannot be zero"); 495 return -1; 496 } 497 if ("inactive".equals(cmd)) { 498 mInternal.mInternal.notifyInactiveMediaForegroundService(pkgName, 499 userId, notificationId); 500 } else { 501 mInternal.mInternal.notifyActiveMediaForegroundService(pkgName, 502 userId, notificationId); 503 } 504 return 0; 505 } 506 err.println("Error: Unknown set-media-foreground-service command: " + cmd); 507 return -1; 508 } 509 runSetAppZygotePreloadTimeout(PrintWriter pw)510 int runSetAppZygotePreloadTimeout(PrintWriter pw) throws RemoteException { 511 final String timeout = getNextArgRequired(); 512 final int timeoutMs = Integer.parseInt(timeout); 513 514 ZygoteProcess.setAppZygotePreloadTimeout(timeoutMs); 515 516 return 0; 517 } 518 runCapabilities(PrintWriter pw)519 int runCapabilities(PrintWriter pw) throws RemoteException { 520 final PrintWriter err = getErrPrintWriter(); 521 boolean outputAsProtobuf = false; 522 523 String opt; 524 while ((opt = getNextOption()) != null) { 525 if (opt.equals("--protobuf")) { 526 outputAsProtobuf = true; 527 } else { 528 err.println("Error: Unknown option: " + opt); 529 return -1; 530 } 531 } 532 String vmName = System.getProperty("java.vm.name", "?"); 533 String vmVersion = System.getProperty("java.vm.version", "?"); 534 535 if (outputAsProtobuf) { 536 Capabilities capabilities = new Capabilities(); 537 capabilities.values = new Capability[CAPABILITIES.length]; 538 for (int i = 0; i < CAPABILITIES.length; i++) { 539 Capability cap = new Capability(); 540 cap.name = CAPABILITIES[i]; 541 capabilities.values[i] = cap; 542 } 543 544 String[] vmCapabilities = Debug.getVmFeatureList(); 545 capabilities.vmCapabilities = new VMCapability[vmCapabilities.length]; 546 for (int i = 0; i < vmCapabilities.length; i++) { 547 VMCapability cap = new VMCapability(); 548 cap.name = vmCapabilities[i]; 549 capabilities.vmCapabilities[i] = cap; 550 } 551 552 String[] fmCapabilities = Debug.getFeatureList(); 553 capabilities.frameworkCapabilities = new FrameworkCapability[fmCapabilities.length]; 554 for (int i = 0; i < fmCapabilities.length; i++) { 555 FrameworkCapability cap = new FrameworkCapability(); 556 cap.name = fmCapabilities[i]; 557 capabilities.frameworkCapabilities[i] = cap; 558 } 559 560 VMInfo vmInfo = new VMInfo(); 561 vmInfo.name = vmName; 562 vmInfo.version = vmVersion; 563 capabilities.vmInfo = vmInfo; 564 565 try { 566 getRawOutputStream().write(Capabilities.toByteArray(capabilities)); 567 } catch (IOException e) { 568 pw.println("Error while serializing capabilities protobuffer"); 569 } 570 571 } else { 572 // Unfortunately we don't have protobuf text format capabilities here. 573 // Fallback to line separated list instead for text parser. 574 pw.println("Format: 2"); 575 for (String capability : CAPABILITIES) { 576 pw.println(capability); 577 } 578 for (String capability : Debug.getVmFeatureList()) { 579 pw.println("vm:" + capability); 580 } 581 for (String capability : Debug.getFeatureList()) { 582 pw.println("framework:" + capability); 583 } 584 pw.println("vm_name:" + vmName); 585 pw.println("vm_version:" + vmVersion); 586 } 587 return 0; 588 } 589 makeIntent(int defUser)590 private Intent makeIntent(int defUser) throws URISyntaxException { 591 mStartFlags = 0; 592 mWaitOption = false; 593 mStopOption = false; 594 mRepeat = 0; 595 mProfileFile = null; 596 mSamplingInterval = 0; 597 mAutoStop = false; 598 mStreaming = false; 599 mUserId = defUser; 600 mDisplayId = INVALID_DISPLAY; 601 mTaskDisplayAreaFeatureId = FEATURE_UNDEFINED; 602 mWindowingMode = WINDOWING_MODE_UNDEFINED; 603 mActivityType = ACTIVITY_TYPE_UNDEFINED; 604 mTaskId = INVALID_TASK_ID; 605 mIsTaskOverlay = false; 606 mIsLockTask = false; 607 mAsync = false; 608 mBroadcastOptions = null; 609 610 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { 611 @Override 612 public boolean handleOption(String opt, ShellCommand cmd) { 613 if (opt.equals("-D")) { 614 mStartFlags |= ActivityManager.START_FLAG_DEBUG; 615 } else if (opt.equals("--suspend")) { 616 mStartFlags |= ActivityManager.START_FLAG_DEBUG_SUSPEND; 617 } else if (opt.equals("-N")) { 618 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING; 619 } else if (opt.equals("-W")) { 620 mWaitOption = true; 621 } else if (opt.equals("-P")) { 622 mProfileFile = getNextArgRequired(); 623 mAutoStop = true; 624 } else if (opt.equals("--start-profiler")) { 625 mProfileFile = getNextArgRequired(); 626 mAutoStop = false; 627 } else if (opt.equals("--sampling")) { 628 mSamplingInterval = Integer.parseInt(getNextArgRequired()); 629 } else if (opt.equals("--clock-type")) { 630 String clock_type = getNextArgRequired(); 631 mClockType = ProfilerInfo.getClockTypeFromString(clock_type); 632 } else if (opt.equals(PROFILER_OUTPUT_VERSION_FLAG)) { 633 mProfilerOutputVersion = Integer.parseInt(getNextArgRequired()); 634 } else if (opt.equals("--streaming")) { 635 mStreaming = true; 636 } else if (opt.equals("--attach-agent")) { 637 if (mAgent != null) { 638 cmd.getErrPrintWriter().println( 639 "Multiple --attach-agent(-bind) not supported"); 640 return false; 641 } 642 mAgent = getNextArgRequired(); 643 mAttachAgentDuringBind = false; 644 } else if (opt.equals("--attach-agent-bind")) { 645 if (mAgent != null) { 646 cmd.getErrPrintWriter().println( 647 "Multiple --attach-agent(-bind) not supported"); 648 return false; 649 } 650 mAgent = getNextArgRequired(); 651 mAttachAgentDuringBind = true; 652 } else if (opt.equals("-R")) { 653 mRepeat = Integer.parseInt(getNextArgRequired()); 654 } else if (opt.equals("-S")) { 655 mStopOption = true; 656 } else if (opt.equals("--track-allocation")) { 657 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION; 658 } else if (opt.equals("--user")) { 659 mUserId = UserHandle.parseUserArg(getNextArgRequired()); 660 } else if (opt.equals("--receiver-permission")) { 661 mReceiverPermission = getNextArgRequired(); 662 } else if (opt.equals("--display")) { 663 mDisplayId = Integer.parseInt(getNextArgRequired()); 664 } else if (opt.equals("--task-display-area-feature-id")) { 665 mTaskDisplayAreaFeatureId = Integer.parseInt(getNextArgRequired()); 666 } else if (opt.equals("--windowingMode")) { 667 mWindowingMode = Integer.parseInt(getNextArgRequired()); 668 } else if (opt.equals("--activityType")) { 669 mActivityType = Integer.parseInt(getNextArgRequired()); 670 } else if (opt.equals("--task")) { 671 mTaskId = Integer.parseInt(getNextArgRequired()); 672 } else if (opt.equals("--task-overlay")) { 673 mIsTaskOverlay = true; 674 } else if (opt.equals("--lock-task")) { 675 mIsLockTask = true; 676 } else if (opt.equals("--allow-background-activity-starts")) { 677 if (mBroadcastOptions == null) { 678 mBroadcastOptions = BroadcastOptions.makeBasic(); 679 } 680 mBroadcastOptions.setBackgroundActivityStartsAllowed(true); 681 } else if (opt.equals("--async")) { 682 mAsync = true; 683 } else if (opt.equals("--splashscreen-show-icon")) { 684 mShowSplashScreen = true; 685 } else if (opt.equals("--dismiss-keyguard-if-insecure") 686 || opt.equals("--dismiss-keyguard")) { 687 mDismissKeyguardIfInsecure = true; 688 } else if (opt.equals("--allow-fgs-start-reason")) { 689 final int reasonCode = Integer.parseInt(getNextArgRequired()); 690 mBroadcastOptions = BroadcastOptions.makeBasic(); 691 mBroadcastOptions.setTemporaryAppAllowlist(10_000, 692 TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 693 reasonCode, 694 ""); 695 } else { 696 return false; 697 } 698 return true; 699 } 700 }); 701 } 702 703 private class ProgressWaiter extends IProgressListener.Stub { 704 private final CountDownLatch mFinishedLatch = new CountDownLatch(1); 705 private final @UserIdInt int mUserId; 706 707 private ProgressWaiter(@UserIdInt int userId) { 708 mUserId = userId; 709 } 710 711 @Override 712 public void onStarted(int id, Bundle extras) {} 713 714 @Override 715 public void onProgress(int id, int progress, Bundle extras) { 716 Slogf.d(TAG, "ProgressWaiter[user=%d]: onProgress(%d, %d)", mUserId, id, progress); 717 } 718 719 @Override 720 public void onFinished(int id, Bundle extras) { 721 Slogf.d(TAG, "ProgressWaiter[user=%d]: onFinished(%d)", mUserId, id); 722 mFinishedLatch.countDown(); 723 } 724 725 @Override 726 public String toString() { 727 return "ProgressWaiter[userId=" + mUserId + ", finished=" 728 + (mFinishedLatch.getCount() == 0) + "]"; 729 } 730 731 public boolean waitForFinish(long timeoutMillis) { 732 try { 733 return mFinishedLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); 734 } catch (InterruptedException e) { 735 System.err.println("Thread interrupted unexpectedly."); 736 return false; 737 } 738 } 739 } 740 741 int runStartActivity(PrintWriter pw) throws RemoteException { 742 Intent intent; 743 try { 744 intent = makeIntent(UserHandle.USER_CURRENT); 745 } catch (URISyntaxException e) { 746 throw new RuntimeException(e.getMessage(), e); 747 } 748 749 if (mUserId == UserHandle.USER_ALL) { 750 getErrPrintWriter().println("Error: Can't start service with user 'all'"); 751 return 1; 752 } 753 754 final String mimeType = intent.resolveType(mInternal.mContext); 755 756 do { 757 if (mStopOption) { 758 String packageName; 759 if (intent.getComponent() != null) { 760 packageName = intent.getComponent().getPackageName(); 761 } else { 762 // queryIntentActivities does not convert user id, so we convert it here first 763 int userIdForQuery = mInternal.mUserController.handleIncomingUser( 764 Binder.getCallingPid(), Binder.getCallingUid(), mUserId, false, 765 ALLOW_NON_FULL, "ActivityManagerShellCommand", null); 766 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 767 0, userIdForQuery).getList(); 768 if (activities == null || activities.size() <= 0) { 769 getErrPrintWriter().println("Error: Intent does not match any activities: " 770 + intent); 771 return 1; 772 } else if (activities.size() > 1) { 773 getErrPrintWriter().println( 774 "Error: Intent matches multiple activities; can't stop: " 775 + intent); 776 return 1; 777 } 778 packageName = activities.get(0).activityInfo.packageName; 779 } 780 pw.println("Stopping: " + packageName); 781 pw.flush(); 782 mInterface.forceStopPackage(packageName, mUserId); 783 try { 784 Thread.sleep(250); 785 } catch (InterruptedException e) { 786 } 787 } 788 789 ProfilerInfo profilerInfo = null; 790 791 if (mProfileFile != null || mAgent != null) { 792 ParcelFileDescriptor fd = null; 793 if (mProfileFile != null) { 794 fd = openFileForSystem(mProfileFile, "w"); 795 if (fd == null) { 796 return 1; 797 } 798 } 799 profilerInfo = 800 new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, mStreaming, 801 mAgent, mAttachAgentDuringBind, mClockType, mProfilerOutputVersion); 802 } 803 804 pw.println("Starting: " + intent); 805 pw.flush(); 806 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 807 808 WaitResult result = null; 809 int res; 810 final long startTime = SystemClock.uptimeMillis(); 811 ActivityOptions options = null; 812 if (mDisplayId != INVALID_DISPLAY) { 813 options = ActivityOptions.makeBasic(); 814 options.setLaunchDisplayId(mDisplayId); 815 } 816 if (mTaskDisplayAreaFeatureId != FEATURE_UNDEFINED) { 817 if (options == null) { 818 options = ActivityOptions.makeBasic(); 819 } 820 options.setLaunchTaskDisplayAreaFeatureId(mTaskDisplayAreaFeatureId); 821 } 822 if (mWindowingMode != WINDOWING_MODE_UNDEFINED) { 823 if (options == null) { 824 options = ActivityOptions.makeBasic(); 825 } 826 options.setLaunchWindowingMode(mWindowingMode); 827 } 828 if (mActivityType != ACTIVITY_TYPE_UNDEFINED) { 829 if (options == null) { 830 options = ActivityOptions.makeBasic(); 831 } 832 options.setLaunchActivityType(mActivityType); 833 } 834 if (mTaskId != INVALID_TASK_ID) { 835 if (options == null) { 836 options = ActivityOptions.makeBasic(); 837 } 838 options.setLaunchTaskId(mTaskId); 839 840 if (mIsTaskOverlay) { 841 options.setTaskOverlay(true, true /* canResume */); 842 } 843 } 844 if (mIsLockTask) { 845 if (options == null) { 846 options = ActivityOptions.makeBasic(); 847 } 848 options.setLockTaskEnabled(true); 849 } 850 if (mShowSplashScreen) { 851 if (options == null) { 852 options = ActivityOptions.makeBasic(); 853 } 854 options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON); 855 } 856 if (mDismissKeyguardIfInsecure) { 857 if (options == null) { 858 options = ActivityOptions.makeBasic(); 859 } 860 options.setDismissKeyguardIfInsecure(); 861 } 862 intent.collectExtraIntentKeys(); 863 if (mWaitOption) { 864 result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent, 865 mimeType, null, null, 0, mStartFlags, profilerInfo, 866 options != null ? options.toBundle() : null, mUserId); 867 res = result.result; 868 } else { 869 res = mInternal.startActivityAsUserWithFeature(null, SHELL_PACKAGE_NAME, null, 870 intent, mimeType, null, null, 0, mStartFlags, profilerInfo, 871 options != null ? options.toBundle() : null, mUserId); 872 } 873 final long endTime = SystemClock.uptimeMillis(); 874 PrintWriter out = mWaitOption ? pw : getErrPrintWriter(); 875 boolean launched = false; 876 switch (res) { 877 case ActivityManager.START_SUCCESS: 878 launched = true; 879 break; 880 case ActivityManager.START_SWITCHES_CANCELED: 881 launched = true; 882 out.println( 883 "Warning: Activity not started because the " 884 + " current activity is being kept for the user."); 885 break; 886 case ActivityManager.START_DELIVERED_TO_TOP: 887 launched = true; 888 out.println( 889 "Warning: Activity not started, intent has " 890 + "been delivered to currently running " 891 + "top-most instance."); 892 break; 893 case ActivityManager.START_RETURN_INTENT_TO_CALLER: 894 launched = true; 895 out.println( 896 "Warning: Activity not started because intent " 897 + "should be handled by the caller"); 898 break; 899 case ActivityManager.START_TASK_TO_FRONT: 900 launched = true; 901 out.println( 902 "Warning: Activity not started, its current " 903 + "task has been brought to the front"); 904 break; 905 case ActivityManager.START_INTENT_NOT_RESOLVED: 906 out.println( 907 "Error: Activity not started, unable to " 908 + "resolve " + intent.toString()); 909 return 1; 910 case ActivityManager.START_CLASS_NOT_FOUND: 911 out.println(NO_CLASS_ERROR_CODE); 912 out.println("Error: Activity class " + 913 intent.getComponent().toShortString() 914 + " does not exist."); 915 return 1; 916 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: 917 out.println( 918 "Error: Activity not started, you requested to " 919 + "both forward and receive its result"); 920 return 1; 921 case ActivityManager.START_PERMISSION_DENIED: 922 out.println( 923 "Error: Activity not started, you do not " 924 + "have permission to access it."); 925 return 1; 926 case ActivityManager.START_NOT_VOICE_COMPATIBLE: 927 out.println( 928 "Error: Activity not started, voice control not allowed for: " 929 + intent); 930 return 1; 931 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY: 932 out.println( 933 "Error: Not allowed to start background user activity" 934 + " that shouldn't be displayed for all users."); 935 return 1; 936 default: 937 out.println( 938 "Error: Activity not started, unknown error code " + res); 939 return 1; 940 } 941 out.flush(); 942 if (mWaitOption && launched) { 943 if (result == null) { 944 result = new WaitResult(); 945 result.who = intent.getComponent(); 946 } 947 pw.println("Status: " + (result.timeout ? "timeout" : "ok")); 948 pw.println("LaunchState: " + launchStateToString(result.launchState)); 949 if (result.who != null) { 950 pw.println("Activity: " + result.who.flattenToShortString()); 951 } 952 if (result.totalTime >= 0) { 953 pw.println("TotalTime: " + result.totalTime); 954 } 955 pw.println("WaitTime: " + (endTime-startTime)); 956 pw.println("Complete"); 957 pw.flush(); 958 } 959 mRepeat--; 960 if (mRepeat > 0) { 961 mTaskInterface.unhandledBack(); 962 } 963 } while (mRepeat > 0); 964 return 0; 965 } 966 967 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException { 968 final PrintWriter err = getErrPrintWriter(); 969 Intent intent; 970 try { 971 intent = makeIntent(UserHandle.USER_CURRENT); 972 } catch (URISyntaxException e) { 973 throw new RuntimeException(e.getMessage(), e); 974 } 975 if (mUserId == UserHandle.USER_ALL) { 976 err.println("Error: Can't start activity with user 'all'"); 977 return -1; 978 } 979 pw.println("Starting service: " + intent); 980 pw.flush(); 981 intent.collectExtraIntentKeys(); 982 ComponentName cn = mInterface.startService(null, intent, intent.getType(), 983 asForeground, SHELL_PACKAGE_NAME, null, mUserId); 984 if (cn == null) { 985 err.println("Error: Not found; no service started."); 986 return -1; 987 } else if (cn.getPackageName().equals("!")) { 988 err.println("Error: Requires permission " + cn.getClassName()); 989 return -1; 990 } else if (cn.getPackageName().equals("!!")) { 991 err.println("Error: " + cn.getClassName()); 992 return -1; 993 } else if (cn.getPackageName().equals("?")) { 994 err.println("Error: " + cn.getClassName()); 995 return -1; 996 } 997 return 0; 998 } 999 1000 int runStopService(PrintWriter pw) throws RemoteException { 1001 final PrintWriter err = getErrPrintWriter(); 1002 Intent intent; 1003 try { 1004 intent = makeIntent(UserHandle.USER_CURRENT); 1005 } catch (URISyntaxException e) { 1006 throw new RuntimeException(e.getMessage(), e); 1007 } 1008 if (mUserId == UserHandle.USER_ALL) { 1009 err.println("Error: Can't stop activity with user 'all'"); 1010 return -1; 1011 } 1012 pw.println("Stopping service: " + intent); 1013 pw.flush(); 1014 intent.collectExtraIntentKeys(); 1015 int result = mInterface.stopService(null, intent, intent.getType(), mUserId); 1016 if (result == 0) { 1017 err.println("Service not stopped: was not running."); 1018 return -1; 1019 } else if (result == 1) { 1020 err.println("Service stopped"); 1021 return -1; 1022 } else if (result == -1) { 1023 err.println("Error stopping service"); 1024 return -1; 1025 } 1026 return 0; 1027 } 1028 1029 final static class IntentReceiver extends IIntentReceiver.Stub { 1030 private final PrintWriter mPw; 1031 private boolean mFinished = false; 1032 1033 IntentReceiver(PrintWriter pw) { 1034 mPw = pw; 1035 } 1036 1037 @Override 1038 public void performReceive(Intent intent, int resultCode, String data, Bundle extras, 1039 boolean ordered, boolean sticky, int sendingUser) { 1040 String line = "Broadcast completed: result=" + resultCode; 1041 if (data != null) line = line + ", data=\"" + data + "\""; 1042 if (extras != null) line = line + ", extras: " + extras; 1043 mPw.println(line); 1044 mPw.flush(); 1045 synchronized (this) { 1046 mFinished = true; 1047 notifyAll(); 1048 } 1049 } 1050 1051 public synchronized void waitForFinish() { 1052 try { 1053 while (!mFinished) wait(); 1054 } catch (InterruptedException e) { 1055 throw new IllegalStateException(e); 1056 } 1057 } 1058 } 1059 1060 int runSendBroadcast(PrintWriter pw) throws RemoteException { 1061 pw = new PrintWriter(new TeeWriter(LOG_WRITER_INFO, pw)); 1062 Intent intent; 1063 try { 1064 intent = makeIntent(UserHandle.USER_CURRENT); 1065 } catch (URISyntaxException e) { 1066 throw new RuntimeException(e.getMessage(), e); 1067 } 1068 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL); 1069 IntentReceiver receiver = new IntentReceiver(pw); 1070 String[] requiredPermissions = mReceiverPermission == null ? null 1071 : new String[] {mReceiverPermission}; 1072 pw.println("Broadcasting: " + intent); 1073 pw.flush(); 1074 Bundle bundle = mBroadcastOptions == null ? null : mBroadcastOptions.toBundle(); 1075 final int result = mInterface.broadcastIntentWithFeature(null, null, intent, null, 1076 receiver, 0, null, null, requiredPermissions, null, null, 1077 android.app.AppOpsManager.OP_NONE, bundle, true, false, mUserId); 1078 Slogf.i(TAG, "Enqueued broadcast %s: " + result, intent); 1079 if (result == ActivityManager.BROADCAST_SUCCESS && !mAsync) { 1080 receiver.waitForFinish(); 1081 } 1082 return 0; 1083 } 1084 1085 int runTraceIpc(PrintWriter pw) throws RemoteException { 1086 String op = getNextArgRequired(); 1087 if (op.equals("start")) { 1088 return runTraceIpcStart(pw); 1089 } else if (op.equals("stop")) { 1090 return runTraceIpcStop(pw); 1091 } else { 1092 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'"); 1093 return -1; 1094 } 1095 } 1096 1097 int runTraceIpcStart(PrintWriter pw) throws RemoteException { 1098 pw.println("Starting IPC tracing."); 1099 pw.flush(); 1100 mInterface.startBinderTracking(); 1101 return 0; 1102 } 1103 1104 int runTraceIpcStop(PrintWriter pw) throws RemoteException { 1105 final PrintWriter err = getErrPrintWriter(); 1106 String opt; 1107 String filename = null; 1108 while ((opt=getNextOption()) != null) { 1109 if (opt.equals("--dump-file")) { 1110 filename = getNextArgRequired(); 1111 } else { 1112 err.println("Error: Unknown option: " + opt); 1113 return -1; 1114 } 1115 } 1116 if (filename == null) { 1117 err.println("Error: Specify filename to dump logs to."); 1118 return -1; 1119 } 1120 1121 // Writes an error message to stderr on failure 1122 ParcelFileDescriptor fd = openFileForSystem(filename, "w"); 1123 if (fd == null) { 1124 return -1; 1125 } 1126 1127 if (!mInterface.stopBinderTrackingAndDump(fd)) { 1128 err.println("STOP TRACE FAILED."); 1129 return -1; 1130 } 1131 1132 pw.println("Stopped IPC tracing. Dumping logs to: " + filename); 1133 return 0; 1134 } 1135 1136 // Update AnrTimer tracing. 1137 private int runTraceTimer(PrintWriter pw) throws RemoteException { 1138 if (!AnrTimer.traceFeatureEnabled()) return -1; 1139 1140 // Delegate all argument parsing to the AnrTimer method. 1141 try { 1142 final String result = AnrTimer.traceTimers(peekRemainingArgs()); 1143 if (result != null) { 1144 pw.println(result); 1145 } 1146 return 0; 1147 } catch (IllegalArgumentException e) { 1148 getErrPrintWriter().println("Error: bad trace-timer command: " + e); 1149 return -1; 1150 } 1151 } 1152 1153 // NOTE: current profiles can only be started on default display (even on automotive builds with 1154 // passenger displays), so there's no need to pass a display-id 1155 private int runProfile(PrintWriter pw) throws RemoteException { 1156 final PrintWriter err = getErrPrintWriter(); 1157 String profileFile = null; 1158 boolean start = false; 1159 int userId = UserHandle.USER_CURRENT; 1160 int profileType = ProfilerInfo.PROFILE_TYPE_REGULAR; 1161 mSamplingInterval = 0; 1162 mStreaming = false; 1163 mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT; 1164 mProfilerOutputVersion = ProfilerInfo.OUTPUT_VERSION_DEFAULT; 1165 1166 String process = null; 1167 1168 String cmd = getNextArgRequired(); 1169 1170 if ("start".equals(cmd)) { 1171 start = true; 1172 String opt; 1173 while ((opt=getNextOption()) != null) { 1174 if (opt.equals("--user")) { 1175 userId = UserHandle.parseUserArg(getNextArgRequired()); 1176 } else if (opt.equals("--clock-type")) { 1177 String clock_type = getNextArgRequired(); 1178 mClockType = ProfilerInfo.getClockTypeFromString(clock_type); 1179 } else if (opt.equals(PROFILER_OUTPUT_VERSION_FLAG)) { 1180 mProfilerOutputVersion = Integer.parseInt(getNextArgRequired()); 1181 } else if (opt.equals("--streaming")) { 1182 mStreaming = true; 1183 } else if (opt.equals("--sampling")) { 1184 mSamplingInterval = Integer.parseInt(getNextArgRequired()); 1185 } else { 1186 err.println("Error: Unknown option: " + opt); 1187 return -1; 1188 } 1189 } 1190 process = getNextArgRequired(); 1191 } else if ("stop".equals(cmd)) { 1192 String opt; 1193 while ((opt=getNextOption()) != null) { 1194 if (opt.equals("--user")) { 1195 userId = UserHandle.parseUserArg(getNextArgRequired()); 1196 } else { 1197 err.println("Error: Unknown option: " + opt); 1198 return -1; 1199 } 1200 } 1201 process = getNextArgRequired(); 1202 } else if ("lowoverhead".equals(cmd)) { 1203 // This is an experimental low overhead profiling. 1204 profileType = ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD; 1205 cmd = getNextArgRequired(); 1206 if ("start".equals(cmd)) { 1207 start = true; 1208 } else if ("stop".equals(cmd)) { 1209 start = false; 1210 } else { 1211 throw new IllegalArgumentException("Profile command not valid"); 1212 } 1213 process = getNextArgRequired(); 1214 } else { 1215 // Compatibility with old syntax: process is specified first. 1216 process = cmd; 1217 cmd = getNextArgRequired(); 1218 if ("start".equals(cmd)) { 1219 start = true; 1220 } else if (!"stop".equals(cmd)) { 1221 throw new IllegalArgumentException("Profile command " + process + " not valid"); 1222 } 1223 } 1224 1225 if (userId == UserHandle.USER_ALL) { 1226 err.println("Error: Can't profile with user 'all'"); 1227 return -1; 1228 } 1229 1230 ParcelFileDescriptor fd = null; 1231 ProfilerInfo profilerInfo = null; 1232 1233 // For regular method tracing profileFile should be provided with the start command. For 1234 // low overhead method tracing the profileFile is optional and provided with the stop 1235 // command. 1236 if ((start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR) 1237 || (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD 1238 && !start && getRemainingArgsCount() > 0)) { 1239 profileFile = getNextArgRequired(); 1240 fd = openFileForSystem(profileFile, "w"); 1241 if (fd == null) { 1242 return -1; 1243 } 1244 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming, 1245 null, false, mClockType, mProfilerOutputVersion); 1246 } 1247 1248 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) { 1249 err.println("PROFILE FAILED on process " + process); 1250 return -1; 1251 } 1252 return 0; 1253 } 1254 1255 @NeverCompile 1256 int runCompact(PrintWriter pw) throws RemoteException { 1257 ProcessRecord app; 1258 String op = getNextArgRequired(); 1259 boolean isFullCompact = op.equals("full"); 1260 boolean isSomeCompact = op.equals("some"); 1261 if (isFullCompact || isSomeCompact) { 1262 app = getProcessFromShell(); 1263 if (app == null) { 1264 getErrPrintWriter().println("Error: could not find process"); 1265 return -1; 1266 } 1267 pw.println("Process record found pid: " + app.mPid); 1268 if (isFullCompact) { 1269 pw.println("Executing full compaction for " + app.mPid); 1270 synchronized (mInternal.mProcLock) { 1271 mInternal.mOomAdjuster.mCachedAppOptimizer.compactApp(app, 1272 CachedAppOptimizer.CompactProfile.FULL, 1273 CachedAppOptimizer.CompactSource.SHELL, true); 1274 } 1275 pw.println("Finished full compaction for " + app.mPid); 1276 } else if (isSomeCompact) { 1277 pw.println("Executing some compaction for " + app.mPid); 1278 synchronized (mInternal.mProcLock) { 1279 mInternal.mOomAdjuster.mCachedAppOptimizer.compactApp(app, 1280 CachedAppOptimizer.CompactProfile.SOME, 1281 CachedAppOptimizer.CompactSource.SHELL, true); 1282 } 1283 pw.println("Finished some compaction for " + app.mPid); 1284 } 1285 } else if (op.equals("system")) { 1286 pw.println("Executing system compaction"); 1287 synchronized (mInternal.mProcLock) { 1288 mInternal.mOomAdjuster.mCachedAppOptimizer.compactAllSystem(); 1289 } 1290 pw.println("Finished system compaction"); 1291 } else if (op.equals("native")) { 1292 op = getNextArgRequired(); 1293 isFullCompact = op.equals("full"); 1294 isSomeCompact = op.equals("some"); 1295 int pid; 1296 String pidStr = getNextArgRequired(); 1297 try { 1298 pid = Integer.parseInt(pidStr); 1299 } catch (Exception e) { 1300 getErrPrintWriter().println("Error: failed to parse '" + pidStr + "' as a PID"); 1301 return -1; 1302 } 1303 if (isFullCompact) { 1304 mInternal.mOomAdjuster.mCachedAppOptimizer.compactNative( 1305 CachedAppOptimizer.CompactProfile.FULL, pid); 1306 } else if (isSomeCompact) { 1307 mInternal.mOomAdjuster.mCachedAppOptimizer.compactNative( 1308 CachedAppOptimizer.CompactProfile.SOME, pid); 1309 } else { 1310 getErrPrintWriter().println("Error: unknown compaction type '" + op + "'"); 1311 return -1; 1312 } 1313 } else { 1314 getErrPrintWriter().println("Error: unknown compact command '" + op + "'"); 1315 return -1; 1316 } 1317 1318 return 0; 1319 } 1320 1321 @NeverCompile 1322 int runFreeze(PrintWriter pw, boolean freeze) throws RemoteException { 1323 String freezerOpt = getNextOption(); 1324 boolean isSticky = false; 1325 1326 if (freezerOpt != null) { 1327 isSticky = freezerOpt.equals("--sticky"); 1328 } 1329 ProcessRecord proc = getProcessFromShell(); 1330 if (proc == null) { 1331 return -1; 1332 } 1333 pw.print(freeze ? "Freezing" : "Unfreezing"); 1334 pw.print(" process " + proc.processName); 1335 pw.println(" (" + proc.mPid + ") sticky=" + isSticky); 1336 synchronized (mInternal) { 1337 synchronized (mInternal.mProcLock) { 1338 proc.mOptRecord.setFreezeSticky(isSticky); 1339 if (freeze) { 1340 mInternal.mOomAdjuster.mCachedAppOptimizer.forceFreezeAppAsyncLSP(proc); 1341 } else { 1342 mInternal.mOomAdjuster.mCachedAppOptimizer.unfreezeAppLSP(proc, 0, true); 1343 } 1344 } 1345 } 1346 return 0; 1347 } 1348 1349 /** 1350 * Parses from the shell the pid or process name and provides the corresponding 1351 * {@link ProcessRecord}. 1352 * Example usage: {@code <processname>} or {@code <pid>} 1353 * @return process record of process, null if none or more than one found. 1354 * @throws RemoteException 1355 */ 1356 @NeverCompile 1357 ProcessRecord getProcessFromShell() throws RemoteException { 1358 ProcessRecord proc = null; 1359 String process = getNextArgRequired(); 1360 try { 1361 int pid = Integer.parseInt(process); 1362 synchronized (mInternal.mPidsSelfLocked) { 1363 proc = mInternal.mPidsSelfLocked.get(pid); 1364 } 1365 } catch (NumberFormatException e) { 1366 // Fallback to process name if it's not a valid pid 1367 } 1368 1369 if (proc == null) { 1370 synchronized (mInternal.mProcLock) { 1371 ArrayMap<String, SparseArray<ProcessRecord>> all = 1372 mInternal.mProcessList.getProcessNamesLOSP().getMap(); 1373 SparseArray<ProcessRecord> procs = all.get(process); 1374 if (procs == null || procs.size() == 0) { 1375 getErrPrintWriter().println("Error: could not find process"); 1376 return null; 1377 } else if (procs.size() > 1) { 1378 getErrPrintWriter().println("Error: more than one processes found"); 1379 return null; 1380 } 1381 proc = procs.valueAt(0); 1382 } 1383 } 1384 1385 return proc; 1386 } 1387 1388 int runDumpHeap(PrintWriter pw) throws RemoteException { 1389 final PrintWriter err = getErrPrintWriter(); 1390 boolean managed = true; 1391 boolean mallocInfo = false; 1392 String dumpBitmaps = null; 1393 int userId = UserHandle.USER_CURRENT; 1394 boolean runGc = false; 1395 1396 String opt; 1397 while ((opt=getNextOption()) != null) { 1398 if (opt.equals("--user")) { 1399 userId = UserHandle.parseUserArg(getNextArgRequired()); 1400 if (userId == UserHandle.USER_ALL) { 1401 err.println("Error: Can't dump heap with user 'all'"); 1402 return -1; 1403 } 1404 } else if (opt.equals("-n")) { 1405 managed = false; 1406 } else if (opt.equals("-g")) { 1407 runGc = true; 1408 } else if (opt.equals("-m")) { 1409 managed = false; 1410 mallocInfo = true; 1411 } else if (opt.equals("-b")) { 1412 dumpBitmaps = getNextArg(); 1413 if (dumpBitmaps == null) { 1414 dumpBitmaps = "png"; // default to PNG in dumping bitmaps 1415 } 1416 } else { 1417 err.println("Error: Unknown option: " + opt); 1418 return -1; 1419 } 1420 } 1421 String process = getNextArgRequired(); 1422 String heapFile = getNextArg(); 1423 if (heapFile == null) { 1424 LocalDateTime localDateTime = LocalDateTime.now(Clock.systemDefaultZone()); 1425 String logNameTimeString = LOG_NAME_TIME_FORMATTER.format(localDateTime); 1426 heapFile = "/data/local/tmp/heapdump-" + logNameTimeString + ".prof"; 1427 } 1428 1429 String argAfterHeapFile = getNextArg(); 1430 if (argAfterHeapFile != null) { 1431 err.println("Error: Arguments cannot be placed after the heap file"); 1432 return -1; 1433 } 1434 1435 // Writes an error message to stderr on failure 1436 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w"); 1437 if (fd == null) { 1438 return -1; 1439 } 1440 1441 pw.println("File: " + heapFile); 1442 pw.flush(); 1443 1444 final CountDownLatch latch = new CountDownLatch(1); 1445 1446 final RemoteCallback finishCallback = new RemoteCallback(new OnResultListener() { 1447 @Override 1448 public void onResult(Bundle result) { 1449 latch.countDown(); 1450 } 1451 }, null); 1452 1453 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, dumpBitmaps, 1454 heapFile, fd, finishCallback)) { 1455 err.println("HEAP DUMP FAILED on process " + process); 1456 return -1; 1457 } 1458 pw.println("Waiting for dump to finish..."); 1459 pw.flush(); 1460 try { 1461 latch.await(); 1462 } catch (InterruptedException e) { 1463 err.println("Caught InterruptedException"); 1464 } 1465 1466 return 0; 1467 } 1468 1469 int runSetDebugApp(PrintWriter pw) throws RemoteException { 1470 boolean wait = false; 1471 boolean persistent = false; 1472 1473 String opt; 1474 while ((opt=getNextOption()) != null) { 1475 if (opt.equals("-w")) { 1476 wait = true; 1477 } else if (opt.equals("--persistent")) { 1478 persistent = true; 1479 } else { 1480 getErrPrintWriter().println("Error: Unknown option: " + opt); 1481 return -1; 1482 } 1483 } 1484 1485 String pkg = getNextArgRequired(); 1486 mInterface.setDebugApp(pkg, wait, persistent); 1487 return 0; 1488 } 1489 1490 int runSetAgentApp(PrintWriter pw) throws RemoteException { 1491 String pkg = getNextArgRequired(); 1492 String agent = getNextArg(); 1493 mInterface.setAgentApp(pkg, agent); 1494 return 0; 1495 } 1496 1497 int runClearDebugApp(PrintWriter pw) throws RemoteException { 1498 mInterface.setDebugApp(null, false, true); 1499 return 0; 1500 } 1501 1502 int runSetWatchHeap(PrintWriter pw) throws RemoteException { 1503 String proc = getNextArgRequired(); 1504 String limit = getNextArgRequired(); 1505 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null); 1506 return 0; 1507 } 1508 1509 int runClearWatchHeap(PrintWriter pw) throws RemoteException { 1510 String proc = getNextArgRequired(); 1511 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null); 1512 return 0; 1513 } 1514 1515 int runClearStartInfo(PrintWriter pw) throws RemoteException { 1516 mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 1517 "runClearStartInfo()"); 1518 String opt; 1519 int userId = UserHandle.USER_CURRENT; 1520 while ((opt = getNextOption()) != null) { 1521 if (opt.equals("--user")) { 1522 userId = UserHandle.parseUserArg(getNextArgRequired()); 1523 } else { 1524 getErrPrintWriter().println("Error: Unknown option: " + opt); 1525 return -1; 1526 } 1527 } 1528 if (userId == UserHandle.USER_CURRENT) { 1529 UserInfo user = mInterface.getCurrentUser(); 1530 if (user == null) { 1531 return -1; 1532 } 1533 userId = user.id; 1534 } 1535 mInternal.mProcessList.getAppStartInfoTracker() 1536 .clearHistoryProcessStartInfo(getNextArg(), userId); 1537 return 0; 1538 } 1539 1540 int runStartInfoDetailedMonitoring(PrintWriter pw) throws RemoteException { 1541 String opt; 1542 int userId = UserHandle.USER_CURRENT; 1543 while ((opt = getNextOption()) != null) { 1544 if (opt.equals("--user")) { 1545 userId = UserHandle.parseUserArg(getNextArgRequired()); 1546 } else { 1547 getErrPrintWriter().println("Error: Unknown option: " + opt); 1548 return -1; 1549 } 1550 } 1551 if (userId == UserHandle.USER_CURRENT) { 1552 UserInfo user = mInterface.getCurrentUser(); 1553 if (user == null) { 1554 return -1; 1555 } 1556 userId = user.id; 1557 } 1558 mInternal.mProcessList.getAppStartInfoTracker() 1559 .configureDetailedMonitoring(pw, getNextArg(), userId); 1560 return 0; 1561 } 1562 1563 int runClearExitInfo(PrintWriter pw) throws RemoteException { 1564 mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 1565 "runClearExitInfo()"); 1566 String opt; 1567 int userId = UserHandle.USER_CURRENT; 1568 while ((opt = getNextOption()) != null) { 1569 if (opt.equals("--user")) { 1570 userId = UserHandle.parseUserArg(getNextArgRequired()); 1571 } else { 1572 getErrPrintWriter().println("Error: Unknown option: " + opt); 1573 return -1; 1574 } 1575 } 1576 if (userId == UserHandle.USER_CURRENT) { 1577 UserInfo user = mInterface.getCurrentUser(); 1578 if (user == null) { 1579 return -1; 1580 } 1581 userId = user.id; 1582 } 1583 mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(getNextArg(), 1584 userId); 1585 return 0; 1586 } 1587 1588 int runBugReport(PrintWriter pw) throws RemoteException { 1589 String opt; 1590 boolean fullBugreport = true; 1591 while ((opt=getNextOption()) != null) { 1592 if (opt.equals("--progress")) { 1593 fullBugreport = false; 1594 mInterface.requestInteractiveBugReport(); 1595 } else if (opt.equals("--telephony")) { 1596 fullBugreport = false; 1597 // no title and description specified 1598 mInterface.requestTelephonyBugReport("" /* no title */, "" /* no descriptions */); 1599 } else { 1600 getErrPrintWriter().println("Error: Unknown option: " + opt); 1601 return -1; 1602 } 1603 } 1604 if (fullBugreport) { 1605 mInterface.requestFullBugReport(); 1606 } 1607 pw.println("Your lovely bug report is being created; please be patient."); 1608 return 0; 1609 } 1610 1611 int runForceStop(PrintWriter pw) throws RemoteException { 1612 int userId = UserHandle.USER_ALL; 1613 1614 String opt; 1615 while ((opt = getNextOption()) != null) { 1616 if (opt.equals("--user")) { 1617 userId = UserHandle.parseUserArg(getNextArgRequired()); 1618 } else { 1619 getErrPrintWriter().println("Error: Unknown option: " + opt); 1620 return -1; 1621 } 1622 } 1623 mInterface.forceStopPackage(getNextArgRequired(), userId); 1624 return 0; 1625 } 1626 1627 int runStopApp(PrintWriter pw) throws RemoteException { 1628 int userId = UserHandle.USER_SYSTEM; 1629 1630 String opt; 1631 while ((opt = getNextOption()) != null) { 1632 if (opt.equals("--user")) { 1633 userId = UserHandle.parseUserArg(getNextArgRequired()); 1634 } else { 1635 getErrPrintWriter().println("Error: Unknown option: " + opt); 1636 return -1; 1637 } 1638 } 1639 mInterface.stopAppForUser(getNextArgRequired(), userId); 1640 return 0; 1641 } 1642 1643 int runClearRecentApps(PrintWriter pw) throws RemoteException { 1644 mTaskInterface.removeAllVisibleRecentTasks(); 1645 return 0; 1646 } 1647 1648 int runFgsNotificationRateLimit(PrintWriter pw) throws RemoteException { 1649 final String toggleValue = getNextArgRequired(); 1650 final boolean enable; 1651 switch (toggleValue) { 1652 case "enable": 1653 enable = true; 1654 break; 1655 case "disable": 1656 enable = false; 1657 break; 1658 default: 1659 throw new IllegalArgumentException( 1660 "Argument must be either 'enable' or 'disable'"); 1661 } 1662 mInterface.enableFgsNotificationRateLimit(enable); 1663 return 0; 1664 } 1665 1666 int runCrash(PrintWriter pw) throws RemoteException { 1667 int userId = UserHandle.USER_ALL; 1668 1669 String opt; 1670 while ((opt=getNextOption()) != null) { 1671 if (opt.equals("--user")) { 1672 userId = UserHandle.parseUserArg(getNextArgRequired()); 1673 } else { 1674 getErrPrintWriter().println("Error: Unknown option: " + opt); 1675 return -1; 1676 } 1677 } 1678 1679 int pid = -1; 1680 String packageName = null; 1681 final String arg = getNextArgRequired(); 1682 // The argument is either a pid or a package name 1683 try { 1684 pid = Integer.parseInt(arg); 1685 } catch (NumberFormatException e) { 1686 packageName = arg; 1687 } 1688 1689 int[] userIds = (userId == UserHandle.USER_ALL) ? mInternal.mUserController.getUserIds() 1690 : new int[]{userId}; 1691 for (int id : userIds) { 1692 if (mInternal.mUserController.hasUserRestriction( 1693 UserManager.DISALLOW_DEBUGGING_FEATURES, id)) { 1694 getOutPrintWriter().println( 1695 "Shell does not have permission to crash packages for user " + id); 1696 continue; 1697 } 1698 mInterface.crashApplicationWithType(-1, pid, packageName, id, "shell-induced crash", 1699 false, CrashedByAdbException.TYPE_ID); 1700 } 1701 return 0; 1702 } 1703 1704 int runKill(PrintWriter pw) throws RemoteException { 1705 int userId = UserHandle.USER_ALL; 1706 1707 String opt; 1708 while ((opt=getNextOption()) != null) { 1709 if (opt.equals("--user")) { 1710 userId = UserHandle.parseUserArg(getNextArgRequired()); 1711 } else { 1712 getErrPrintWriter().println("Error: Unknown option: " + opt); 1713 return -1; 1714 } 1715 } 1716 mInterface.killBackgroundProcesses(getNextArgRequired(), userId); 1717 return 0; 1718 } 1719 1720 int runKillAll(PrintWriter pw) throws RemoteException { 1721 mInterface.killAllBackgroundProcesses(); 1722 return 0; 1723 } 1724 1725 int runMakeIdle(PrintWriter pw) throws RemoteException { 1726 int userId = UserHandle.USER_ALL; 1727 1728 String opt; 1729 while ((opt = getNextOption()) != null) { 1730 if (opt.equals("--user")) { 1731 userId = UserHandle.parseUserArg(getNextArgRequired()); 1732 } else { 1733 getErrPrintWriter().println("Error: Unknown option: " + opt); 1734 return -1; 1735 } 1736 } 1737 mInterface.makePackageIdle(getNextArgRequired(), userId); 1738 return 0; 1739 } 1740 1741 int runSetDeterministicUidIdle(PrintWriter pw) throws RemoteException { 1742 int userId = UserHandle.USER_ALL; 1743 1744 String opt; 1745 while ((opt = getNextOption()) != null) { 1746 if (opt.equals("--user")) { 1747 userId = UserHandle.parseUserArg(getNextArgRequired()); 1748 } else { 1749 getErrPrintWriter().println("Error: Unknown option: " + opt); 1750 return -1; 1751 } 1752 } 1753 boolean deterministic = Boolean.parseBoolean(getNextArgRequired()); 1754 mInterface.setDeterministicUidIdle(deterministic); 1755 return 0; 1756 } 1757 1758 static final class MyActivityController extends IActivityController.Stub { 1759 final IActivityManager mInterface; 1760 final PrintWriter mPw; 1761 final InputStream mInput; 1762 final String mGdbPort; 1763 final boolean mMonkey; 1764 final boolean mSimpleMode; 1765 final String mTarget; 1766 final boolean mAlwaysContinue; 1767 final boolean mAlwaysKill; 1768 1769 static final int STATE_NORMAL = 0; 1770 static final int STATE_CRASHED = 1; 1771 static final int STATE_EARLY_ANR = 2; 1772 static final int STATE_ANR = 3; 1773 1774 int mState; 1775 1776 static final int RESULT_DEFAULT = 0; 1777 1778 static final int RESULT_CRASH_DIALOG = 0; 1779 static final int RESULT_CRASH_KILL = 1; 1780 1781 static final int RESULT_EARLY_ANR_CONTINUE = 0; 1782 static final int RESULT_EARLY_ANR_KILL = 1; 1783 1784 static final int RESULT_ANR_DIALOG = 0; 1785 static final int RESULT_ANR_KILL = 1; 1786 static final int RESULT_ANR_WAIT = 2; 1787 1788 int mResult; 1789 1790 Process mGdbProcess; 1791 Thread mGdbThread; 1792 boolean mGotGdbPrint; 1793 1794 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input, 1795 String gdbPort, boolean monkey, boolean simpleMode, String target, 1796 boolean alwaysContinue, boolean alwaysKill) { 1797 mInterface = iam; 1798 mPw = pw; 1799 mInput = input; 1800 mGdbPort = gdbPort; 1801 mMonkey = monkey; 1802 mSimpleMode = simpleMode; 1803 mTarget = target; 1804 mAlwaysContinue = alwaysContinue; 1805 mAlwaysKill = alwaysKill; 1806 } 1807 1808 private boolean shouldHandlePackageOrProcess(String packageOrProcess) { 1809 if (mTarget == null) { 1810 return true; // Always handle all packages / processes. 1811 } 1812 return mTarget.equals(packageOrProcess); 1813 } 1814 1815 @Override 1816 public boolean activityResuming(String pkg) { 1817 if (!shouldHandlePackageOrProcess(pkg)) { 1818 return true; 1819 } 1820 synchronized (this) { 1821 mPw.println("** Activity resuming: " + pkg); 1822 mPw.flush(); 1823 } 1824 return true; 1825 } 1826 1827 @Override 1828 public boolean activityStarting(Intent intent, String pkg) { 1829 if (!shouldHandlePackageOrProcess(pkg)) { 1830 return true; 1831 } 1832 synchronized (this) { 1833 mPw.println("** Activity starting: " + pkg); 1834 mPw.flush(); 1835 } 1836 return true; 1837 } 1838 1839 @Override 1840 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg, 1841 long timeMillis, String stackTrace) { 1842 if (!shouldHandlePackageOrProcess(processName)) { 1843 return true; // Don't kill 1844 } 1845 synchronized (this) { 1846 if (mSimpleMode) { 1847 mPw.println("** PROCESS CRASHED: " + processName); 1848 } else { 1849 mPw.println("** ERROR: PROCESS CRASHED"); 1850 mPw.println("processName: " + processName); 1851 mPw.println("processPid: " + pid); 1852 mPw.println("shortMsg: " + shortMsg); 1853 mPw.println("longMsg: " + longMsg); 1854 mPw.println("timeMillis: " + timeMillis); 1855 mPw.println("uptime: " + SystemClock.uptimeMillis()); 1856 mPw.println("stack:"); 1857 mPw.print(stackTrace); 1858 mPw.println("#"); 1859 } 1860 mPw.flush(); 1861 if (mAlwaysContinue) { 1862 return true; 1863 } 1864 if (mAlwaysKill) { 1865 return false; 1866 } 1867 int result = waitControllerLocked(pid, STATE_CRASHED); 1868 return result == RESULT_CRASH_KILL ? false : true; 1869 } 1870 } 1871 1872 @Override 1873 public int appEarlyNotResponding(String processName, int pid, String annotation) { 1874 if (!shouldHandlePackageOrProcess(processName)) { 1875 return 0; // Continue 1876 } 1877 synchronized (this) { 1878 if (mSimpleMode) { 1879 mPw.println("** EARLY PROCESS NOT RESPONDING: " + processName); 1880 } else { 1881 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING"); 1882 mPw.println("processName: " + processName); 1883 mPw.println("processPid: " + pid); 1884 mPw.println("annotation: " + annotation); 1885 mPw.println("uptime: " + SystemClock.uptimeMillis()); 1886 } 1887 mPw.flush(); 1888 if (mAlwaysContinue) { 1889 return 0; 1890 } 1891 if (mAlwaysKill) { 1892 return -1; 1893 } 1894 int result = waitControllerLocked(pid, STATE_EARLY_ANR); 1895 if (result == RESULT_EARLY_ANR_KILL) return -1; 1896 return 0; 1897 } 1898 } 1899 1900 @Override 1901 public int appNotResponding(String processName, int pid, String processStats) { 1902 if (!shouldHandlePackageOrProcess(processName)) { 1903 return 0; // Default == show dialog 1904 } 1905 synchronized (this) { 1906 if (mSimpleMode) { 1907 mPw.println("** PROCESS NOT RESPONDING: " + processName); 1908 } else { 1909 mPw.println("** ERROR: PROCESS NOT RESPONDING"); 1910 mPw.println("processName: " + processName); 1911 mPw.println("processPid: " + pid); 1912 mPw.println("uptime: " + SystemClock.uptimeMillis()); 1913 mPw.println("processStats:"); 1914 mPw.print(processStats); 1915 mPw.println("#"); 1916 } 1917 mPw.flush(); 1918 if (mAlwaysContinue) { 1919 return 0; 1920 } 1921 if (mAlwaysKill) { 1922 return -1; 1923 } 1924 int result = waitControllerLocked(pid, STATE_ANR); 1925 if (result == RESULT_ANR_KILL) return -1; 1926 if (result == RESULT_ANR_WAIT) return 1; 1927 return 0; 1928 } 1929 } 1930 1931 @Override 1932 public int systemNotResponding(String message) { 1933 if (mTarget != null) { 1934 return -1; // If any target is set, just return. 1935 } 1936 synchronized (this) { 1937 mPw.println("** ERROR: PROCESS NOT RESPONDING"); 1938 if (!mSimpleMode) { 1939 mPw.println("message: " + message); 1940 mPw.println("#"); 1941 mPw.println("Allowing system to die."); 1942 } 1943 mPw.flush(); 1944 return -1; 1945 } 1946 } 1947 1948 void killGdbLocked() { 1949 mGotGdbPrint = false; 1950 if (mGdbProcess != null) { 1951 mPw.println("Stopping gdbserver"); 1952 mPw.flush(); 1953 mGdbProcess.destroy(); 1954 mGdbProcess = null; 1955 } 1956 if (mGdbThread != null) { 1957 mGdbThread.interrupt(); 1958 mGdbThread = null; 1959 } 1960 } 1961 1962 int waitControllerLocked(int pid, int state) { 1963 if (mGdbPort != null) { 1964 killGdbLocked(); 1965 1966 try { 1967 mPw.println("Starting gdbserver on port " + mGdbPort); 1968 mPw.println("Do the following:"); 1969 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort); 1970 mPw.println(" gdbclient app_process :" + mGdbPort); 1971 mPw.flush(); 1972 1973 mGdbProcess = Runtime.getRuntime().exec(new String[] { 1974 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid) 1975 }); 1976 final InputStreamReader converter = new InputStreamReader( 1977 mGdbProcess.getInputStream()); 1978 mGdbThread = new Thread() { 1979 @Override 1980 public void run() { 1981 BufferedReader in = new BufferedReader(converter); 1982 String line; 1983 int count = 0; 1984 while (true) { 1985 synchronized (MyActivityController.this) { 1986 if (mGdbThread == null) { 1987 return; 1988 } 1989 if (count == 2) { 1990 mGotGdbPrint = true; 1991 MyActivityController.this.notifyAll(); 1992 } 1993 } 1994 try { 1995 line = in.readLine(); 1996 if (line == null) { 1997 return; 1998 } 1999 mPw.println("GDB: " + line); 2000 mPw.flush(); 2001 count++; 2002 } catch (IOException e) { 2003 return; 2004 } 2005 } 2006 } 2007 }; 2008 mGdbThread.start(); 2009 2010 // Stupid waiting for .5s. Doesn't matter if we end early. 2011 try { 2012 this.wait(500); 2013 } catch (InterruptedException e) { 2014 } 2015 2016 } catch (IOException e) { 2017 mPw.println("Failure starting gdbserver: " + e); 2018 mPw.flush(); 2019 killGdbLocked(); 2020 } 2021 } 2022 mState = state; 2023 mPw.println(""); 2024 printMessageForState(); 2025 mPw.flush(); 2026 2027 while (mState != STATE_NORMAL) { 2028 try { 2029 wait(); 2030 } catch (InterruptedException e) { 2031 } 2032 } 2033 2034 killGdbLocked(); 2035 2036 return mResult; 2037 } 2038 2039 void resumeController(int result) { 2040 synchronized (this) { 2041 mState = STATE_NORMAL; 2042 mResult = result; 2043 notifyAll(); 2044 } 2045 } 2046 2047 void printMessageForState() { 2048 if ((mAlwaysContinue || mAlwaysKill) && mSimpleMode) { 2049 return; // In the simplest mode, we don't need to show anything. 2050 } 2051 switch (mState) { 2052 case STATE_NORMAL: 2053 mPw.println("Monitoring activity manager... available commands:"); 2054 break; 2055 case STATE_CRASHED: 2056 mPw.println("Waiting after crash... available commands:"); 2057 mPw.println("(c)ontinue: show crash dialog"); 2058 mPw.println("(k)ill: immediately kill app"); 2059 break; 2060 case STATE_EARLY_ANR: 2061 mPw.println("Waiting after early ANR... available commands:"); 2062 mPw.println("(c)ontinue: standard ANR processing"); 2063 mPw.println("(k)ill: immediately kill app"); 2064 break; 2065 case STATE_ANR: 2066 mPw.println("Waiting after ANR... available commands:"); 2067 mPw.println("(c)ontinue: show ANR dialog"); 2068 mPw.println("(k)ill: immediately kill app"); 2069 mPw.println("(w)ait: wait some more"); 2070 break; 2071 } 2072 mPw.println("(q)uit: finish monitoring"); 2073 } 2074 2075 void run() throws RemoteException { 2076 try { 2077 printMessageForState(); 2078 mPw.flush(); 2079 2080 mInterface.setActivityController(this, mMonkey); 2081 mState = STATE_NORMAL; 2082 2083 InputStreamReader converter = new InputStreamReader(mInput); 2084 BufferedReader in = new BufferedReader(converter); 2085 String line; 2086 2087 while ((line = in.readLine()) != null) { 2088 boolean addNewline = true; 2089 if (line.length() <= 0) { 2090 addNewline = false; 2091 } else if ("q".equals(line) || "quit".equals(line)) { 2092 resumeController(RESULT_DEFAULT); 2093 break; 2094 } else if (mState == STATE_CRASHED) { 2095 if ("c".equals(line) || "continue".equals(line)) { 2096 resumeController(RESULT_CRASH_DIALOG); 2097 } else if ("k".equals(line) || "kill".equals(line)) { 2098 resumeController(RESULT_CRASH_KILL); 2099 } else { 2100 mPw.println("Invalid command: " + line); 2101 } 2102 } else if (mState == STATE_ANR) { 2103 if ("c".equals(line) || "continue".equals(line)) { 2104 resumeController(RESULT_ANR_DIALOG); 2105 } else if ("k".equals(line) || "kill".equals(line)) { 2106 resumeController(RESULT_ANR_KILL); 2107 } else if ("w".equals(line) || "wait".equals(line)) { 2108 resumeController(RESULT_ANR_WAIT); 2109 } else { 2110 mPw.println("Invalid command: " + line); 2111 } 2112 } else if (mState == STATE_EARLY_ANR) { 2113 if ("c".equals(line) || "continue".equals(line)) { 2114 resumeController(RESULT_EARLY_ANR_CONTINUE); 2115 } else if ("k".equals(line) || "kill".equals(line)) { 2116 resumeController(RESULT_EARLY_ANR_KILL); 2117 } else { 2118 mPw.println("Invalid command: " + line); 2119 } 2120 } else { 2121 mPw.println("Invalid command: " + line); 2122 } 2123 2124 synchronized (this) { 2125 if (addNewline) { 2126 mPw.println(""); 2127 } 2128 printMessageForState(); 2129 mPw.flush(); 2130 } 2131 } 2132 2133 } catch (IOException e) { 2134 e.printStackTrace(mPw); 2135 mPw.flush(); 2136 } finally { 2137 mInterface.setActivityController(null, mMonkey); 2138 } 2139 } 2140 } 2141 2142 int runMonitor(PrintWriter pw) throws RemoteException { 2143 String opt; 2144 String gdbPort = null; 2145 boolean monkey = false; 2146 boolean simpleMode = false; 2147 boolean alwaysContinue = false; 2148 boolean alwaysKill = false; 2149 String target = null; 2150 2151 while ((opt=getNextOption()) != null) { 2152 if (opt.equals("--gdb")) { 2153 gdbPort = getNextArgRequired(); 2154 } else if (opt.equals("-p")) { 2155 target = getNextArgRequired(); 2156 } else if (opt.equals("-m")) { 2157 monkey = true; 2158 } else if (opt.equals("-s")) { 2159 simpleMode = true; 2160 } else if (opt.equals("-c")) { 2161 alwaysContinue = true; 2162 } else if (opt.equals("-k")) { 2163 alwaysKill = true; 2164 } else { 2165 getErrPrintWriter().println("Error: Unknown option: " + opt); 2166 return -1; 2167 } 2168 } 2169 if (alwaysContinue && alwaysKill) { 2170 getErrPrintWriter().println("Error: -k and -c options can't be used together."); 2171 return -1; 2172 } 2173 2174 MyActivityController controller = new MyActivityController(mInterface, pw, 2175 getRawInputStream(), gdbPort, monkey, simpleMode, target, alwaysContinue, 2176 alwaysKill); 2177 controller.run(); 2178 return 0; 2179 } 2180 2181 static final class MyUidObserver extends UidObserver 2182 implements ActivityManagerService.OomAdjObserver { 2183 final IActivityManager mInterface; 2184 final ActivityManagerService mInternal; 2185 final PrintWriter mPw; 2186 final InputStream mInput; 2187 final int mUid; 2188 2189 final int mMask; 2190 2191 static final int STATE_NORMAL = 0; 2192 2193 int mState; 2194 2195 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid, 2196 int mask) { 2197 mInterface = service; 2198 mInternal = service; 2199 mPw = pw; 2200 mInput = input; 2201 mUid = uid; 2202 mMask = mask; 2203 } 2204 2205 @Override 2206 public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { 2207 synchronized (this) { 2208 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2209 try { 2210 mPw.print(uid); 2211 mPw.print(" procstate "); 2212 mPw.print(ProcessList.makeProcStateString(procState)); 2213 mPw.print(" seq "); 2214 mPw.print(procStateSeq); 2215 mPw.print(" capability "); 2216 mPw.println(capability & mMask); 2217 mPw.flush(); 2218 } finally { 2219 StrictMode.setThreadPolicy(oldPolicy); 2220 } 2221 } 2222 } 2223 2224 @Override 2225 public void onUidGone(int uid, boolean disabled) { 2226 synchronized (this) { 2227 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2228 try { 2229 mPw.print(uid); 2230 mPw.print(" gone"); 2231 if (disabled) { 2232 mPw.print(" disabled"); 2233 } 2234 mPw.println(); 2235 mPw.flush(); 2236 } finally { 2237 StrictMode.setThreadPolicy(oldPolicy); 2238 } 2239 } 2240 } 2241 2242 @Override 2243 public void onUidActive(int uid) { 2244 synchronized (this) { 2245 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2246 try { 2247 mPw.print(uid); 2248 mPw.println(" active"); 2249 mPw.flush(); 2250 } finally { 2251 StrictMode.setThreadPolicy(oldPolicy); 2252 } 2253 } 2254 } 2255 2256 @Override 2257 public void onUidIdle(int uid, boolean disabled) { 2258 synchronized (this) { 2259 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2260 try { 2261 mPw.print(uid); 2262 mPw.print(" idle"); 2263 if (disabled) { 2264 mPw.print(" disabled"); 2265 } 2266 mPw.println(); 2267 mPw.flush(); 2268 } finally { 2269 StrictMode.setThreadPolicy(oldPolicy); 2270 } 2271 } 2272 } 2273 2274 @Override 2275 public void onUidCachedChanged(int uid, boolean cached) { 2276 synchronized (this) { 2277 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2278 try { 2279 mPw.print(uid); 2280 mPw.println(cached ? " cached" : " uncached"); 2281 mPw.flush(); 2282 } finally { 2283 StrictMode.setThreadPolicy(oldPolicy); 2284 } 2285 } 2286 } 2287 2288 @Override 2289 public void onOomAdjMessage(String msg) { 2290 synchronized (this) { 2291 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2292 try { 2293 mPw.print("# "); 2294 mPw.println(msg); 2295 mPw.flush(); 2296 } finally { 2297 StrictMode.setThreadPolicy(oldPolicy); 2298 } 2299 } 2300 } 2301 2302 void printMessageForState() { 2303 switch (mState) { 2304 case STATE_NORMAL: 2305 mPw.println("Watching uid states... available commands:"); 2306 break; 2307 } 2308 mPw.println("(q)uit: finish watching"); 2309 } 2310 2311 void run() throws RemoteException { 2312 try { 2313 printMessageForState(); 2314 mPw.flush(); 2315 2316 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE 2317 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE 2318 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED, 2319 ActivityManager.PROCESS_STATE_UNKNOWN, null); 2320 if (mUid >= 0) { 2321 mInternal.setOomAdjObserver(mUid, this); 2322 } 2323 mState = STATE_NORMAL; 2324 2325 InputStreamReader converter = new InputStreamReader(mInput); 2326 BufferedReader in = new BufferedReader(converter); 2327 String line; 2328 2329 while ((line = in.readLine()) != null) { 2330 boolean addNewline = true; 2331 if (line.length() <= 0) { 2332 addNewline = false; 2333 } else if ("q".equals(line) || "quit".equals(line)) { 2334 break; 2335 } else { 2336 mPw.println("Invalid command: " + line); 2337 } 2338 2339 synchronized (this) { 2340 if (addNewline) { 2341 mPw.println(""); 2342 } 2343 printMessageForState(); 2344 mPw.flush(); 2345 } 2346 } 2347 2348 } catch (IOException e) { 2349 e.printStackTrace(mPw); 2350 mPw.flush(); 2351 } finally { 2352 if (mUid >= 0) { 2353 mInternal.clearOomAdjObserver(); 2354 } 2355 mInterface.unregisterUidObserver(this); 2356 } 2357 } 2358 } 2359 2360 int runWatchUids(PrintWriter pw) throws RemoteException { 2361 String opt; 2362 int uid = -1; 2363 2364 // Because a lot of CTS won't ignore capabilities newly added, we report 2365 // only the following capabilities -- the ones we had on Android T -- by default. 2366 int mask = PROCESS_CAPABILITY_FOREGROUND_LOCATION 2367 | PROCESS_CAPABILITY_FOREGROUND_CAMERA 2368 | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE 2369 | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; 2370 2371 while ((opt=getNextOption()) != null) { 2372 if (opt.equals("--oom")) { 2373 uid = Integer.parseInt(getNextArgRequired()); 2374 } else if (opt.equals("--mask")) { 2375 mask = Integer.parseInt(getNextArgRequired()); 2376 } else { 2377 getErrPrintWriter().println("Error: Unknown option: " + opt); 2378 return -1; 2379 2380 } 2381 } 2382 2383 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid, mask); 2384 controller.run(); 2385 return 0; 2386 } 2387 2388 int runHang(PrintWriter pw) throws RemoteException { 2389 String opt; 2390 boolean allowRestart = false; 2391 while ((opt=getNextOption()) != null) { 2392 if (opt.equals("--allow-restart")) { 2393 allowRestart = true; 2394 } else { 2395 getErrPrintWriter().println("Error: Unknown option: " + opt); 2396 return -1; 2397 } 2398 } 2399 2400 pw.println("Hanging the system..."); 2401 pw.flush(); 2402 try { 2403 mInterface.hang(getShellCallback().getShellCallbackBinder(), allowRestart); 2404 } catch (NullPointerException e) { 2405 pw.println("Hanging failed, since caller " + Binder.getCallingPid() + 2406 " did not provide a ShellCallback!"); 2407 pw.flush(); 2408 return 1; 2409 } 2410 return 0; 2411 } 2412 2413 int runRestart(PrintWriter pw) throws RemoteException { 2414 String opt; 2415 while ((opt=getNextOption()) != null) { 2416 getErrPrintWriter().println("Error: Unknown option: " + opt); 2417 return -1; 2418 } 2419 2420 pw.println("Restart the system..."); 2421 pw.flush(); 2422 mInterface.restart(); 2423 return 0; 2424 } 2425 2426 int runIdleMaintenance(PrintWriter pw) throws RemoteException { 2427 String opt; 2428 while ((opt=getNextOption()) != null) { 2429 getErrPrintWriter().println("Error: Unknown option: " + opt); 2430 return -1; 2431 } 2432 2433 pw.println("Performing idle maintenance..."); 2434 mInterface.sendIdleJobTrigger(); 2435 mInternal.performIdleMaintenance(); 2436 return 0; 2437 } 2438 2439 int runScreenCompat(PrintWriter pw) throws RemoteException { 2440 String mode = getNextArgRequired(); 2441 boolean enabled; 2442 if ("on".equals(mode)) { 2443 enabled = true; 2444 } else if ("off".equals(mode)) { 2445 enabled = false; 2446 } else { 2447 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode); 2448 return -1; 2449 } 2450 2451 String packageName = getNextArgRequired(); 2452 do { 2453 try { 2454 mInterface.setPackageScreenCompatMode(packageName, enabled 2455 ? ActivityManager.COMPAT_MODE_ENABLED 2456 : ActivityManager.COMPAT_MODE_DISABLED); 2457 } catch (RemoteException e) { 2458 } 2459 packageName = getNextArg(); 2460 } while (packageName != null); 2461 return 0; 2462 } 2463 2464 int runPackageImportance(PrintWriter pw) throws RemoteException { 2465 String packageName = getNextArgRequired(); 2466 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell"); 2467 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState)); 2468 return 0; 2469 } 2470 2471 int runToUri(PrintWriter pw, int flags) throws RemoteException { 2472 Intent intent; 2473 try { 2474 intent = makeIntent(UserHandle.USER_CURRENT); 2475 } catch (URISyntaxException e) { 2476 throw new RuntimeException(e.getMessage(), e); 2477 } 2478 pw.println(intent.toUri(flags)); 2479 return 0; 2480 } 2481 2482 private boolean switchUserAndWaitForComplete(int userId) throws RemoteException { 2483 UserInfo currentUser = mInterface.getCurrentUser(); 2484 if (currentUser != null && userId == currentUser.id) { 2485 // Already switched to the correct user, exit early. 2486 return true; 2487 } 2488 2489 // Register switch observer. 2490 final CountDownLatch switchLatch = new CountDownLatch(1); 2491 final IUserSwitchObserver userSwitchObserver = new UserSwitchObserver() { 2492 @Override 2493 public void onUserSwitchComplete(int newUserId) { 2494 if (userId == newUserId) { 2495 switchLatch.countDown(); 2496 } 2497 } 2498 }; 2499 try { 2500 mInterface.registerUserSwitchObserver(userSwitchObserver, 2501 ActivityManagerShellCommand.class.getName()); 2502 2503 // Switch. 2504 boolean switched = mInterface.switchUser(userId); 2505 if (!switched) { 2506 // Switching failed, don't wait for the user switch observer. 2507 return false; 2508 } 2509 2510 // Wait. 2511 try { 2512 switched = switchLatch.await(USER_OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS); 2513 } catch (InterruptedException e) { 2514 getErrPrintWriter().println("Error: Thread interrupted unexpectedly."); 2515 } 2516 2517 return switched; 2518 } finally { 2519 mInterface.unregisterUserSwitchObserver(userSwitchObserver); 2520 } 2521 } 2522 2523 int runSwitchUser(PrintWriter pw) throws RemoteException { 2524 boolean wait = false; 2525 String opt; 2526 while ((opt = getNextOption()) != null) { 2527 if ("-w".equals(opt)) { 2528 wait = true; 2529 } else { 2530 getErrPrintWriter().println("Error: unknown option: " + opt); 2531 return -1; 2532 } 2533 } 2534 2535 int userId = Integer.parseInt(getNextArgRequired()); 2536 2537 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class); 2538 final int userSwitchable = userManager.getUserSwitchability(UserHandle.of(userId)); 2539 if (userSwitchable != UserManager.SWITCHABILITY_STATUS_OK) { 2540 getErrPrintWriter().println("Error: UserSwitchabilityResult=" + userSwitchable); 2541 return -1; 2542 } 2543 2544 boolean switched; 2545 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "shell_runSwitchUser"); 2546 try { 2547 if (wait) { 2548 switched = switchUserAndWaitForComplete(userId); 2549 } else { 2550 switched = mInterface.switchUser(userId); 2551 } 2552 if (switched) { 2553 return 0; 2554 } else { 2555 pw.printf("Error: Failed to switch to user %d\n", userId); 2556 return 1; 2557 } 2558 } finally { 2559 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2560 } 2561 } 2562 2563 int runGetCurrentUser(PrintWriter pw) throws RemoteException { 2564 int userId = mInterface.getCurrentUserId(); 2565 if (userId == UserHandle.USER_NULL) { 2566 throw new IllegalStateException("Current user not set"); 2567 } 2568 pw.println(userId); 2569 return 0; 2570 } 2571 2572 int runStartUser(PrintWriter pw) throws RemoteException { 2573 boolean wait = false; 2574 String opt; 2575 int displayId = Display.INVALID_DISPLAY; 2576 while ((opt = getNextOption()) != null) { 2577 switch(opt) { 2578 case "-w": 2579 wait = true; 2580 break; 2581 case "--display": 2582 displayId = getDisplayIdFromNextArg(); 2583 break; 2584 default: 2585 getErrPrintWriter().println("Error: unknown option: " + opt); 2586 return -1; 2587 } 2588 } 2589 final int userId = Integer.parseInt(getNextArgRequired()); 2590 final ProgressWaiter waiter = wait ? new ProgressWaiter(userId) : null; 2591 2592 // For backwards compatibility, if the user is a profile, we need to define whether it 2593 // should be started visible (when its parent is the current user) or not (when it isn't) 2594 final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); 2595 final ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class); 2596 final int parentUserId = umi.getProfileParentId(userId); 2597 final int currentUserId = ami.getCurrentUserId(); 2598 final boolean isProfile = parentUserId != userId; 2599 final boolean isVisibleProfile = isProfile && parentUserId == currentUserId; 2600 Slogf.d(TAG, "runStartUser(): userId=%d, parentUserId=%d, currentUserId=%d, isProfile=%b, " 2601 + "isVisibleProfile=%b, display=%d, waiter=%s", userId, parentUserId, currentUserId, 2602 isProfile, isVisibleProfile, displayId, waiter); 2603 2604 boolean success; 2605 String displaySuffix = ""; 2606 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "shell_runStartUser" + userId); 2607 try { 2608 if (isVisibleProfile) { 2609 Slogf.d(TAG, "calling startProfileWithListener(%d, %s)", userId, waiter); 2610 // startProfileWithListener() will start the profile visible (as long its parent is 2611 // the current user), while startUserInBackgroundWithListener() will always start 2612 // the user (or profile) invisible 2613 success = mInterface.startProfileWithListener(userId, waiter); 2614 } else if (displayId == Display.INVALID_DISPLAY) { 2615 Slogf.d(TAG, "calling startUserInBackgroundWithListener(%d)", userId); 2616 success = mInterface.startUserInBackgroundWithListener(userId, waiter); 2617 } else { 2618 if (!UserManager.isVisibleBackgroundUsersEnabled()) { 2619 pw.println("Not supported"); 2620 return -1; 2621 } 2622 Slogf.d(TAG, "calling startUserInBackgroundVisibleOnDisplay(%d, %d, %s)", userId, 2623 displayId, waiter); 2624 success = mInterface.startUserInBackgroundVisibleOnDisplay(userId, displayId, 2625 waiter); 2626 displaySuffix = " on display " + displayId; 2627 } 2628 if (wait && success) { 2629 Slogf.d(TAG, "waiting %d ms", USER_OPERATION_TIMEOUT_MS); 2630 success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS); 2631 } 2632 } finally { 2633 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2634 } 2635 2636 if (success) { 2637 pw.println("Success: user started" + displaySuffix); 2638 } else { 2639 getErrPrintWriter().println("Error: could not start user" + displaySuffix); 2640 } 2641 return 0; 2642 } 2643 2644 int runUnlockUser(PrintWriter pw) throws RemoteException { 2645 int userId = Integer.parseInt(getNextArgRequired()); 2646 2647 /* 2648 * Originally this command required two more parameters: the hardware 2649 * authentication token and secret needed to unlock the user. However, 2650 * unlockUser() no longer takes a token parameter at all, and there 2651 * isn't really any way for callers of this shell command to get the 2652 * secret if one is needed (i.e., when the user has an LSKF), given that 2653 * the secret must be a cryptographic key derived from the user's 2654 * synthetic password. I.e. the secret is *not* the LSKF here, but 2655 * rather an intermediate value several steps down the chain. 2656 * 2657 * As such, the only supported use for this command is unlocking a user 2658 * who doesn't have an LSKF, with empty or unspecified token and secret. 2659 * 2660 * To preserve previous behavior, an exclamation mark ("!") is also 2661 * accepted for these values; it means the same as an empty string. 2662 */ 2663 String token = getNextArg(); 2664 if (!TextUtils.isEmpty(token) && !"!".equals(token)) { 2665 getErrPrintWriter().println("Error: token parameter not supported"); 2666 return -1; 2667 } 2668 String secret = getNextArg(); 2669 if (!TextUtils.isEmpty(secret) && !"!".equals(secret)) { 2670 getErrPrintWriter().println("Error: secret parameter not supported"); 2671 return -1; 2672 } 2673 2674 boolean success = mInterface.unlockUser2(userId, null); 2675 if (success) { 2676 pw.println("Success: user unlocked"); 2677 } else { 2678 // TODO(b/218389026): we can reach here even if the user's storage 2679 // was successfully unlocked. 2680 getErrPrintWriter().println("Error: could not unlock user"); 2681 } 2682 return 0; 2683 } 2684 2685 static final class StopUserCallback extends IStopUserCallback.Stub { 2686 private final @UserIdInt int mUserId; 2687 private boolean mFinished = false; 2688 2689 private StopUserCallback(@UserIdInt int userId) { 2690 mUserId = userId; 2691 } 2692 2693 public synchronized void waitForFinish() { 2694 try { 2695 while (!mFinished) wait(); 2696 } catch (InterruptedException e) { 2697 throw new IllegalStateException(e); 2698 } 2699 Slogf.d(TAG, "user %d finished stopping", mUserId); 2700 } 2701 2702 @Override 2703 public synchronized void userStopped(int userId) { 2704 Slogf.d(TAG, "StopUserCallback: userStopped(%d)", userId); 2705 mFinished = true; 2706 notifyAll(); 2707 } 2708 2709 @Override 2710 public synchronized void userStopAborted(int userId) { 2711 Slogf.d(TAG, "StopUserCallback: userStopAborted(%d)", userId); 2712 mFinished = true; 2713 notifyAll(); 2714 } 2715 2716 @Override 2717 public String toString() { 2718 return "ProgressWaiter[userId=" + mUserId + ", finished=" + mFinished + "]"; 2719 } 2720 } 2721 2722 int runStopUser(PrintWriter pw) throws RemoteException { 2723 boolean wait = false; 2724 boolean force = false; 2725 String opt; 2726 while ((opt = getNextOption()) != null) { 2727 if ("-w".equals(opt)) { 2728 wait = true; 2729 } else if ("-f".equals(opt)) { 2730 force = true; 2731 } else { 2732 getErrPrintWriter().println("Error: unknown option: " + opt); 2733 return -1; 2734 } 2735 } 2736 int userId = Integer.parseInt(getNextArgRequired()); 2737 StopUserCallback callback = wait ? new StopUserCallback(userId) : null; 2738 2739 Slogf.d(TAG, "Calling stopUser(%d, %b, %s)", userId, force, callback); 2740 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, 2741 "shell_runStopUser-" + userId + "-[stopUser]"); 2742 try { 2743 int res = mInterface.stopUserExceptCertainProfiles( 2744 userId, /* stopProfileRegardlessOfParent= */ force, callback); 2745 if (res != ActivityManager.USER_OP_SUCCESS) { 2746 String txt = ""; 2747 switch (res) { 2748 case ActivityManager.USER_OP_IS_CURRENT: 2749 txt = " (Can't stop current user)"; 2750 break; 2751 case ActivityManager.USER_OP_UNKNOWN_USER: 2752 txt = " (Unknown user " + userId + ")"; 2753 break; 2754 case ActivityManager.USER_OP_ERROR_IS_SYSTEM: 2755 txt = " (System user cannot be stopped)"; 2756 break; 2757 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP: 2758 txt = " (Can't stop user " + userId 2759 + " - one of its related users can't be stopped)"; 2760 break; 2761 } 2762 getErrPrintWriter().println("Switch failed: " + res + txt); 2763 return -1; 2764 } else if (callback != null) { 2765 callback.waitForFinish(); 2766 } 2767 return 0; 2768 } finally { 2769 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 2770 } 2771 } 2772 2773 int runIsUserStopped(PrintWriter pw) { 2774 int userId = UserHandle.parseUserArg(getNextArgRequired()); 2775 boolean stopped = mInternal.isUserStopped(userId); 2776 pw.println(stopped); 2777 return 0; 2778 } 2779 2780 int runGetStartedUserState(PrintWriter pw) throws RemoteException { 2781 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP, 2782 "runGetStartedUserState()"); 2783 final int userId = Integer.parseInt(getNextArgRequired()); 2784 try { 2785 pw.println(mInternal.getStartedUserState(userId)); 2786 } catch (NullPointerException e) { 2787 pw.println("User is not started: " + userId); 2788 } 2789 return 0; 2790 } 2791 2792 int runTrackAssociations(PrintWriter pw) { 2793 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 2794 "runTrackAssociations()"); 2795 synchronized (mInternal) { 2796 if (!mInternal.mTrackingAssociations) { 2797 mInternal.mTrackingAssociations = true; 2798 pw.println("Association tracking started."); 2799 } else { 2800 pw.println("Association tracking already enabled."); 2801 } 2802 } 2803 return 0; 2804 } 2805 2806 int runUntrackAssociations(PrintWriter pw) { 2807 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 2808 "runUntrackAssociations()"); 2809 synchronized (mInternal) { 2810 if (mInternal.mTrackingAssociations) { 2811 mInternal.mTrackingAssociations = false; 2812 mInternal.mAssociations.clear(); 2813 pw.println("Association tracking stopped."); 2814 } else { 2815 pw.println("Association tracking not running."); 2816 } 2817 } 2818 return 0; 2819 } 2820 2821 int getUidState(PrintWriter pw) throws RemoteException { 2822 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP, 2823 "getUidState()"); 2824 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired())); 2825 pw.print(state); 2826 pw.print(" ("); 2827 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state)); 2828 pw.println(")"); 2829 return 0; 2830 } 2831 2832 private List<Configuration> getRecentConfigurations(int days) { 2833 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 2834 Context.USAGE_STATS_SERVICE)); 2835 final long now = System.currentTimeMillis(); 2836 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000); 2837 try { 2838 @SuppressWarnings("unchecked") 2839 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats( 2840 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell"); 2841 if (configStatsSlice == null) { 2842 return Collections.emptyList(); 2843 } 2844 2845 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>(); 2846 final List<ConfigurationStats> configStatsList = configStatsSlice.getList(); 2847 final int configStatsListSize = configStatsList.size(); 2848 for (int i = 0; i < configStatsListSize; i++) { 2849 final ConfigurationStats stats = configStatsList.get(i); 2850 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration()); 2851 if (indexOfKey < 0) { 2852 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount()); 2853 } else { 2854 recentConfigs.setValueAt(indexOfKey, 2855 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount()); 2856 } 2857 } 2858 2859 final Comparator<Configuration> comparator = new Comparator<Configuration>() { 2860 @Override 2861 public int compare(Configuration a, Configuration b) { 2862 return recentConfigs.get(b).compareTo(recentConfigs.get(a)); 2863 } 2864 }; 2865 2866 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size()); 2867 configs.addAll(recentConfigs.keySet()); 2868 Collections.sort(configs, comparator); 2869 return configs; 2870 2871 } catch (RemoteException e) { 2872 return Collections.emptyList(); 2873 } 2874 } 2875 2876 /** 2877 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext 2878 * and EGLSurface and querying extensions. 2879 * 2880 * @param egl An EGL API object 2881 * @param display An EGLDisplay to create a context and surface with 2882 * @param config The EGLConfig to get the extensions for 2883 * @param surfaceSize eglCreatePbufferSurface generic parameters 2884 * @param contextAttribs eglCreateContext generic parameters 2885 * @param glExtensions A Set<String> to add GL extensions to 2886 */ 2887 private static void addExtensionsForConfig( 2888 EGL10 egl, 2889 EGLDisplay display, 2890 EGLConfig config, 2891 int[] surfaceSize, 2892 int[] contextAttribs, 2893 Set<String> glExtensions) { 2894 // Create a context. 2895 EGLContext context = 2896 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs); 2897 // No-op if we can't create a context. 2898 if (context == EGL10.EGL_NO_CONTEXT) { 2899 return; 2900 } 2901 2902 // Create a surface. 2903 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize); 2904 if (surface == EGL10.EGL_NO_SURFACE) { 2905 egl.eglDestroyContext(display, context); 2906 return; 2907 } 2908 2909 // Update the current surface and context. 2910 egl.eglMakeCurrent(display, surface, surface, context); 2911 2912 // Get the list of extensions. 2913 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS); 2914 if (!TextUtils.isEmpty(extensionList)) { 2915 // The list of extensions comes from the driver separated by spaces. 2916 // Split them apart and add them into a Set for deduping purposes. 2917 for (String extension : extensionList.split(" ")) { 2918 glExtensions.add(extension); 2919 } 2920 } 2921 2922 // Tear down the context and surface for this config. 2923 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); 2924 egl.eglDestroySurface(display, surface); 2925 egl.eglDestroyContext(display, context); 2926 } 2927 2928 2929 Set<String> getGlExtensionsFromDriver() { 2930 Set<String> glExtensions = new HashSet<>(); 2931 2932 // Get the EGL implementation. 2933 EGL10 egl = (EGL10) EGLContext.getEGL(); 2934 if (egl == null) { 2935 getErrPrintWriter().println("Warning: couldn't get EGL"); 2936 return glExtensions; 2937 } 2938 2939 // Get the default display and initialize it. 2940 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 2941 int[] version = new int[2]; 2942 egl.eglInitialize(display, version); 2943 2944 // Call getConfigs() in order to find out how many there are. 2945 int[] numConfigs = new int[1]; 2946 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) { 2947 getErrPrintWriter().println("Warning: couldn't get EGL config count"); 2948 return glExtensions; 2949 } 2950 2951 // Allocate space for all configs and ask again. 2952 EGLConfig[] configs = new EGLConfig[numConfigs[0]]; 2953 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) { 2954 getErrPrintWriter().println("Warning: couldn't get EGL configs"); 2955 return glExtensions; 2956 } 2957 2958 // Allocate surface size parameters outside of the main loop to cut down 2959 // on GC thrashing. 1x1 is enough since we are only using it to get at 2960 // the list of extensions. 2961 int[] surfaceSize = 2962 new int[] { 2963 EGL10.EGL_WIDTH, 1, 2964 EGL10.EGL_HEIGHT, 1, 2965 EGL10.EGL_NONE 2966 }; 2967 2968 // For when we need to create a GLES2.0 context. 2969 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 2970 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE}; 2971 2972 // For getting return values from eglGetConfigAttrib 2973 int[] attrib = new int[1]; 2974 2975 for (int i = 0; i < numConfigs[0]; i++) { 2976 // Get caveat for this config in order to skip slow (i.e. software) configs. 2977 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib); 2978 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) { 2979 continue; 2980 } 2981 2982 // If the config does not support pbuffers we cannot do an eglMakeCurrent 2983 // on it in addExtensionsForConfig(), so skip it here. Attempting to make 2984 // it current with a pbuffer will result in an EGL_BAD_MATCH error 2985 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib); 2986 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) { 2987 continue; 2988 } 2989 2990 final int EGL_OPENGL_ES_BIT = 0x0001; 2991 final int EGL_OPENGL_ES2_BIT = 0x0004; 2992 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib); 2993 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) { 2994 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions); 2995 } 2996 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) { 2997 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions); 2998 } 2999 } 3000 3001 // Release all EGL resources. 3002 egl.eglTerminate(display); 3003 3004 return glExtensions; 3005 } 3006 3007 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId, 3008 PrintWriter pw, Configuration config, DisplayMetrics displayMetrics) { 3009 long token = -1; 3010 if (protoOutputStream != null) { 3011 token = protoOutputStream.start(fieldId); 3012 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX, 3013 displayMetrics.widthPixels); 3014 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX, 3015 displayMetrics.heightPixels); 3016 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI, 3017 DisplayMetrics.DENSITY_DEVICE_STABLE); 3018 } 3019 if (pw != null) { 3020 pw.print("stable-width-px: "); pw.println(displayMetrics.widthPixels); 3021 pw.print("stable-height-px: "); pw.println(displayMetrics.heightPixels); 3022 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE); 3023 } 3024 3025 MemInfoReader memreader = new MemInfoReader(); 3026 memreader.readMemInfo(); 3027 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class); 3028 if (protoOutputStream != null) { 3029 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize()); 3030 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM, 3031 ActivityManager.isLowRamDeviceStatic()); 3032 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES, 3033 Runtime.getRuntime().availableProcessors()); 3034 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK, 3035 kgm.isDeviceSecure()); 3036 } 3037 if (pw != null) { 3038 pw.print("total-ram: "); pw.println(memreader.getTotalSize()); 3039 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic()); 3040 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors()); 3041 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure()); 3042 } 3043 3044 ConfigurationInfo configInfo = null; 3045 try { 3046 configInfo = mTaskInterface.getDeviceConfigurationInfo(); 3047 } catch (RemoteException e) { 3048 throw e.rethrowFromSystemServer(); 3049 } 3050 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) { 3051 if (protoOutputStream != null) { 3052 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION, 3053 configInfo.reqGlEsVersion); 3054 } 3055 if (pw != null) { 3056 pw.print("opengl-version: 0x"); 3057 pw.println(Integer.toHexString(configInfo.reqGlEsVersion)); 3058 } 3059 } 3060 3061 Set<String> glExtensionsSet = getGlExtensionsFromDriver(); 3062 String[] glExtensions = new String[glExtensionsSet.size()]; 3063 glExtensions = glExtensionsSet.toArray(glExtensions); 3064 Arrays.sort(glExtensions); 3065 for (int i = 0; i < glExtensions.length; i++) { 3066 if (protoOutputStream != null) { 3067 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS, 3068 glExtensions[i]); 3069 } 3070 if (pw != null) { 3071 pw.print("opengl-extensions: "); pw.println(glExtensions[i]); 3072 } 3073 3074 } 3075 3076 PackageManager pm = mInternal.mContext.getPackageManager(); 3077 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0); 3078 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName)); 3079 for (int i = 0; i < slibs.size(); i++) { 3080 if (protoOutputStream != null) { 3081 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES, 3082 slibs.get(i).getName()); 3083 } 3084 if (pw != null) { 3085 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName()); 3086 } 3087 } 3088 3089 FeatureInfo[] features = pm.getSystemAvailableFeatures(); 3090 Arrays.sort(features, (o1, o2) -> { 3091 if (o1.name == o2.name) return 0; 3092 if (o1.name == null) return -1; 3093 if (o2.name == null) return 1; 3094 return o1.name.compareTo(o2.name); 3095 }); 3096 3097 for (int i = 0; i < features.length; i++) { 3098 if (features[i].name != null) { 3099 if (protoOutputStream != null) { 3100 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name); 3101 } 3102 if (pw != null) { 3103 pw.print("features: "); pw.println(features[i].name); 3104 } 3105 } 3106 } 3107 3108 if (protoOutputStream != null) { 3109 protoOutputStream.end(token); 3110 } 3111 } 3112 3113 private int getDisplayIdFromNextArg() { 3114 int displayId = Integer.parseInt(getNextArgRequired()); 3115 if (displayId < 0) { 3116 throw new IllegalArgumentException("--display must be a non-negative integer"); 3117 } 3118 return displayId; 3119 } 3120 3121 int runGetConfig(PrintWriter pw) throws RemoteException { 3122 int days = -1; 3123 int displayId = Display.DEFAULT_DISPLAY; 3124 boolean asProto = false; 3125 boolean inclDevice = false; 3126 3127 String opt; 3128 while ((opt = getNextOption()) != null) { 3129 if (opt.equals("--days")) { 3130 days = Integer.parseInt(getNextArgRequired()); 3131 if (days <= 0) { 3132 throw new IllegalArgumentException("--days must be a positive integer"); 3133 } 3134 } else if (opt.equals("--proto")) { 3135 asProto = true; 3136 } else if (opt.equals("--device")) { 3137 inclDevice = true; 3138 } else if (opt.equals("--display")) { 3139 displayId = getDisplayIdFromNextArg(); 3140 } else { 3141 getErrPrintWriter().println("Error: Unknown option: " + opt); 3142 return -1; 3143 } 3144 } 3145 3146 Configuration config = mInterface.getConfiguration(); 3147 if (config == null) { 3148 getErrPrintWriter().println("Activity manager has no configuration"); 3149 return -1; 3150 } 3151 3152 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class); 3153 Display display = dm.getDisplay(displayId); 3154 3155 if (display == null) { 3156 getErrPrintWriter().println("Error: Display does not exist: " + displayId); 3157 return -1; 3158 } 3159 3160 DisplayMetrics metrics = new DisplayMetrics(); 3161 display.getMetrics(metrics); 3162 3163 if (asProto) { 3164 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor()); 3165 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics); 3166 if (inclDevice) { 3167 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, metrics); 3168 } 3169 proto.flush(); 3170 } else { 3171 pw.println("config: " + Configuration.resourceQualifierString(config, metrics)); 3172 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS)); 3173 if (inclDevice) { 3174 writeDeviceConfig(null, -1, pw, config, metrics); 3175 } 3176 3177 if (days >= 0) { 3178 final List<Configuration> recentConfigs = getRecentConfigurations(days); 3179 final int recentConfigSize = recentConfigs.size(); 3180 if (recentConfigSize > 0) { 3181 pw.println("recentConfigs:"); 3182 for (int i = 0; i < recentConfigSize; i++) { 3183 pw.println(" config: " + Configuration.resourceQualifierString( 3184 recentConfigs.get(i))); 3185 } 3186 } 3187 } 3188 3189 } 3190 return 0; 3191 } 3192 3193 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException { 3194 boolean suppress = Boolean.valueOf(getNextArgRequired()); 3195 mTaskInterface.suppressResizeConfigChanges(suppress); 3196 return 0; 3197 } 3198 3199 int runSetInactive(PrintWriter pw) throws RemoteException { 3200 int userId = UserHandle.USER_CURRENT; 3201 3202 String opt; 3203 while ((opt=getNextOption()) != null) { 3204 if (opt.equals("--user")) { 3205 userId = UserHandle.parseUserArg(getNextArgRequired()); 3206 } else { 3207 getErrPrintWriter().println("Error: Unknown option: " + opt); 3208 return -1; 3209 } 3210 } 3211 String packageName = getNextArgRequired(); 3212 String value = getNextArgRequired(); 3213 3214 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 3215 Context.USAGE_STATS_SERVICE)); 3216 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId); 3217 return 0; 3218 } 3219 3220 private int bucketNameToBucketValue(String name) { 3221 String lower = name.toLowerCase(); 3222 if (lower.startsWith("ac")) { 3223 return UsageStatsManager.STANDBY_BUCKET_ACTIVE; 3224 } else if (lower.startsWith("wo")) { 3225 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET; 3226 } else if (lower.startsWith("fr")) { 3227 return UsageStatsManager.STANDBY_BUCKET_FREQUENT; 3228 } else if (lower.startsWith("ra")) { 3229 return UsageStatsManager.STANDBY_BUCKET_RARE; 3230 } else if (lower.startsWith("re")) { 3231 return UsageStatsManager.STANDBY_BUCKET_RESTRICTED; 3232 } else if (lower.startsWith("ne")) { 3233 return UsageStatsManager.STANDBY_BUCKET_NEVER; 3234 } else { 3235 try { 3236 int bucket = Integer.parseInt(lower); 3237 return bucket; 3238 } catch (NumberFormatException nfe) { 3239 getErrPrintWriter().println("Error: Unknown bucket: " + name); 3240 } 3241 } 3242 return -1; 3243 } 3244 3245 int runSetStandbyBucket(PrintWriter pw) throws RemoteException { 3246 int userId = UserHandle.USER_CURRENT; 3247 3248 String opt; 3249 while ((opt=getNextOption()) != null) { 3250 if (opt.equals("--user")) { 3251 userId = UserHandle.parseUserArg(getNextArgRequired()); 3252 } else { 3253 getErrPrintWriter().println("Error: Unknown option: " + opt); 3254 return -1; 3255 } 3256 } 3257 String packageName = getNextArgRequired(); 3258 String value = getNextArgRequired(); 3259 int bucket = bucketNameToBucketValue(value); 3260 if (bucket < 0) return -1; 3261 boolean multiple = peekNextArg() != null; 3262 3263 3264 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 3265 Context.USAGE_STATS_SERVICE)); 3266 if (!multiple) { 3267 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId); 3268 } else { 3269 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>(); 3270 bucketInfoList.add(new AppStandbyInfo(packageName, bucket)); 3271 while ((packageName = getNextArg()) != null) { 3272 value = getNextArgRequired(); 3273 bucket = bucketNameToBucketValue(value); 3274 if (bucket < 0) continue; 3275 bucketInfoList.add(new AppStandbyInfo(packageName, bucket)); 3276 } 3277 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList); 3278 usm.setAppStandbyBuckets(slice, userId); 3279 } 3280 return 0; 3281 } 3282 3283 int runGetStandbyBucket(PrintWriter pw) throws RemoteException { 3284 int userId = UserHandle.USER_CURRENT; 3285 3286 String opt; 3287 while ((opt=getNextOption()) != null) { 3288 if (opt.equals("--user")) { 3289 userId = UserHandle.parseUserArg(getNextArgRequired()); 3290 } else { 3291 getErrPrintWriter().println("Error: Unknown option: " + opt); 3292 return -1; 3293 } 3294 } 3295 String packageName = getNextArg(); 3296 3297 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 3298 Context.USAGE_STATS_SERVICE)); 3299 if (packageName != null) { 3300 int bucket = usm.getAppStandbyBucket(packageName, null, userId); 3301 pw.println(bucket); 3302 } else { 3303 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets( 3304 SHELL_PACKAGE_NAME, userId); 3305 for (AppStandbyInfo bucketInfo : buckets.getList()) { 3306 pw.print(bucketInfo.mPackageName); pw.print(": "); 3307 pw.println(bucketInfo.mStandbyBucket); 3308 } 3309 } 3310 return 0; 3311 } 3312 3313 int runGetInactive(PrintWriter pw) throws RemoteException { 3314 int userId = UserHandle.USER_CURRENT; 3315 3316 String opt; 3317 while ((opt=getNextOption()) != null) { 3318 if (opt.equals("--user")) { 3319 userId = UserHandle.parseUserArg(getNextArgRequired()); 3320 } else { 3321 getErrPrintWriter().println("Error: Unknown option: " + opt); 3322 return -1; 3323 } 3324 } 3325 String packageName = getNextArgRequired(); 3326 3327 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 3328 Context.USAGE_STATS_SERVICE)); 3329 boolean isIdle = usm.isAppInactive(packageName, userId, SHELL_PACKAGE_NAME); 3330 pw.println("Idle=" + isIdle); 3331 return 0; 3332 } 3333 3334 int runSendTrimMemory(PrintWriter pw) throws RemoteException { 3335 int userId = UserHandle.USER_CURRENT; 3336 String opt; 3337 while ((opt = getNextOption()) != null) { 3338 if (opt.equals("--user")) { 3339 userId = UserHandle.parseUserArg(getNextArgRequired()); 3340 if (userId == UserHandle.USER_ALL) { 3341 getErrPrintWriter().println("Error: Can't use user 'all'"); 3342 return -1; 3343 } 3344 } else { 3345 getErrPrintWriter().println("Error: Unknown option: " + opt); 3346 return -1; 3347 } 3348 } 3349 3350 String proc = getNextArgRequired(); 3351 String levelArg = getNextArgRequired(); 3352 int level; 3353 switch (levelArg) { 3354 case "HIDDEN": 3355 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 3356 break; 3357 case "RUNNING_MODERATE": 3358 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 3359 break; 3360 case "BACKGROUND": 3361 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 3362 break; 3363 case "RUNNING_LOW": 3364 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 3365 break; 3366 case "MODERATE": 3367 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 3368 break; 3369 case "RUNNING_CRITICAL": 3370 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 3371 break; 3372 case "COMPLETE": 3373 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 3374 break; 3375 default: 3376 try { 3377 level = Integer.parseInt(levelArg); 3378 } catch (NumberFormatException e) { 3379 getErrPrintWriter().println("Error: Unknown level option: " + levelArg); 3380 return -1; 3381 } 3382 } 3383 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) { 3384 getErrPrintWriter().println("Unknown error: failed to set trim level"); 3385 return -1; 3386 } 3387 return 0; 3388 } 3389 3390 int runDisplay(PrintWriter pw) throws RemoteException { 3391 String op = getNextArgRequired(); 3392 switch (op) { 3393 case "move-stack": 3394 return runDisplayMoveStack(pw); 3395 default: 3396 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 3397 return -1; 3398 } 3399 } 3400 3401 int runStack(PrintWriter pw) throws RemoteException { 3402 String op = getNextArgRequired(); 3403 switch (op) { 3404 case "move-task": 3405 return runStackMoveTask(pw); 3406 case "list": 3407 return runStackList(pw); 3408 case "info": 3409 return runRootTaskInfo(pw); 3410 case "remove": 3411 return runRootTaskRemove(pw); 3412 default: 3413 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 3414 return -1; 3415 } 3416 } 3417 3418 3419 private Rect getBounds() { 3420 String leftStr = getNextArgRequired(); 3421 int left = Integer.parseInt(leftStr); 3422 String topStr = getNextArgRequired(); 3423 int top = Integer.parseInt(topStr); 3424 String rightStr = getNextArgRequired(); 3425 int right = Integer.parseInt(rightStr); 3426 String bottomStr = getNextArgRequired(); 3427 int bottom = Integer.parseInt(bottomStr); 3428 if (left < 0) { 3429 getErrPrintWriter().println("Error: bad left arg: " + leftStr); 3430 return null; 3431 } 3432 if (top < 0) { 3433 getErrPrintWriter().println("Error: bad top arg: " + topStr); 3434 return null; 3435 } 3436 if (right <= 0) { 3437 getErrPrintWriter().println("Error: bad right arg: " + rightStr); 3438 return null; 3439 } 3440 if (bottom <= 0) { 3441 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr); 3442 return null; 3443 } 3444 return new Rect(left, top, right, bottom); 3445 } 3446 3447 int runDisplayMoveStack(PrintWriter pw) throws RemoteException { 3448 String rootTaskIdStr = getNextArgRequired(); 3449 int rootTaskId = Integer.parseInt(rootTaskIdStr); 3450 String displayIdStr = getNextArgRequired(); 3451 int displayId = Integer.parseInt(displayIdStr); 3452 mTaskInterface.moveRootTaskToDisplay(rootTaskId, displayId); 3453 return 0; 3454 } 3455 3456 int runStackMoveTask(PrintWriter pw) throws RemoteException { 3457 String taskIdStr = getNextArgRequired(); 3458 int taskId = Integer.parseInt(taskIdStr); 3459 String rootTaskIdStr = getNextArgRequired(); 3460 int rootTaskId = Integer.parseInt(rootTaskIdStr); 3461 String toTopStr = getNextArgRequired(); 3462 final boolean toTop; 3463 if ("true".equals(toTopStr)) { 3464 toTop = true; 3465 } else if ("false".equals(toTopStr)) { 3466 toTop = false; 3467 } else { 3468 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr); 3469 return -1; 3470 } 3471 3472 mTaskInterface.moveTaskToRootTask(taskId, rootTaskId, toTop); 3473 return 0; 3474 } 3475 3476 int runStackList(PrintWriter pw) throws RemoteException { 3477 List<RootTaskInfo> tasks = mTaskInterface.getAllRootTaskInfos(); 3478 for (RootTaskInfo info : tasks) { 3479 pw.println(info); 3480 } 3481 return 0; 3482 } 3483 3484 int runRootTaskInfo(PrintWriter pw) throws RemoteException { 3485 int windowingMode = Integer.parseInt(getNextArgRequired()); 3486 int activityType = Integer.parseInt(getNextArgRequired()); 3487 RootTaskInfo info = mTaskInterface.getRootTaskInfo(windowingMode, activityType); 3488 pw.println(info); 3489 return 0; 3490 } 3491 3492 int runRootTaskRemove(PrintWriter pw) throws RemoteException { 3493 String taskIdStr = getNextArgRequired(); 3494 int taskId = Integer.parseInt(taskIdStr); 3495 mTaskInterface.removeTask(taskId); 3496 return 0; 3497 } 3498 3499 int runTask(PrintWriter pw) throws RemoteException { 3500 String op = getNextArgRequired(); 3501 if (op.equals("lock")) { 3502 return runTaskLock(pw); 3503 } else if (op.equals("resizeable")) { 3504 return runTaskResizeable(pw); 3505 } else if (op.equals("resize")) { 3506 return runTaskResize(pw); 3507 } else if (op.equals("focus")) { 3508 return runTaskFocus(pw); 3509 } else { 3510 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 3511 return -1; 3512 } 3513 } 3514 3515 int runTaskLock(PrintWriter pw) throws RemoteException { 3516 String taskIdStr = getNextArgRequired(); 3517 if (taskIdStr.equals("stop")) { 3518 mTaskInterface.stopSystemLockTaskMode(); 3519 } else { 3520 int taskId = Integer.parseInt(taskIdStr); 3521 mTaskInterface.startSystemLockTaskMode(taskId); 3522 } 3523 pw.println("Activity manager is " + (mTaskInterface.isInLockTaskMode() ? "" : "not ") + 3524 "in lockTaskMode"); 3525 return 0; 3526 } 3527 3528 int runTaskResizeable(PrintWriter pw) throws RemoteException { 3529 final String taskIdStr = getNextArgRequired(); 3530 final int taskId = Integer.parseInt(taskIdStr); 3531 final String resizeableStr = getNextArgRequired(); 3532 final int resizeableMode = Integer.parseInt(resizeableStr); 3533 mTaskInterface.setTaskResizeable(taskId, resizeableMode); 3534 return 0; 3535 } 3536 3537 int runTaskResize(PrintWriter pw) throws RemoteException { 3538 final String taskIdStr = getNextArgRequired(); 3539 final int taskId = Integer.parseInt(taskIdStr); 3540 final Rect bounds = getBounds(); 3541 if (bounds == null) { 3542 getErrPrintWriter().println("Error: invalid input bounds"); 3543 return -1; 3544 } 3545 taskResize(taskId, bounds, 0, false); 3546 return 0; 3547 } 3548 3549 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize) 3550 throws RemoteException { 3551 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM; 3552 mTaskInterface.resizeTask(taskId, bounds, resizeMode); 3553 try { 3554 Thread.sleep(delay_ms); 3555 } catch (InterruptedException e) { 3556 } 3557 } 3558 3559 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize, 3560 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms) 3561 throws RemoteException { 3562 int maxMove; 3563 if (movingForward) { 3564 while (maxToTravel > 0 3565 && ((horizontal && taskRect.right < stackRect.right) 3566 ||(!horizontal && taskRect.bottom < stackRect.bottom))) { 3567 if (horizontal) { 3568 maxMove = Math.min(stepSize, stackRect.right - taskRect.right); 3569 maxToTravel -= maxMove; 3570 taskRect.right += maxMove; 3571 taskRect.left += maxMove; 3572 } else { 3573 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom); 3574 maxToTravel -= maxMove; 3575 taskRect.top += maxMove; 3576 taskRect.bottom += maxMove; 3577 } 3578 taskResize(taskId, taskRect, delay_ms, false); 3579 } 3580 } else { 3581 while (maxToTravel < 0 3582 && ((horizontal && taskRect.left > stackRect.left) 3583 ||(!horizontal && taskRect.top > stackRect.top))) { 3584 if (horizontal) { 3585 maxMove = Math.min(stepSize, taskRect.left - stackRect.left); 3586 maxToTravel -= maxMove; 3587 taskRect.right -= maxMove; 3588 taskRect.left -= maxMove; 3589 } else { 3590 maxMove = Math.min(stepSize, taskRect.top - stackRect.top); 3591 maxToTravel -= maxMove; 3592 taskRect.top -= maxMove; 3593 taskRect.bottom -= maxMove; 3594 } 3595 taskResize(taskId, taskRect, delay_ms, false); 3596 } 3597 } 3598 // Return the remaining distance we didn't travel because we reached the target location. 3599 return maxToTravel; 3600 } 3601 3602 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) { 3603 int stepSize = 0; 3604 if (greaterThanTarget && target < current) { 3605 current -= inStepSize; 3606 stepSize = inStepSize; 3607 if (target > current) { 3608 stepSize -= (target - current); 3609 } 3610 } 3611 if (!greaterThanTarget && target > current) { 3612 current += inStepSize; 3613 stepSize = inStepSize; 3614 if (target < current) { 3615 stepSize += (current - target); 3616 } 3617 } 3618 return stepSize; 3619 } 3620 3621 int runTaskFocus(PrintWriter pw) throws RemoteException { 3622 final int taskId = Integer.parseInt(getNextArgRequired()); 3623 pw.println("Setting focus to task " + taskId); 3624 mTaskInterface.setFocusedTask(taskId); 3625 return 0; 3626 } 3627 3628 int runWrite(PrintWriter pw) { 3629 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 3630 "registerUidObserver()"); 3631 mInternal.mAtmInternal.flushRecentTasks(); 3632 pw.println("All tasks persisted."); 3633 return 0; 3634 } 3635 3636 int runAttachAgent(PrintWriter pw) { 3637 // TODO: revisit the permissions required for attaching agents 3638 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 3639 "attach-agent"); 3640 String process = getNextArgRequired(); 3641 String agent = getNextArgRequired(); 3642 String opt; 3643 if ((opt = getNextArg()) != null) { 3644 pw.println("Error: Unknown option: " + opt); 3645 return -1; 3646 } 3647 mInternal.attachAgent(process, agent); 3648 return 0; 3649 } 3650 3651 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException { 3652 final Resources res = getResources(pw); 3653 if (res == null) { 3654 return -1; 3655 } 3656 pw.println(ActivityTaskManager.supportsMultiWindow(mInternal.mContext)); 3657 return 0; 3658 } 3659 3660 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException { 3661 final Resources res = getResources(pw); 3662 if (res == null) { 3663 return -1; 3664 } 3665 pw.println(ActivityTaskManager.supportsSplitScreenMultiWindow(mInternal.mContext)); 3666 return 0; 3667 } 3668 3669 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException { 3670 int userid = UserHandle.parseUserArg(getNextArgRequired()); 3671 ArrayList<String> packages = new ArrayList<>(); 3672 packages.add(getNextArgRequired()); 3673 String packageName; 3674 while ((packageName = getNextArg()) != null) { 3675 packages.add(packageName); 3676 } 3677 mInternal.scheduleApplicationInfoChanged(packages, userid); 3678 pw.println("Packages updated with most recent ApplicationInfos."); 3679 return 0; 3680 } 3681 3682 int runNoHomeScreen(PrintWriter pw) throws RemoteException { 3683 final Resources res = getResources(pw); 3684 if (res == null) { 3685 return -1; 3686 } 3687 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen)); 3688 return 0; 3689 } 3690 3691 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException { 3692 pw = new PrintWriter(new TeeWriter(LOG_WRITER_INFO, pw)); 3693 boolean flushBroadcastLoopers = false; 3694 String opt; 3695 while ((opt = getNextOption()) != null) { 3696 if (opt.equals("--flush-broadcast-loopers")) { 3697 flushBroadcastLoopers = true; 3698 } else { 3699 getErrPrintWriter().println("Error: Unknown option: " + opt); 3700 return -1; 3701 } 3702 } 3703 mInternal.waitForBroadcastIdle(pw, flushBroadcastLoopers); 3704 return 0; 3705 } 3706 3707 int runWaitForBroadcastBarrier(PrintWriter pw) throws RemoteException { 3708 pw = new PrintWriter(new TeeWriter(LOG_WRITER_INFO, pw)); 3709 boolean flushBroadcastLoopers = false; 3710 boolean flushApplicationThreads = false; 3711 String opt; 3712 while ((opt = getNextOption()) != null) { 3713 if (opt.equals("--flush-broadcast-loopers")) { 3714 flushBroadcastLoopers = true; 3715 } else if (opt.equals("--flush-application-threads")) { 3716 flushApplicationThreads = true; 3717 } else { 3718 getErrPrintWriter().println("Error: Unknown option: " + opt); 3719 return -1; 3720 } 3721 } 3722 mInternal.waitForBroadcastBarrier(pw, flushBroadcastLoopers, flushApplicationThreads); 3723 return 0; 3724 } 3725 3726 int runWaitForApplicationBarrier(PrintWriter pw) throws RemoteException { 3727 pw = new PrintWriter(new TeeWriter(LOG_WRITER_INFO, pw)); 3728 mInternal.waitForApplicationBarrier(pw); 3729 return 0; 3730 } 3731 3732 int runWaitForBroadcastDispatch(PrintWriter pw) throws RemoteException { 3733 pw = new PrintWriter(new TeeWriter(LOG_WRITER_INFO, pw)); 3734 final Intent intent; 3735 try { 3736 intent = makeIntent(UserHandle.USER_CURRENT); 3737 } catch (URISyntaxException e) { 3738 throw new RuntimeException(e.getMessage(), e); 3739 } 3740 mInternal.waitForBroadcastDispatch(pw, intent); 3741 return 0; 3742 } 3743 3744 int runSetIgnoreDeliveryGroupPolicy(PrintWriter pw) throws RemoteException { 3745 final String broadcastAction = getNextArgRequired(); 3746 mInternal.setIgnoreDeliveryGroupPolicy(broadcastAction); 3747 return 0; 3748 } 3749 3750 int runClearIgnoreDeliveryGroupPolicy(PrintWriter pw) throws RemoteException { 3751 final String broadcastAction = getNextArgRequired(); 3752 mInternal.clearIgnoreDeliveryGroupPolicy(broadcastAction); 3753 return 0; 3754 } 3755 3756 int runRefreshSettingsCache() throws RemoteException { 3757 mInternal.refreshSettingsCache(); 3758 return 0; 3759 } 3760 3761 private int runCompat(PrintWriter pw) throws RemoteException { 3762 final PlatformCompat platformCompat = (PlatformCompat) 3763 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE); 3764 String toggleValue = getNextArgRequired(); 3765 boolean killPackage = !"--no-kill".equals(getNextOption()); 3766 boolean toggleAll = false; 3767 int targetSdkVersion = -1; 3768 long changeId = -1; 3769 3770 if (toggleValue.endsWith("-all")) { 3771 toggleValue = toggleValue.substring(0, toggleValue.lastIndexOf("-all")); 3772 toggleAll = true; 3773 if (!toggleValue.equals("reset")) { 3774 try { 3775 targetSdkVersion = Integer.parseInt(getNextArgRequired()); 3776 } catch (NumberFormatException e) { 3777 pw.println("Invalid targetSdkVersion!"); 3778 return -1; 3779 } 3780 } 3781 } else { 3782 String changeIdString = getNextArgRequired(); 3783 try { 3784 changeId = Long.parseLong(changeIdString); 3785 } catch (NumberFormatException e) { 3786 changeId = platformCompat.lookupChangeId(changeIdString); 3787 } 3788 if (changeId == -1) { 3789 pw.println("Unknown or invalid change: '" + changeIdString + "'."); 3790 return -1; 3791 } 3792 } 3793 String packageName = getNextArgRequired(); 3794 if (!toggleAll && !platformCompat.isKnownChangeId(changeId)) { 3795 pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it" 3796 + " could have no effect."); 3797 } 3798 ArraySet<Long> enabled = new ArraySet<>(); 3799 ArraySet<Long> disabled = new ArraySet<>(); 3800 try { 3801 switch (toggleValue) { 3802 case "enable": 3803 if (toggleAll) { 3804 int numChanges = platformCompat.enableTargetSdkChanges(packageName, 3805 targetSdkVersion); 3806 if (numChanges == 0) { 3807 pw.println("No changes were enabled."); 3808 return -1; 3809 } 3810 pw.println("Enabled " + numChanges + " changes gated by targetSdkVersion " 3811 + targetSdkVersion + " for " + packageName + "."); 3812 } else { 3813 enabled.add(changeId); 3814 CompatibilityChangeConfig overrides = 3815 new CompatibilityChangeConfig( 3816 new Compatibility.ChangeConfig(enabled, disabled)); 3817 if (killPackage) { 3818 platformCompat.setOverrides(overrides, packageName); 3819 } else { 3820 platformCompat.setOverridesForTest(overrides, packageName); 3821 } 3822 pw.println("Enabled change " + changeId + " for " + packageName + "."); 3823 } 3824 return 0; 3825 case "disable": 3826 if (toggleAll) { 3827 int numChanges = platformCompat.disableTargetSdkChanges(packageName, 3828 targetSdkVersion); 3829 if (numChanges == 0) { 3830 pw.println("No changes were disabled."); 3831 return -1; 3832 } 3833 pw.println("Disabled " + numChanges + " changes gated by targetSdkVersion " 3834 + targetSdkVersion + " for " + packageName + "."); 3835 } else { 3836 disabled.add(changeId); 3837 CompatibilityChangeConfig overrides = 3838 new CompatibilityChangeConfig( 3839 new Compatibility.ChangeConfig(enabled, disabled)); 3840 if (killPackage) { 3841 platformCompat.setOverrides(overrides, packageName); 3842 } else { 3843 platformCompat.setOverridesForTest(overrides, packageName); 3844 } 3845 pw.println("Disabled change " + changeId + " for " + packageName + "."); 3846 } 3847 return 0; 3848 case "reset": 3849 if (toggleAll) { 3850 if (killPackage) { 3851 platformCompat.clearOverrides(packageName); 3852 } else { 3853 platformCompat.clearOverridesForTest(packageName); 3854 } 3855 pw.println("Reset all changes for " + packageName + " to default value."); 3856 return 0; 3857 } 3858 boolean existed; 3859 if (killPackage) { 3860 existed = platformCompat.clearOverride(changeId, packageName); 3861 } else { 3862 existed = platformCompat.clearOverrideForTest(changeId, packageName); 3863 } 3864 if (existed) { 3865 pw.println("Reset change " + changeId + " for " + packageName 3866 + " to default value."); 3867 } else { 3868 pw.println("No override exists for changeId " + changeId + "."); 3869 } 3870 return 0; 3871 default: 3872 pw.println("Invalid toggle value: '" + toggleValue + "'."); 3873 } 3874 } catch (SecurityException e) { 3875 pw.println(e.getMessage()); 3876 } 3877 return -1; 3878 } 3879 3880 private int runGetCurrentForegroundProcess(PrintWriter pw, IActivityManager iam) 3881 throws RemoteException { 3882 3883 ProcessObserver observer = new ProcessObserver(pw, iam); 3884 iam.registerProcessObserver(observer); 3885 3886 final InputStream mInput = getRawInputStream(); 3887 InputStreamReader converter = new InputStreamReader(mInput); 3888 BufferedReader in = new BufferedReader(converter); 3889 String line; 3890 try { 3891 while ((line = in.readLine()) != null) { 3892 boolean addNewline = true; 3893 if (line.length() <= 0) { 3894 addNewline = false; 3895 } else if ("q".equals(line) || "quit".equals(line)) { 3896 break; 3897 } else { 3898 pw.println("Invalid command: " + line); 3899 } 3900 if (addNewline) { 3901 pw.println(""); 3902 } 3903 pw.flush(); 3904 } 3905 } catch (IOException e) { 3906 e.printStackTrace(); 3907 pw.flush(); 3908 } finally { 3909 iam.unregisterProcessObserver(observer); 3910 } 3911 return 0; 3912 } 3913 3914 static final class ProcessObserver extends IProcessObserver.Stub { 3915 3916 private PrintWriter mPw; 3917 private IActivityManager mIam; 3918 3919 ProcessObserver(PrintWriter mPw, IActivityManager mIam) { 3920 this.mPw = mPw; 3921 this.mIam = mIam; 3922 } 3923 3924 @Override 3925 public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 3926 if (foregroundActivities) { 3927 try { 3928 int prcState = mIam.getUidProcessState(uid, "android"); 3929 3930 if (prcState == ProcessStateEnum.TOP) { 3931 mPw.println("New foreground process: " + pid); 3932 } else { 3933 mPw.println("No top app found"); 3934 } 3935 mPw.flush(); 3936 } catch (RemoteException e) { 3937 mPw.println("Error occurred in binder call"); 3938 mPw.flush(); 3939 } 3940 } 3941 } 3942 3943 @Override 3944 public void onProcessStarted(int pid, int processUid, int packageUid, String packageName, 3945 String processName) { 3946 } 3947 3948 @Override 3949 public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) { 3950 } 3951 3952 @Override 3953 public void onProcessDied(int pid, int uid) { 3954 } 3955 } 3956 3957 private int runSetMemoryFactor(PrintWriter pw) throws RemoteException { 3958 final String levelArg = getNextArgRequired(); 3959 @MemFactor int level = ADJ_MEM_FACTOR_NOTHING; 3960 switch (levelArg) { 3961 case "NORMAL": 3962 level = ADJ_MEM_FACTOR_NORMAL; 3963 break; 3964 case "MODERATE": 3965 level = ADJ_MEM_FACTOR_MODERATE; 3966 break; 3967 case "LOW": 3968 level = ADJ_MEM_FACTOR_LOW; 3969 break; 3970 case "CRITICAL": 3971 level = ADJ_MEM_FACTOR_CRITICAL; 3972 break; 3973 default: 3974 try { 3975 level = Integer.parseInt(levelArg); 3976 } catch (NumberFormatException e) { 3977 } 3978 if (level < ADJ_MEM_FACTOR_NORMAL || level > ADJ_MEM_FACTOR_CRITICAL) { 3979 getErrPrintWriter().println("Error: Unknown level option: " + levelArg); 3980 return -1; 3981 } 3982 } 3983 mInternal.setMemFactorOverride(level); 3984 return 0; 3985 } 3986 3987 private int runShowMemoryFactor(PrintWriter pw) throws RemoteException { 3988 final @MemFactor int level = mInternal.getMemoryTrimLevel(); 3989 switch (level) { 3990 case ADJ_MEM_FACTOR_NOTHING: 3991 pw.println("<UNKNOWN>"); 3992 break; 3993 case ADJ_MEM_FACTOR_NORMAL: 3994 pw.println("NORMAL"); 3995 break; 3996 case ADJ_MEM_FACTOR_MODERATE: 3997 pw.println("MODERATE"); 3998 break; 3999 case ADJ_MEM_FACTOR_LOW: 4000 pw.println("LOW"); 4001 break; 4002 case ADJ_MEM_FACTOR_CRITICAL: 4003 pw.println("CRITICAL"); 4004 break; 4005 } 4006 pw.flush(); 4007 return 0; 4008 } 4009 4010 private int runResetMemoryFactor(PrintWriter pw) throws RemoteException { 4011 mInternal.setMemFactorOverride(ADJ_MEM_FACTOR_NOTHING); 4012 return 0; 4013 } 4014 4015 private int runMemoryFactor(PrintWriter pw) throws RemoteException { 4016 mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 4017 "runMemoryFactor()"); 4018 4019 final String op = getNextArgRequired(); 4020 switch (op) { 4021 case "set": 4022 return runSetMemoryFactor(pw); 4023 case "show": 4024 return runShowMemoryFactor(pw); 4025 case "reset": 4026 return runResetMemoryFactor(pw); 4027 default: 4028 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 4029 return -1; 4030 } 4031 } 4032 4033 private int runServiceRestartBackoff(PrintWriter pw) throws RemoteException { 4034 mInternal.enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 4035 "runServiceRestartBackoff()"); 4036 4037 final String opt = getNextArgRequired(); 4038 switch (opt) { 4039 case "enable": 4040 mInternal.setServiceRestartBackoffEnabled(getNextArgRequired(), true, "shell"); 4041 return 0; 4042 case "disable": 4043 mInternal.setServiceRestartBackoffEnabled(getNextArgRequired(), false, "shell"); 4044 return 0; 4045 case "show": 4046 pw.println(mInternal.isServiceRestartBackoffEnabled(getNextArgRequired()) 4047 ? "enabled" : "disabled"); 4048 return 0; 4049 default: 4050 getErrPrintWriter().println("Error: unknown command '" + opt + "'"); 4051 return -1; 4052 } 4053 } 4054 4055 private int runGetIsolatedProcesses(PrintWriter pw) throws RemoteException { 4056 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP, 4057 "getIsolatedProcesses()"); 4058 final List<Integer> result = mInternal.mInternal.getIsolatedProcesses( 4059 Integer.parseInt(getNextArgRequired())); 4060 pw.print("["); 4061 if (result != null) { 4062 for (int i = 0, size = result.size(); i < size; i++) { 4063 if (i > 0) { 4064 pw.print(", "); 4065 } 4066 pw.print(result.get(i)); 4067 } 4068 } 4069 pw.println("]"); 4070 return 0; 4071 } 4072 4073 private int runSetStopUserOnSwitch(PrintWriter pw) throws RemoteException { 4074 mInternal.enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 4075 "setStopUserOnSwitch()"); 4076 String arg = getNextArg(); 4077 if (arg == null) { 4078 Slogf.i(TAG, "setStopUserOnSwitch(): resetting to default value"); 4079 mInternal.setStopUserOnSwitch(ActivityManager.STOP_USER_ON_SWITCH_DEFAULT); 4080 pw.println("Reset to default value"); 4081 return 0; 4082 } 4083 4084 boolean stop = Boolean.parseBoolean(arg); 4085 int value = stop 4086 ? ActivityManager.STOP_USER_ON_SWITCH_TRUE 4087 : ActivityManager.STOP_USER_ON_SWITCH_FALSE; 4088 4089 Slogf.i(TAG, "runSetStopUserOnSwitch(): setting to %d (%b)", value, stop); 4090 mInternal.setStopUserOnSwitch(value); 4091 pw.println("Set to " + stop); 4092 4093 return 0; 4094 } 4095 4096 // TODO(b/203105544) STOPSHIP - For debugging only, to be removed before shipping. 4097 private int runSetBgAbusiveUids(PrintWriter pw) throws RemoteException { 4098 final String arg = getNextArg(); 4099 final AppBatteryTracker batteryTracker = 4100 mInternal.mAppRestrictionController.getAppStateTracker(AppBatteryTracker.class); 4101 if (batteryTracker == null) { 4102 getErrPrintWriter().println("Unable to get bg battery tracker"); 4103 return -1; 4104 } 4105 if (arg == null) { 4106 batteryTracker.clearDebugUidPercentage(); 4107 return 0; 4108 } 4109 String[] pairs = arg.split(","); 4110 int[] uids = new int[pairs.length]; 4111 double[][] values = new double[pairs.length][]; 4112 try { 4113 for (int i = 0; i < pairs.length; i++) { 4114 String[] pair = pairs[i].split("="); 4115 if (pair.length != 2) { 4116 getErrPrintWriter().println("Malformed input"); 4117 return -1; 4118 } 4119 uids[i] = Integer.parseInt(pair[0]); 4120 final String[] vals = pair[1].split(":"); 4121 if (vals.length != BATTERY_USAGE_COUNT) { 4122 getErrPrintWriter().println("Malformed input"); 4123 return -1; 4124 } 4125 values[i] = new double[vals.length]; 4126 for (int j = 0; j < vals.length; j++) { 4127 values[i][j] = Double.parseDouble(vals[j]); 4128 } 4129 } 4130 } catch (NumberFormatException e) { 4131 getErrPrintWriter().println("Malformed input"); 4132 return -1; 4133 } 4134 batteryTracker.setDebugUidPercentage(uids, values); 4135 return 0; 4136 } 4137 4138 private int runListBgExemptionsConfig(PrintWriter pw) throws RemoteException { 4139 final ArraySet<String> sysConfigs = mInternal.mAppRestrictionController 4140 .mBgRestrictionExemptioFromSysConfig; 4141 if (sysConfigs != null) { 4142 for (int i = 0, size = sysConfigs.size(); i < size; i++) { 4143 pw.print(sysConfigs.valueAt(i)); 4144 pw.print(' '); 4145 } 4146 pw.println(); 4147 } 4148 return 0; 4149 } 4150 4151 private @ActivityManager.RestrictionLevel int restrictionNameToLevel(String name) { 4152 String lower = name.toLowerCase(); 4153 switch (lower) { 4154 case "unrestricted": 4155 return ActivityManager.RESTRICTION_LEVEL_UNRESTRICTED; 4156 case "exempted": 4157 return ActivityManager.RESTRICTION_LEVEL_EXEMPTED; 4158 case "adaptive_bucket": 4159 return ActivityManager.RESTRICTION_LEVEL_ADAPTIVE_BUCKET; 4160 case "restricted_bucket": 4161 return ActivityManager.RESTRICTION_LEVEL_RESTRICTED_BUCKET; 4162 case "background_restricted": 4163 return ActivityManager.RESTRICTION_LEVEL_BACKGROUND_RESTRICTED; 4164 case "force_stopped": 4165 return ActivityManager.RESTRICTION_LEVEL_FORCE_STOPPED; 4166 case "user_launch_only": 4167 return ActivityManager.RESTRICTION_LEVEL_USER_LAUNCH_ONLY; 4168 case "custom": 4169 return ActivityManager.RESTRICTION_LEVEL_CUSTOM; 4170 default: 4171 return ActivityManager.RESTRICTION_LEVEL_UNKNOWN; 4172 } 4173 } 4174 4175 int runSetBgRestrictionLevel(PrintWriter pw) throws RemoteException { 4176 int userId = UserHandle.USER_CURRENT; 4177 4178 String opt; 4179 while ((opt = getNextOption()) != null) { 4180 if (opt.equals("--user")) { 4181 userId = UserHandle.parseUserArg(getNextArgRequired()); 4182 } else { 4183 getErrPrintWriter().println("Error: Unknown option: " + opt); 4184 return -1; 4185 } 4186 } 4187 String packageName = getNextArgRequired(); 4188 final String value = getNextArgRequired(); 4189 final int level = restrictionNameToLevel(value); 4190 if (level == ActivityManager.RESTRICTION_LEVEL_UNKNOWN) { 4191 pw.println("Error: invalid restriction level"); 4192 return -1; 4193 } 4194 4195 int uid = INVALID_UID; 4196 try { 4197 final PackageManager pm = mInternal.mContext.getPackageManager(); 4198 uid = pm.getPackageUidAsUser(packageName, 4199 PackageManager.PackageInfoFlags.of(MATCH_ANY_USER), userId); 4200 } catch (PackageManager.NameNotFoundException e) { 4201 pw.println("Error: userId:" + userId + " package:" + packageName + " is not found"); 4202 return -1; 4203 } 4204 mInternal.setBackgroundRestrictionLevel(packageName, uid, userId, level, 4205 REASON_MAIN_FORCED_BY_USER, REASON_SUB_FORCED_SYSTEM_FLAG_UNDEFINED); 4206 return 0; 4207 } 4208 4209 int runGetBgRestrictionLevel(PrintWriter pw) throws RemoteException { 4210 int userId = UserHandle.USER_CURRENT; 4211 4212 String opt; 4213 while ((opt = getNextOption()) != null) { 4214 if (opt.equals("--user")) { 4215 userId = UserHandle.parseUserArg(getNextArgRequired()); 4216 } else { 4217 getErrPrintWriter().println("Error: Unknown option: " + opt); 4218 return -1; 4219 } 4220 } 4221 final String packageName = getNextArgRequired(); 4222 final @ActivityManager.RestrictionLevel int level = 4223 mInternal.getBackgroundRestrictionLevel(packageName, userId); 4224 pw.println(ActivityManager.restrictionLevelToName(level)); 4225 return 0; 4226 } 4227 4228 int runSetForegroundServiceDelegate(PrintWriter pw) throws RemoteException { 4229 int userId = UserHandle.USER_CURRENT; 4230 4231 String opt; 4232 while ((opt = getNextOption()) != null) { 4233 if (opt.equals("--user")) { 4234 userId = UserHandle.parseUserArg(getNextArgRequired()); 4235 } else { 4236 getErrPrintWriter().println("Error: Unknown option: " + opt); 4237 return -1; 4238 } 4239 } 4240 final String packageName = getNextArgRequired(); 4241 final String action = getNextArgRequired(); 4242 boolean isStart = true; 4243 if ("start".equals(action)) { 4244 isStart = true; 4245 } else if ("stop".equals(action)) { 4246 isStart = false; 4247 } else { 4248 pw.println("Error: action is either start or stop"); 4249 return -1; 4250 } 4251 4252 int uid = INVALID_UID; 4253 try { 4254 final PackageManager pm = mInternal.mContext.getPackageManager(); 4255 uid = pm.getPackageUidAsUser(packageName, 4256 PackageManager.PackageInfoFlags.of(MATCH_ANY_USER), userId); 4257 } catch (PackageManager.NameNotFoundException e) { 4258 pw.println("Error: userId:" + userId + " package:" + packageName + " is not found"); 4259 return -1; 4260 } 4261 mInternal.setForegroundServiceDelegate(packageName, uid, isStart, 4262 ForegroundServiceDelegationOptions.DELEGATION_SERVICE_SPECIAL_USE, 4263 "FgsDelegate"); 4264 return 0; 4265 } 4266 4267 int runResetDropboxRateLimiter() throws RemoteException { 4268 mInternal.resetDropboxRateLimiter(); 4269 return 0; 4270 } 4271 4272 int runListDisplaysForStartingUsers(PrintWriter pw) throws RemoteException { 4273 int[] displayIds = mInterface.getDisplayIdsForStartingVisibleBackgroundUsers(); 4274 // NOTE: format below cannot be changed as it's used by ITestDevice 4275 pw.println(displayIds == null || displayIds.length == 0 4276 ? "none" 4277 : Arrays.toString(displayIds)); 4278 return 0; 4279 } 4280 4281 int runClearBadProcess(PrintWriter pw) throws RemoteException { 4282 int userId = UserHandle.USER_CURRENT; 4283 String opt; 4284 while ((opt = getNextOption()) != null) { 4285 if ("--user".equals(opt)) { 4286 userId = UserHandle.parseUserArg(getNextArgRequired()); 4287 } else { 4288 getErrPrintWriter().println("Error: unknown option " + opt); 4289 return -1; 4290 } 4291 } 4292 final String processName = getNextArgRequired(); 4293 if (userId == UserHandle.USER_CURRENT) { 4294 userId = mInternal.getCurrentUserId(); 4295 } 4296 4297 pw.println("Clearing '" + processName + "' in u" + userId + " from bad processes list"); 4298 mInternal.mAppErrors.clearBadProcessForUser(processName, userId); 4299 return 0; 4300 } 4301 4302 private Resources getResources(PrintWriter pw) throws RemoteException { 4303 // system resources does not contain all the device configuration, construct it manually. 4304 Configuration config = mInterface.getConfiguration(); 4305 if (config == null) { 4306 pw.println("Error: Activity manager has no configuration"); 4307 return null; 4308 } 4309 4310 final DisplayMetrics metrics = new DisplayMetrics(); 4311 metrics.setToDefaults(); 4312 4313 return new Resources(AssetManager.getSystem(), metrics, config); 4314 } 4315 4316 @Override 4317 public void onHelp() { 4318 PrintWriter pw = getOutPrintWriter(); 4319 dumpHelp(pw, mDumping); 4320 } 4321 4322 @NeverCompile // Avoid size overhead of debugging code. 4323 static void dumpHelp(PrintWriter pw, boolean dumping) { 4324 if (dumping) { 4325 pw.println("Activity manager dump options:"); 4326 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ..."); 4327 pw.println(" WHAT may be one of:"); 4328 pw.println(" a[ctivities]: activity stack state"); 4329 pw.println(" r[recents]: recent activities state"); 4330 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 4331 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics"); 4332 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 4333 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 4334 pw.println(" o[om]: out of memory management"); 4335 pw.println(" perm[issions]: URI permission grant state"); 4336 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 4337 pw.println(" provider [COMP_SPEC]: provider client-side state"); 4338 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 4339 pw.println(" allowed-associations: current package association restrictions"); 4340 pw.println(" as[sociations]: tracked app associations"); 4341 pw.println(" start-info [PACKAGE_NAME]: historical process start information"); 4342 pw.println(" exit-info [PACKAGE_NAME]: historical process exit information"); 4343 pw.println(" lmk: stats on low memory killer"); 4344 pw.println(" lru: raw LRU process list"); 4345 pw.println(" binder-proxies: stats on binder objects and IPCs"); 4346 pw.println(" settings: currently applied config settings"); 4347 pw.println(" cao: cached app optimizer state"); 4348 pw.println(" timers: the current ANR timer state"); 4349 pw.println(" service [COMP_SPEC]: service client-side state"); 4350 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 4351 pw.println(" all: dump all activities"); 4352 pw.println(" top: dump the top activity"); 4353 pw.println(" users: user state"); 4354 pw.println(" WHAT may also be a COMP_SPEC to dump activities."); 4355 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 4356 pw.println(" a partial substring in a component name, a"); 4357 pw.println(" hex object identifier."); 4358 pw.println(" -a: include all available server state."); 4359 pw.println(" -c: include client state."); 4360 pw.println(" -p: limit output to given package."); 4361 pw.println(" -d: limit output to given display."); 4362 pw.println(" --checkin: output checkin format, resetting data."); 4363 pw.println(" --C: output checkin format, not resetting data."); 4364 pw.println(" --proto: output dump in protocol buffer format."); 4365 pw.printf(" %s: dump just the DUMPABLE-related state of an activity. Use the %s " 4366 + "option to list the supported DUMPABLEs\n", Activity.DUMP_ARG_DUMP_DUMPABLE, 4367 Activity.DUMP_ARG_LIST_DUMPABLES); 4368 pw.printf(" %s: show the available dumpables in an activity\n", 4369 Activity.DUMP_ARG_LIST_DUMPABLES); 4370 } else { 4371 pw.println("Activity manager (activity) commands:"); 4372 pw.println(" help"); 4373 pw.println(" Print this help text."); 4374 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]"); 4375 pw.println(" [--sampling INTERVAL] [--clock-type <TYPE>] [--streaming]"); 4376 pw.println(" [" + PROFILER_OUTPUT_VERSION_FLAG + " NUMBER]"); 4377 pw.println(" [-R COUNT] [-S] [--track-allocation]"); 4378 pw.println(" [--user <USER_ID> | current] [--suspend] <INTENT>"); 4379 pw.println(" Start an Activity. Options are:"); 4380 pw.println(" -D: enable debugging"); 4381 pw.println(" --suspend: debugged app suspend threads at startup (only with -D)"); 4382 pw.println(" -N: enable native debugging"); 4383 pw.println(" -W: wait for launch to complete (initial display)"); 4384 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>"); 4385 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds"); 4386 pw.println(" between samples (use with --start-profiler)"); 4387 pw.println(" --clock-type <TYPE>: type can be wall / thread-cpu / dual. Specify"); 4388 pw.println(" the clock that is used to report the timestamps when profiling"); 4389 pw.println(" The default value is dual. (use with --start-profiler)"); 4390 pw.println(" --streaming: stream the profiling output to the specified file"); 4391 pw.println(" (use with --start-profiler)"); 4392 pw.println(" " + PROFILER_OUTPUT_VERSION_FLAG + " Specify the version of the"); 4393 pw.println(" profiling output (use with --start-profiler)"); 4394 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle"); 4395 pw.println(" --attach-agent <agent>: attach the given agent before binding"); 4396 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding"); 4397 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,"); 4398 pw.println(" the top activity will be finished."); 4399 pw.println(" -S: force stop the target app before starting the activity"); 4400 pw.println(" --track-allocation: enable tracking of object allocations"); 4401 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 4402 pw.println(" specified then run as the current user."); 4403 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into."); 4404 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as."); 4405 pw.println(" --display <DISPLAY_ID>: The display to launch the activity into."); 4406 pw.println(" --splashscreen-icon: Show the splash screen icon on launch."); 4407 pw.println(" start-in-vsync"); 4408 pw.println(" Start an Activity with vsync aligned. See `start-activity` for the"); 4409 pw.println(" possible options."); 4410 pw.println(" start-service [--user <USER_ID> | current] <INTENT>"); 4411 pw.println(" Start a Service. Options are:"); 4412 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 4413 pw.println(" specified then run as the current user."); 4414 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>"); 4415 pw.println(" Start a foreground Service. Options are:"); 4416 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 4417 pw.println(" specified then run as the current user."); 4418 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>"); 4419 pw.println(" Stop a Service. Options are:"); 4420 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 4421 pw.println(" specified then run as the current user."); 4422 pw.println(" broadcast [--user <USER_ID> | all | current]"); 4423 pw.println(" [--receiver-permission <PERMISSION>]"); 4424 pw.println(" [--allow-background-activity-starts]"); 4425 pw.println(" [--async] <INTENT>"); 4426 pw.println(" Send a broadcast Intent. Options are:"); 4427 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not"); 4428 pw.println(" specified then send to all users."); 4429 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission."); 4430 pw.println(" --allow-background-activity-starts: The receiver may start activities"); 4431 pw.println(" even if in the background."); 4432 pw.println(" --async: Send without waiting for the completion of the receiver."); 4433 pw.println(" compact {some|full} <PROCESS>"); 4434 pw.println(" Perform a single process compaction. The given <PROCESS> argument"); 4435 pw.println(" may be either a process name or pid."); 4436 pw.println(" some: execute file compaction."); 4437 pw.println(" full: execute anon + file compaction."); 4438 pw.println(" compact system"); 4439 pw.println(" Perform a full system compaction."); 4440 pw.println(" compact native {some|full} <pid>"); 4441 pw.println(" Perform a native compaction for process with <pid>."); 4442 pw.println(" some: execute file compaction."); 4443 pw.println(" full: execute anon + file compaction."); 4444 pw.println(" freeze [--sticky] <PROCESS>"); 4445 pw.println(" Freeze a process. The given <PROCESS> argument"); 4446 pw.println(" may be either a process name or pid. Options are:"); 4447 pw.println(" --sticky: persists the frozen state for the process lifetime or"); 4448 pw.println(" until an unfreeze is triggered via shell"); 4449 pw.println(" unfreeze [--sticky] <PROCESS>"); 4450 pw.println(" Unfreeze a process. The given <PROCESS> argument"); 4451 pw.println(" may be either a process name or pid. Options are:"); 4452 pw.println(" --sticky: persists the unfrozen state for the process lifetime or"); 4453 pw.println(" until a freeze is triggered via shell"); 4454 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]"); 4455 pw.println(" [--user <USER_ID> | current]"); 4456 pw.println(" [--no-hidden-api-checks [--no-test-api-access]]"); 4457 pw.println(" [--no-isolated-storage]"); 4458 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>"); 4459 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the"); 4460 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there"); 4461 pw.println(" is only one instrumentation. Options are:"); 4462 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with"); 4463 pw.println(" [-e perf true] to generate raw output for performance measurements."); 4464 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a"); 4465 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]]."); 4466 pw.println(" -p <FILE>: write profiling data to <FILE>"); 4467 pw.println(" -m: Write output as protobuf to stdout (machine readable)"); 4468 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine"); 4469 pw.println(" readable). If path is not specified, default directory and file name will"); 4470 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto"); 4471 pw.println(" -w: wait for instrumentation to finish before returning. Required for"); 4472 pw.println(" test runners."); 4473 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;"); 4474 pw.println(" current user if not specified."); 4475 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API."); 4476 pw.println(" --no-test-api-access: do not allow access to test APIs, if hidden"); 4477 pw.println(" API checks are enabled."); 4478 pw.println(" --no-isolated-storage: don't use isolated storage sandbox and "); 4479 pw.println(" mount full external storage"); 4480 pw.println(" --no-window-animation: turn off window animations while running."); 4481 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI."); 4482 pw.println(" This assumes that the process supports the selected ABI."); 4483 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]"); 4484 pw.println(" Trace IPC transactions."); 4485 pw.println(" start: start tracing IPC transactions."); 4486 pw.println(" stop: stop tracing IPC transactions and dump the results to file."); 4487 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to."); 4488 anrTimerHelp(pw); 4489 pw.println(" profile start [--user <USER_ID> current]"); 4490 pw.println(" [--clock-type <TYPE>]"); 4491 pw.println(" [" + PROFILER_OUTPUT_VERSION_FLAG + " VERSION]"); 4492 pw.println(" [--sampling INTERVAL | --streaming] <PROCESS> <FILE>"); 4493 pw.println(" Start profiler on a process. The given <PROCESS> argument"); 4494 pw.println(" may be either a process name or pid. Options are:"); 4495 pw.println(" --user <USER_ID> | current: When supplying a process name,"); 4496 pw.println(" specify user of process to profile; uses current user if not"); 4497 pw.println(" specified."); 4498 pw.println(" --clock-type <TYPE>: use the specified clock to report timestamps."); 4499 pw.println(" The type can be one of wall | thread-cpu | dual. The default"); 4500 pw.println(" value is dual."); 4501 pw.println(" " + PROFILER_OUTPUT_VERSION_FLAG + "VERSION: specifies the output"); 4502 pw.println(" format version"); 4503 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds"); 4504 pw.println(" between samples."); 4505 pw.println(" --streaming: stream the profiling output to the specified file."); 4506 pw.println(" profile stop [--user <USER_ID> current] <PROCESS>"); 4507 pw.println(" Stop profiler on a process. The given <PROCESS> argument"); 4508 pw.println(" may be either a process name or pid. Options are:"); 4509 pw.println(" --user <USER_ID> | current: When supplying a process name,"); 4510 pw.println(" specify user of process to profile; uses current user if not"); 4511 pw.println(" specified."); 4512 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] [-b <format>] "); 4513 pw.println(" <PROCESS> <FILE>"); 4514 pw.println(" Dump the heap of a process. The given <PROCESS> argument may"); 4515 pw.println(" be either a process name or pid. Options are:"); 4516 pw.println(" -n: dump native heap instead of managed heap"); 4517 pw.println(" -g: force GC before dumping the heap"); 4518 pw.println(" -b <format>: dump contents of bitmaps in the format specified,"); 4519 pw.println(" which can be \"png\", \"jpg\" or \"webp\"."); 4520 pw.println(" --user <USER_ID> | current: When supplying a process name,"); 4521 pw.println(" specify user of process to dump; uses current user if not specified."); 4522 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>"); 4523 pw.println(" Set application <PACKAGE> to debug. Options are:"); 4524 pw.println(" -w: wait for debugger when application starts"); 4525 pw.println(" --persistent: retain this value"); 4526 pw.println(" clear-debug-app"); 4527 pw.println(" Clear the previously set-debug-app."); 4528 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>"); 4529 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or"); 4530 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report."); 4531 pw.println(" clear-watch-heap"); 4532 pw.println(" Clear the previously set-watch-heap."); 4533 pw.println(" clear-start-info [--user <USER_ID> | all | current] <PACKAGE>"); 4534 pw.println(" Clear process start-info for the given package."); 4535 pw.println(" Clear start-info for all packages if no package is provided."); 4536 pw.println(" start-info-detailed-monitoring [--user <USER_ID> | all | current] <PACKAGE>"); 4537 pw.println(" Enable application start info detailed monitoring for the given package."); 4538 pw.println(" Disable if no package is supplied."); 4539 pw.println(" clear-exit-info [--user <USER_ID> | all | current] <PACKAGE>"); 4540 pw.println(" Clear process exit-info for the given package."); 4541 pw.println(" Clear exit-info for all packages if no package is provided."); 4542 pw.println(" bug-report [--progress | --telephony]"); 4543 pw.println(" Request bug report generation; will launch a notification"); 4544 pw.println(" when done to select where it should be delivered. Options are:"); 4545 pw.println(" --progress: will launch a notification right away to show its progress."); 4546 pw.println(" --telephony: will dump only telephony sections."); 4547 pw.println(" fgs-notification-rate-limit {enable | disable}"); 4548 pw.println(" Enable/disable rate limit on FGS notification deferral policy."); 4549 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>"); 4550 pw.println(" Completely stop the given application package."); 4551 pw.println(" stop-app [--user <USER_ID> | all | current] <PACKAGE>"); 4552 pw.println(" Stop an app and all of its services. Unlike `force-stop` this does"); 4553 pw.println(" not cancel the app's scheduled alarms and jobs."); 4554 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>"); 4555 pw.println(" Induce a VM crash in the specified package or process"); 4556 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>"); 4557 pw.println(" Kill all background processes associated with the given application."); 4558 pw.println(" kill-all"); 4559 pw.println(" Kill all processes that are safe to kill (cached, etc)."); 4560 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>"); 4561 pw.println(" If the given application's uid is in the background and waiting to"); 4562 pw.println(" become idle (not allowing background services), do that now."); 4563 pw.println( 4564 " set-deterministic-uid-idle [--user <USER_ID> | all | current] <true|false>"); 4565 pw.println(" If true, sets the timing of making UIDs idle consistent and"); 4566 pw.println(" deterministic. If false, the timing will be variable depending on"); 4567 pw.println(" other activity on the device. The default is false."); 4568 pw.println(" monitor [--gdb <port>] [-p <TARGET>] [-s] [-c] [-k]"); 4569 pw.println(" Start monitoring for crashes or ANRs."); 4570 pw.println(" --gdb: start gdbserv on the given port at crash/ANR"); 4571 pw.println(" -p: only show events related to a specific process / package"); 4572 pw.println(" -s: simple mode, only show a summary line for each event"); 4573 pw.println(" -c: assume the input is always [c]ontinue"); 4574 pw.println(" -k: assume the input is always [k]ill"); 4575 pw.println(" -c and -k are mutually exclusive."); 4576 pw.println(" watch-uids [--oom <uid>] [--mask <capabilities integer>]"); 4577 pw.println(" Start watching for and reporting uid state changes."); 4578 pw.println(" --oom: specify a uid for which to report detailed change messages."); 4579 pw.println(" --mask: Specify PROCESS_CAPABILITY_XXX mask to report. "); 4580 pw.println(" By default, it only reports FOREGROUND_LOCATION (1)"); 4581 pw.println(" FOREGROUND_CAMERA (2), FOREGROUND_MICROPHONE (4)"); 4582 pw.println(" and NETWORK (8). New capabilities added on or after"); 4583 pw.println(" Android UDC will not be reported by default."); 4584 pw.println(" hang [--allow-restart]"); 4585 pw.println(" Hang the system."); 4586 pw.println(" --allow-restart: allow watchdog to perform normal system restart"); 4587 pw.println(" restart"); 4588 pw.println(" Restart the user-space system."); 4589 pw.println(" idle-maintenance"); 4590 pw.println(" Perform idle maintenance now."); 4591 pw.println(" screen-compat [on|off] <PACKAGE>"); 4592 pw.println(" Control screen compatibility mode of <PACKAGE>."); 4593 pw.println(" package-importance <PACKAGE>"); 4594 pw.println(" Print current importance of <PACKAGE>."); 4595 pw.println(" to-uri [INTENT]"); 4596 pw.println(" Print the given Intent specification as a URI."); 4597 pw.println(" to-intent-uri [INTENT]"); 4598 pw.println(" Print the given Intent specification as an intent: URI."); 4599 pw.println(" to-app-uri [INTENT]"); 4600 pw.println(" Print the given Intent specification as an android-app: URI."); 4601 pw.println(" switch-user <USER_ID>"); 4602 pw.println(" Switch to put USER_ID in the foreground, starting"); 4603 pw.println(" execution of that user if it is currently stopped."); 4604 pw.println(" get-current-user"); 4605 pw.println(" Returns id of the current foreground user."); 4606 pw.println(" start-user [-w] [--display DISPLAY_ID] <USER_ID>"); 4607 pw.println(" Start USER_ID in background if it is currently stopped;"); 4608 pw.println(" use switch-user if you want to start the user in foreground."); 4609 pw.println(" -w: wait for start-user to complete and the user to be unlocked."); 4610 pw.println(" --display <DISPLAY_ID>: starts the user visible in that display, " 4611 + "which allows the user to launch activities on it."); 4612 pw.println(" (not supported on all devices; typically only on automotive builds " 4613 + "where the vehicle has passenger displays)"); 4614 pw.println(" unlock-user <USER_ID>"); 4615 pw.println(" Unlock the given user. This will only work if the user doesn't"); 4616 pw.println(" have an LSKF (PIN/pattern/password)."); 4617 pw.println(" stop-user [-w] [-f] <USER_ID>"); 4618 pw.println(" Stop execution of USER_ID, not allowing it to run any"); 4619 pw.println(" code until a later explicit start or switch to it."); 4620 pw.println(" -w: wait for stop-user to complete."); 4621 pw.println(" -f: force stop, even if user has an unstoppable parent."); 4622 pw.println(" is-user-stopped <USER_ID>"); 4623 pw.println(" Returns whether <USER_ID> has been stopped or not."); 4624 pw.println(" get-started-user-state <USER_ID>"); 4625 pw.println(" Gets the current state of the given started user."); 4626 pw.println(" track-associations"); 4627 pw.println(" Enable association tracking."); 4628 pw.println(" untrack-associations"); 4629 pw.println(" Disable and clear association tracking."); 4630 pw.println(" get-uid-state <UID>"); 4631 pw.println(" Gets the process state of an app given its <UID>."); 4632 pw.println(" attach-agent <PROCESS> <FILE>"); 4633 pw.println(" Attach an agent to the specified <PROCESS>, which may be either a process name or a PID."); 4634 pw.println(" get-config [--days N] [--device] [--proto] [--display <DISPLAY_ID>]"); 4635 pw.println(" Retrieve the configuration and any recent configurations of the device."); 4636 pw.println(" --days: also return last N days of configurations that have been seen."); 4637 pw.println(" --device: also output global device configuration info."); 4638 pw.println(" --proto: return result as a proto; does not include --days info."); 4639 pw.println(" --display: Specify for which display to run the command; if not "); 4640 pw.println(" specified then run for the default display."); 4641 pw.println(" supports-multiwindow"); 4642 pw.println(" Returns true if the device supports multiwindow."); 4643 pw.println(" supports-split-screen-multi-window"); 4644 pw.println(" Returns true if the device supports split screen multiwindow."); 4645 pw.println(" suppress-resize-config-changes <true|false>"); 4646 pw.println(" Suppresses configuration changes due to user resizing an activity/task."); 4647 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false"); 4648 pw.println(" Sets the inactive state of an app."); 4649 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>"); 4650 pw.println(" Returns the inactive state of an app."); 4651 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare|restricted"); 4652 pw.println(" Puts an app in the standby bucket."); 4653 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>"); 4654 pw.println(" Returns the standby bucket of an app."); 4655 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>"); 4656 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]"); 4657 pw.println(" Send a memory trim event to a <PROCESS>. May also supply a raw trim int level."); 4658 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays."); 4659 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>"); 4660 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>."); 4661 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks."); 4662 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]"); 4663 pw.println(" Move <TASK_ID> from its current stack to the top (true) or"); 4664 pw.println(" bottom (false) of <STACK_ID>."); 4665 pw.println(" list"); 4666 pw.println(" List all of the activity stacks and their sizes."); 4667 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>"); 4668 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>."); 4669 pw.println(" remove <STACK_ID>"); 4670 pw.println(" Remove stack <STACK_ID>."); 4671 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks."); 4672 pw.println(" lock <TASK_ID>"); 4673 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run."); 4674 pw.println(" lock stop"); 4675 pw.println(" End the current task lock."); 4676 pw.println(" resizeable <TASK_ID> [0|1|2|3]"); 4677 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:"); 4678 pw.println(" 0: unresizeable"); 4679 pw.println(" 1: crop_windows"); 4680 pw.println(" 2: resizeable"); 4681 pw.println(" 3: resizeable_and_pipable"); 4682 pw.println(" resize <TASK_ID> <LEFT> <TOP> <RIGHT> <BOTTOM>"); 4683 pw.println(" The task is resized only if it is in multi-window windowing"); 4684 pw.println(" mode or freeform windowing mode."); 4685 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]"); 4686 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>"); 4687 pw.println(" without restarting any processes."); 4688 pw.println(" write"); 4689 pw.println(" Write all pending state to storage."); 4690 pw.println(" compat [COMMAND] [...]: sub-commands for toggling app-compat changes."); 4691 pw.println(" enable|disable [--no-kill] <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>"); 4692 pw.println(" Toggles a change either by id or by name for <PACKAGE_NAME>."); 4693 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect) unless --no-kill is provided."); 4694 pw.println(" reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>"); 4695 pw.println(" Toggles a change either by id or by name for <PACKAGE_NAME>."); 4696 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect)."); 4697 pw.println(" enable-all|disable-all <targetSdkVersion> <PACKAGE_NAME>"); 4698 pw.println(" Toggles all changes that are gated by <targetSdkVersion>."); 4699 pw.println(" reset-all [--no-kill] <PACKAGE_NAME>"); 4700 pw.println(" Removes all existing overrides for all changes for "); 4701 pw.println(" <PACKAGE_NAME> (back to default behaviour)."); 4702 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect) unless --no-kill is provided."); 4703 pw.println(" memory-factor [command] [...]: sub-commands for overriding memory pressure factor"); 4704 pw.println(" set <NORMAL|MODERATE|LOW|CRITICAL>"); 4705 pw.println(" Overrides memory pressure factor. May also supply a raw int level"); 4706 pw.println(" show"); 4707 pw.println(" Shows the existing memory pressure factor"); 4708 pw.println(" reset"); 4709 pw.println(" Removes existing override for memory pressure factor"); 4710 pw.println(" service-restart-backoff <COMMAND> [...]: sub-commands to toggle service restart backoff policy."); 4711 pw.println(" enable|disable <PACKAGE_NAME>"); 4712 pw.println(" Toggles the restart backoff policy on/off for <PACKAGE_NAME>."); 4713 pw.println(" show <PACKAGE_NAME>"); 4714 pw.println(" Shows the restart backoff policy state for <PACKAGE_NAME>."); 4715 pw.println(" get-isolated-pids <UID>"); 4716 pw.println(" Get the PIDs of isolated processes with packages in this <UID>"); 4717 pw.println(" set-stop-user-on-switch [true|false]"); 4718 pw.println(" Sets whether the current user (and its profiles) should be stopped" 4719 + " when switching to a different user."); 4720 pw.println(" Without arguments, it resets to the value defined by platform."); 4721 pw.println(" set-bg-abusive-uids [uid=percentage][,uid=percentage...]"); 4722 pw.println(" Force setting the battery usage of the given UID."); 4723 pw.println(" set-bg-restriction-level [--user <USER_ID>] <PACKAGE> unrestricted|exempted|adaptive_bucket|restricted_bucket|background_restricted|hibernation"); 4724 pw.println(" Set an app's background restriction level which in turn map to a app standby bucket."); 4725 pw.println(" get-bg-restriction-level [--user <USER_ID>] <PACKAGE>"); 4726 pw.println(" Get an app's background restriction level."); 4727 pw.println(" list-displays-for-starting-users"); 4728 pw.println(" Lists the id of displays that can be used to start users on " 4729 + "background."); 4730 pw.println(" set-foreground-service-delegate [--user <USER_ID>] <PACKAGE> start|stop"); 4731 pw.println(" Start/stop an app's foreground service delegate."); 4732 pw.println(" set-ignore-delivery-group-policy <ACTION>"); 4733 pw.println(" Start ignoring delivery group policy set for a broadcast action"); 4734 pw.println(" clear-ignore-delivery-group-policy <ACTION>"); 4735 pw.println(" Stop ignoring delivery group policy set for a broadcast action"); 4736 pw.println(" capabilities [--protobuf]"); 4737 pw.println(" Output am supported features (text format). Options are:"); 4738 pw.println(" --protobuf: format output using protobuffer"); 4739 pw.println(" set-app-zygote-preload-timeout <TIMEOUT_IN_MS>"); 4740 pw.println(" Set the timeout for preloading code in the app-zygote"); 4741 pw.println(" set-media-foreground-service inactive|active [--user USER_ID] <PACKAGE>" 4742 + " <NOTIFICATION_ID>"); 4743 pw.println(" Set an app's media service inactive or active."); 4744 pw.println(" clear-bad-process [--user USER_ID] <PROCESS_NAME>"); 4745 pw.println(" Clears a process from the bad processes list."); 4746 Intent.printIntentArgsHelp(pw, ""); 4747 } 4748 } 4749 4750 static void anrTimerHelp(PrintWriter pw) { 4751 // Return silently if tracing is not feature-enabled. 4752 if (!AnrTimer.traceFeatureEnabled()) return; 4753 4754 String h = AnrTimer.traceTimers(new String[]{"help"}); 4755 if (h == null) { 4756 return; 4757 } 4758 4759 pw.println(" trace-timer <cmd>"); 4760 for (String s : h.split("\n")) { 4761 pw.println(" " + s); 4762 } 4763 } 4764 } 4765