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.ActivityManagerInternal.ALLOW_NON_FULL; 20 import static android.app.ActivityTaskManager.INVALID_TASK_ID; 21 import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM; 22 import static android.app.ActivityTaskManager.RESIZE_MODE_USER; 23 import static android.app.WaitResult.launchStateToString; 24 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; 25 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; 26 import static android.view.Display.INVALID_DISPLAY; 27 28 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 29 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW; 30 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE; 31 import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL; 32 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 33 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 34 import static com.android.server.am.AppBatteryTracker.BatteryUsage.BATTERY_USAGE_COUNT; 35 import static com.android.server.am.LowMemDetector.ADJ_MEM_FACTOR_NOTHING; 36 37 import android.app.Activity; 38 import android.app.ActivityManager; 39 import android.app.ActivityOptions; 40 import android.app.ActivityTaskManager; 41 import android.app.ActivityTaskManager.RootTaskInfo; 42 import android.app.AppGlobals; 43 import android.app.BroadcastOptions; 44 import android.app.IActivityController; 45 import android.app.IActivityManager; 46 import android.app.IActivityTaskManager; 47 import android.app.IStopUserCallback; 48 import android.app.IUidObserver; 49 import android.app.KeyguardManager; 50 import android.app.ProfilerInfo; 51 import android.app.RemoteServiceException.CrashedByAdbException; 52 import android.app.UserSwitchObserver; 53 import android.app.WaitResult; 54 import android.app.usage.AppStandbyInfo; 55 import android.app.usage.ConfigurationStats; 56 import android.app.usage.IUsageStatsManager; 57 import android.app.usage.UsageStatsManager; 58 import android.compat.Compatibility; 59 import android.content.ComponentCallbacks2; 60 import android.content.ComponentName; 61 import android.content.Context; 62 import android.content.DeviceConfigurationProto; 63 import android.content.GlobalConfigurationProto; 64 import android.content.IIntentReceiver; 65 import android.content.Intent; 66 import android.content.pm.ConfigurationInfo; 67 import android.content.pm.FeatureInfo; 68 import android.content.pm.IPackageManager; 69 import android.content.pm.PackageManager; 70 import android.content.pm.ParceledListSlice; 71 import android.content.pm.ResolveInfo; 72 import android.content.pm.SharedLibraryInfo; 73 import android.content.pm.UserInfo; 74 import android.content.res.AssetManager; 75 import android.content.res.Configuration; 76 import android.content.res.Resources; 77 import android.graphics.Rect; 78 import android.hardware.display.DisplayManager; 79 import android.opengl.GLES10; 80 import android.os.Binder; 81 import android.os.Build; 82 import android.os.Bundle; 83 import android.os.IProgressListener; 84 import android.os.ParcelFileDescriptor; 85 import android.os.RemoteCallback; 86 import android.os.RemoteCallback.OnResultListener; 87 import android.os.RemoteException; 88 import android.os.ServiceManager; 89 import android.os.ShellCommand; 90 import android.os.StrictMode; 91 import android.os.SystemClock; 92 import android.os.SystemProperties; 93 import android.os.Trace; 94 import android.os.UserHandle; 95 import android.os.UserManager; 96 import android.text.TextUtils; 97 import android.util.ArrayMap; 98 import android.util.ArraySet; 99 import android.util.DebugUtils; 100 import android.util.DisplayMetrics; 101 import android.util.proto.ProtoOutputStream; 102 import android.view.Display; 103 import android.window.SplashScreen; 104 105 import com.android.internal.compat.CompatibilityChangeConfig; 106 import com.android.internal.util.MemInfoReader; 107 import com.android.server.am.LowMemDetector.MemFactor; 108 import com.android.server.compat.PlatformCompat; 109 import com.android.server.utils.Slogf; 110 111 import dalvik.annotation.optimization.NeverCompile; 112 113 import java.io.BufferedReader; 114 import java.io.IOException; 115 import java.io.InputStream; 116 import java.io.InputStreamReader; 117 import java.io.PrintWriter; 118 import java.net.URISyntaxException; 119 import java.time.Clock; 120 import java.time.LocalDateTime; 121 import java.time.format.DateTimeFormatter; 122 import java.util.ArrayList; 123 import java.util.Arrays; 124 import java.util.Collections; 125 import java.util.Comparator; 126 import java.util.HashSet; 127 import java.util.List; 128 import java.util.Locale; 129 import java.util.Set; 130 import java.util.concurrent.CountDownLatch; 131 import java.util.concurrent.TimeUnit; 132 133 import javax.microedition.khronos.egl.EGL10; 134 import javax.microedition.khronos.egl.EGLConfig; 135 import javax.microedition.khronos.egl.EGLContext; 136 import javax.microedition.khronos.egl.EGLDisplay; 137 import javax.microedition.khronos.egl.EGLSurface; 138 139 final class ActivityManagerShellCommand extends ShellCommand { 140 141 static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerShellCommand" : TAG_AM; 142 143 144 public static final String NO_CLASS_ERROR_CODE = "Error type 3"; 145 146 private static final String SHELL_PACKAGE_NAME = "com.android.shell"; 147 148 private static final int USER_OPERATION_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes 149 150 private static final DateTimeFormatter LOG_NAME_TIME_FORMATTER = 151 DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss", Locale.ROOT); 152 153 // IPC interface to activity manager -- don't need to do additional security checks. 154 final IActivityManager mInterface; 155 final IActivityTaskManager mTaskInterface; 156 157 // Internal service impl -- must perform security checks before touching. 158 final ActivityManagerService mInternal; 159 160 // Convenience for interacting with package manager. 161 final IPackageManager mPm; 162 163 private int mStartFlags = 0; 164 private boolean mWaitOption = false; 165 private boolean mStopOption = false; 166 167 private int mRepeat = 0; 168 private int mUserId; 169 private String mReceiverPermission; 170 171 private String mProfileFile; 172 private int mSamplingInterval; 173 private boolean mAutoStop; 174 private boolean mStreaming; // Streaming the profiling output to a file. 175 private String mAgent; // Agent to attach on startup. 176 private boolean mAttachAgentDuringBind; // Whether agent should be attached late. 177 private int mDisplayId; 178 private int mWindowingMode; 179 private int mActivityType; 180 private int mTaskId; 181 private boolean mIsTaskOverlay; 182 private boolean mIsLockTask; 183 private boolean mAsync; 184 private BroadcastOptions mBroadcastOptions; 185 private boolean mShowSplashScreen; 186 private boolean mDismissKeyguard; 187 188 final boolean mDumping; 189 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping)190 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) { 191 mInterface = service; 192 mTaskInterface = service.mActivityTaskManager; 193 mInternal = service; 194 mPm = AppGlobals.getPackageManager(); 195 mDumping = dumping; 196 } 197 198 @Override onCommand(String cmd)199 public int onCommand(String cmd) { 200 if (cmd == null) { 201 return handleDefaultCommands(cmd); 202 } 203 final PrintWriter pw = getOutPrintWriter(); 204 try { 205 switch (cmd) { 206 case "start": 207 case "start-activity": 208 return runStartActivity(pw); 209 case "startservice": 210 case "start-service": 211 return runStartService(pw, false); 212 case "startforegroundservice": 213 case "startfgservice": 214 case "start-foreground-service": 215 case "start-fg-service": 216 return runStartService(pw, true); 217 case "stopservice": 218 case "stop-service": 219 return runStopService(pw); 220 case "broadcast": 221 return runSendBroadcast(pw); 222 case "compact": 223 return runCompact(pw); 224 case "instrument": 225 getOutPrintWriter().println("Error: must be invoked through 'am instrument'."); 226 return -1; 227 case "trace-ipc": 228 return runTraceIpc(pw); 229 case "profile": 230 return runProfile(pw); 231 case "dumpheap": 232 return runDumpHeap(pw); 233 case "set-debug-app": 234 return runSetDebugApp(pw); 235 case "set-agent-app": 236 return runSetAgentApp(pw); 237 case "clear-debug-app": 238 return runClearDebugApp(pw); 239 case "set-watch-heap": 240 return runSetWatchHeap(pw); 241 case "clear-watch-heap": 242 return runClearWatchHeap(pw); 243 case "clear-exit-info": 244 return runClearExitInfo(pw); 245 case "bug-report": 246 return runBugReport(pw); 247 case "force-stop": 248 return runForceStop(pw); 249 case "stop-app": 250 return runStopApp(pw); 251 case "clear-recent-apps": 252 return runClearRecentApps(pw); 253 case "fgs-notification-rate-limit": 254 return runFgsNotificationRateLimit(pw); 255 case "crash": 256 return runCrash(pw); 257 case "kill": 258 return runKill(pw); 259 case "kill-all": 260 return runKillAll(pw); 261 case "make-uid-idle": 262 return runMakeIdle(pw); 263 case "monitor": 264 return runMonitor(pw); 265 case "watch-uids": 266 return runWatchUids(pw); 267 case "hang": 268 return runHang(pw); 269 case "restart": 270 return runRestart(pw); 271 case "idle-maintenance": 272 return runIdleMaintenance(pw); 273 case "screen-compat": 274 return runScreenCompat(pw); 275 case "package-importance": 276 return runPackageImportance(pw); 277 case "to-uri": 278 return runToUri(pw, 0); 279 case "to-intent-uri": 280 return runToUri(pw, Intent.URI_INTENT_SCHEME); 281 case "to-app-uri": 282 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME); 283 case "switch-user": 284 return runSwitchUser(pw); 285 case "get-current-user": 286 return runGetCurrentUser(pw); 287 case "start-user": 288 return runStartUser(pw); 289 case "unlock-user": 290 return runUnlockUser(pw); 291 case "stop-user": 292 return runStopUser(pw); 293 case "is-user-stopped": 294 return runIsUserStopped(pw); 295 case "get-started-user-state": 296 return runGetStartedUserState(pw); 297 case "track-associations": 298 return runTrackAssociations(pw); 299 case "untrack-associations": 300 return runUntrackAssociations(pw); 301 case "get-uid-state": 302 return getUidState(pw); 303 case "get-config": 304 return runGetConfig(pw); 305 case "suppress-resize-config-changes": 306 return runSuppressResizeConfigChanges(pw); 307 case "set-inactive": 308 return runSetInactive(pw); 309 case "get-inactive": 310 return runGetInactive(pw); 311 case "set-standby-bucket": 312 return runSetStandbyBucket(pw); 313 case "get-standby-bucket": 314 return runGetStandbyBucket(pw); 315 case "send-trim-memory": 316 return runSendTrimMemory(pw); 317 case "display": 318 return runDisplay(pw); 319 case "stack": 320 return runStack(pw); 321 case "task": 322 return runTask(pw); 323 case "write": 324 return runWrite(pw); 325 case "attach-agent": 326 return runAttachAgent(pw); 327 case "supports-multiwindow": 328 return runSupportsMultiwindow(pw); 329 case "supports-split-screen-multi-window": 330 return runSupportsSplitScreenMultiwindow(pw); 331 case "update-appinfo": 332 return runUpdateApplicationInfo(pw); 333 case "no-home-screen": 334 return runNoHomeScreen(pw); 335 case "wait-for-broadcast-idle": 336 return runWaitForBroadcastIdle(pw); 337 case "compat": 338 return runCompat(pw); 339 case "refresh-settings-cache": 340 return runRefreshSettingsCache(); 341 case "memory-factor": 342 return runMemoryFactor(pw); 343 case "service-restart-backoff": 344 return runServiceRestartBackoff(pw); 345 case "get-isolated-pids": 346 return runGetIsolatedProcesses(pw); 347 case "set-stop-user-on-switch": 348 return runSetStopUserOnSwitch(pw); 349 case "set-bg-abusive-uids": 350 return runSetBgAbusiveUids(pw); 351 case "list-bg-exemptions-config": 352 return runListBgExemptionsConfig(pw); 353 default: 354 return handleDefaultCommands(cmd); 355 } 356 } catch (RemoteException e) { 357 pw.println("Remote exception: " + e); 358 } 359 return -1; 360 } 361 makeIntent(int defUser)362 private Intent makeIntent(int defUser) throws URISyntaxException { 363 mStartFlags = 0; 364 mWaitOption = false; 365 mStopOption = false; 366 mRepeat = 0; 367 mProfileFile = null; 368 mSamplingInterval = 0; 369 mAutoStop = false; 370 mStreaming = false; 371 mUserId = defUser; 372 mDisplayId = INVALID_DISPLAY; 373 mWindowingMode = WINDOWING_MODE_UNDEFINED; 374 mActivityType = ACTIVITY_TYPE_UNDEFINED; 375 mTaskId = INVALID_TASK_ID; 376 mIsTaskOverlay = false; 377 mIsLockTask = false; 378 mAsync = false; 379 mBroadcastOptions = null; 380 381 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { 382 @Override 383 public boolean handleOption(String opt, ShellCommand cmd) { 384 if (opt.equals("-D")) { 385 mStartFlags |= ActivityManager.START_FLAG_DEBUG; 386 } else if (opt.equals("-N")) { 387 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING; 388 } else if (opt.equals("-W")) { 389 mWaitOption = true; 390 } else if (opt.equals("-P")) { 391 mProfileFile = getNextArgRequired(); 392 mAutoStop = true; 393 } else if (opt.equals("--start-profiler")) { 394 mProfileFile = getNextArgRequired(); 395 mAutoStop = false; 396 } else if (opt.equals("--sampling")) { 397 mSamplingInterval = Integer.parseInt(getNextArgRequired()); 398 } else if (opt.equals("--streaming")) { 399 mStreaming = true; 400 } else if (opt.equals("--attach-agent")) { 401 if (mAgent != null) { 402 cmd.getErrPrintWriter().println( 403 "Multiple --attach-agent(-bind) not supported"); 404 return false; 405 } 406 mAgent = getNextArgRequired(); 407 mAttachAgentDuringBind = false; 408 } else if (opt.equals("--attach-agent-bind")) { 409 if (mAgent != null) { 410 cmd.getErrPrintWriter().println( 411 "Multiple --attach-agent(-bind) not supported"); 412 return false; 413 } 414 mAgent = getNextArgRequired(); 415 mAttachAgentDuringBind = true; 416 } else if (opt.equals("-R")) { 417 mRepeat = Integer.parseInt(getNextArgRequired()); 418 } else if (opt.equals("-S")) { 419 mStopOption = true; 420 } else if (opt.equals("--track-allocation")) { 421 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION; 422 } else if (opt.equals("--user")) { 423 mUserId = UserHandle.parseUserArg(getNextArgRequired()); 424 } else if (opt.equals("--receiver-permission")) { 425 mReceiverPermission = getNextArgRequired(); 426 } else if (opt.equals("--display")) { 427 mDisplayId = Integer.parseInt(getNextArgRequired()); 428 } else if (opt.equals("--windowingMode")) { 429 mWindowingMode = Integer.parseInt(getNextArgRequired()); 430 } else if (opt.equals("--activityType")) { 431 mActivityType = Integer.parseInt(getNextArgRequired()); 432 } else if (opt.equals("--task")) { 433 mTaskId = Integer.parseInt(getNextArgRequired()); 434 } else if (opt.equals("--task-overlay")) { 435 mIsTaskOverlay = true; 436 } else if (opt.equals("--lock-task")) { 437 mIsLockTask = true; 438 } else if (opt.equals("--allow-background-activity-starts")) { 439 if (mBroadcastOptions == null) { 440 mBroadcastOptions = BroadcastOptions.makeBasic(); 441 } 442 mBroadcastOptions.setBackgroundActivityStartsAllowed(true); 443 } else if (opt.equals("--async")) { 444 mAsync = true; 445 } else if (opt.equals("--splashscreen-show-icon")) { 446 mShowSplashScreen = true; 447 } else if (opt.equals("--dismiss-keyguard")) { 448 mDismissKeyguard = true; 449 } else { 450 return false; 451 } 452 return true; 453 } 454 }); 455 } 456 457 private class ProgressWaiter extends IProgressListener.Stub { 458 private final CountDownLatch mFinishedLatch = new CountDownLatch(1); 459 460 @Override 461 public void onStarted(int id, Bundle extras) {} 462 463 @Override 464 public void onProgress(int id, int progress, Bundle extras) {} 465 466 @Override 467 public void onFinished(int id, Bundle extras) { 468 mFinishedLatch.countDown(); 469 } 470 471 public boolean waitForFinish(long timeoutMillis) { 472 try { 473 return mFinishedLatch.await(timeoutMillis, TimeUnit.MILLISECONDS); 474 } catch (InterruptedException e) { 475 System.err.println("Thread interrupted unexpectedly."); 476 return false; 477 } 478 } 479 } 480 481 int runStartActivity(PrintWriter pw) throws RemoteException { 482 Intent intent; 483 try { 484 intent = makeIntent(UserHandle.USER_CURRENT); 485 } catch (URISyntaxException e) { 486 throw new RuntimeException(e.getMessage(), e); 487 } 488 489 if (mUserId == UserHandle.USER_ALL) { 490 getErrPrintWriter().println("Error: Can't start service with user 'all'"); 491 return 1; 492 } 493 494 String mimeType = intent.getType(); 495 if (mimeType == null && intent.getData() != null 496 && "content".equals(intent.getData().getScheme())) { 497 mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId); 498 } 499 500 do { 501 if (mStopOption) { 502 String packageName; 503 if (intent.getComponent() != null) { 504 packageName = intent.getComponent().getPackageName(); 505 } else { 506 // queryIntentActivities does not convert user id, so we convert it here first 507 int userIdForQuery = mInternal.mUserController.handleIncomingUser( 508 Binder.getCallingPid(), Binder.getCallingUid(), mUserId, false, 509 ALLOW_NON_FULL, "ActivityManagerShellCommand", null); 510 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0, 511 userIdForQuery).getList(); 512 if (activities == null || activities.size() <= 0) { 513 getErrPrintWriter().println("Error: Intent does not match any activities: " 514 + intent); 515 return 1; 516 } else if (activities.size() > 1) { 517 getErrPrintWriter().println( 518 "Error: Intent matches multiple activities; can't stop: " 519 + intent); 520 return 1; 521 } 522 packageName = activities.get(0).activityInfo.packageName; 523 } 524 pw.println("Stopping: " + packageName); 525 pw.flush(); 526 mInterface.forceStopPackage(packageName, mUserId); 527 try { 528 Thread.sleep(250); 529 } catch (InterruptedException e) { 530 } 531 } 532 533 ProfilerInfo profilerInfo = null; 534 535 if (mProfileFile != null || mAgent != null) { 536 ParcelFileDescriptor fd = null; 537 if (mProfileFile != null) { 538 fd = openFileForSystem(mProfileFile, "w"); 539 if (fd == null) { 540 return 1; 541 } 542 } 543 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, 544 mStreaming, mAgent, mAttachAgentDuringBind); 545 } 546 547 pw.println("Starting: " + intent); 548 pw.flush(); 549 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 550 551 WaitResult result = null; 552 int res; 553 final long startTime = SystemClock.uptimeMillis(); 554 ActivityOptions options = null; 555 if (mDisplayId != INVALID_DISPLAY) { 556 options = ActivityOptions.makeBasic(); 557 options.setLaunchDisplayId(mDisplayId); 558 } 559 if (mWindowingMode != WINDOWING_MODE_UNDEFINED) { 560 if (options == null) { 561 options = ActivityOptions.makeBasic(); 562 } 563 options.setLaunchWindowingMode(mWindowingMode); 564 } 565 if (mActivityType != ACTIVITY_TYPE_UNDEFINED) { 566 if (options == null) { 567 options = ActivityOptions.makeBasic(); 568 } 569 options.setLaunchActivityType(mActivityType); 570 } 571 if (mTaskId != INVALID_TASK_ID) { 572 if (options == null) { 573 options = ActivityOptions.makeBasic(); 574 } 575 options.setLaunchTaskId(mTaskId); 576 577 if (mIsTaskOverlay) { 578 options.setTaskOverlay(true, true /* canResume */); 579 } 580 } 581 if (mIsLockTask) { 582 if (options == null) { 583 options = ActivityOptions.makeBasic(); 584 } 585 options.setLockTaskEnabled(true); 586 } 587 if (mShowSplashScreen) { 588 if (options == null) { 589 options = ActivityOptions.makeBasic(); 590 } 591 options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON); 592 } 593 if (mDismissKeyguard) { 594 if (options == null) { 595 options = ActivityOptions.makeBasic(); 596 } 597 options.setDismissKeyguard(); 598 } 599 if (mWaitOption) { 600 result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent, 601 mimeType, null, null, 0, mStartFlags, profilerInfo, 602 options != null ? options.toBundle() : null, mUserId); 603 res = result.result; 604 } else { 605 res = mInternal.startActivityAsUserWithFeature(null, SHELL_PACKAGE_NAME, null, 606 intent, mimeType, null, null, 0, mStartFlags, profilerInfo, 607 options != null ? options.toBundle() : null, mUserId); 608 } 609 final long endTime = SystemClock.uptimeMillis(); 610 PrintWriter out = mWaitOption ? pw : getErrPrintWriter(); 611 boolean launched = false; 612 switch (res) { 613 case ActivityManager.START_SUCCESS: 614 launched = true; 615 break; 616 case ActivityManager.START_SWITCHES_CANCELED: 617 launched = true; 618 out.println( 619 "Warning: Activity not started because the " 620 + " current activity is being kept for the user."); 621 break; 622 case ActivityManager.START_DELIVERED_TO_TOP: 623 launched = true; 624 out.println( 625 "Warning: Activity not started, intent has " 626 + "been delivered to currently running " 627 + "top-most instance."); 628 break; 629 case ActivityManager.START_RETURN_INTENT_TO_CALLER: 630 launched = true; 631 out.println( 632 "Warning: Activity not started because intent " 633 + "should be handled by the caller"); 634 break; 635 case ActivityManager.START_TASK_TO_FRONT: 636 launched = true; 637 out.println( 638 "Warning: Activity not started, its current " 639 + "task has been brought to the front"); 640 break; 641 case ActivityManager.START_INTENT_NOT_RESOLVED: 642 out.println( 643 "Error: Activity not started, unable to " 644 + "resolve " + intent.toString()); 645 break; 646 case ActivityManager.START_CLASS_NOT_FOUND: 647 out.println(NO_CLASS_ERROR_CODE); 648 out.println("Error: Activity class " + 649 intent.getComponent().toShortString() 650 + " does not exist."); 651 break; 652 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: 653 out.println( 654 "Error: Activity not started, you requested to " 655 + "both forward and receive its result"); 656 break; 657 case ActivityManager.START_PERMISSION_DENIED: 658 out.println( 659 "Error: Activity not started, you do not " 660 + "have permission to access it."); 661 break; 662 case ActivityManager.START_NOT_VOICE_COMPATIBLE: 663 out.println( 664 "Error: Activity not started, voice control not allowed for: " 665 + intent); 666 break; 667 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY: 668 out.println( 669 "Error: Not allowed to start background user activity" 670 + " that shouldn't be displayed for all users."); 671 break; 672 default: 673 out.println( 674 "Error: Activity not started, unknown error code " + res); 675 break; 676 } 677 out.flush(); 678 if (mWaitOption && launched) { 679 if (result == null) { 680 result = new WaitResult(); 681 result.who = intent.getComponent(); 682 } 683 pw.println("Status: " + (result.timeout ? "timeout" : "ok")); 684 pw.println("LaunchState: " + launchStateToString(result.launchState)); 685 if (result.who != null) { 686 pw.println("Activity: " + result.who.flattenToShortString()); 687 } 688 if (result.totalTime >= 0) { 689 pw.println("TotalTime: " + result.totalTime); 690 } 691 pw.println("WaitTime: " + (endTime-startTime)); 692 pw.println("Complete"); 693 pw.flush(); 694 } 695 mRepeat--; 696 if (mRepeat > 0) { 697 mTaskInterface.unhandledBack(); 698 } 699 } while (mRepeat > 0); 700 return 0; 701 } 702 703 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException { 704 final PrintWriter err = getErrPrintWriter(); 705 Intent intent; 706 try { 707 intent = makeIntent(UserHandle.USER_CURRENT); 708 } catch (URISyntaxException e) { 709 throw new RuntimeException(e.getMessage(), e); 710 } 711 if (mUserId == UserHandle.USER_ALL) { 712 err.println("Error: Can't start activity with user 'all'"); 713 return -1; 714 } 715 pw.println("Starting service: " + intent); 716 pw.flush(); 717 ComponentName cn = mInterface.startService(null, intent, intent.getType(), 718 asForeground, SHELL_PACKAGE_NAME, null, mUserId); 719 if (cn == null) { 720 err.println("Error: Not found; no service started."); 721 return -1; 722 } else if (cn.getPackageName().equals("!")) { 723 err.println("Error: Requires permission " + cn.getClassName()); 724 return -1; 725 } else if (cn.getPackageName().equals("!!")) { 726 err.println("Error: " + cn.getClassName()); 727 return -1; 728 } else if (cn.getPackageName().equals("?")) { 729 err.println("Error: " + cn.getClassName()); 730 return -1; 731 } 732 return 0; 733 } 734 735 int runStopService(PrintWriter pw) throws RemoteException { 736 final PrintWriter err = getErrPrintWriter(); 737 Intent intent; 738 try { 739 intent = makeIntent(UserHandle.USER_CURRENT); 740 } catch (URISyntaxException e) { 741 throw new RuntimeException(e.getMessage(), e); 742 } 743 if (mUserId == UserHandle.USER_ALL) { 744 err.println("Error: Can't stop activity with user 'all'"); 745 return -1; 746 } 747 pw.println("Stopping service: " + intent); 748 pw.flush(); 749 int result = mInterface.stopService(null, intent, intent.getType(), mUserId); 750 if (result == 0) { 751 err.println("Service not stopped: was not running."); 752 return -1; 753 } else if (result == 1) { 754 err.println("Service stopped"); 755 return -1; 756 } else if (result == -1) { 757 err.println("Error stopping service"); 758 return -1; 759 } 760 return 0; 761 } 762 763 final static class IntentReceiver extends IIntentReceiver.Stub { 764 private final PrintWriter mPw; 765 private boolean mFinished = false; 766 767 IntentReceiver(PrintWriter pw) { 768 mPw = pw; 769 } 770 771 @Override 772 public void performReceive(Intent intent, int resultCode, String data, Bundle extras, 773 boolean ordered, boolean sticky, int sendingUser) { 774 String line = "Broadcast completed: result=" + resultCode; 775 if (data != null) line = line + ", data=\"" + data + "\""; 776 if (extras != null) line = line + ", extras: " + extras; 777 mPw.println(line); 778 mPw.flush(); 779 synchronized (this) { 780 mFinished = true; 781 notifyAll(); 782 } 783 } 784 785 public synchronized void waitForFinish() { 786 try { 787 while (!mFinished) wait(); 788 } catch (InterruptedException e) { 789 throw new IllegalStateException(e); 790 } 791 } 792 } 793 794 int runSendBroadcast(PrintWriter pw) throws RemoteException { 795 Intent intent; 796 try { 797 intent = makeIntent(UserHandle.USER_CURRENT); 798 } catch (URISyntaxException e) { 799 throw new RuntimeException(e.getMessage(), e); 800 } 801 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL); 802 IntentReceiver receiver = new IntentReceiver(pw); 803 String[] requiredPermissions = mReceiverPermission == null ? null 804 : new String[] {mReceiverPermission}; 805 pw.println("Broadcasting: " + intent); 806 pw.flush(); 807 Bundle bundle = mBroadcastOptions == null ? null : mBroadcastOptions.toBundle(); 808 mInterface.broadcastIntentWithFeature(null, null, intent, null, receiver, 0, null, null, 809 requiredPermissions, null, null, android.app.AppOpsManager.OP_NONE, bundle, true, 810 false, mUserId); 811 if (!mAsync) { 812 receiver.waitForFinish(); 813 } 814 return 0; 815 } 816 817 int runTraceIpc(PrintWriter pw) throws RemoteException { 818 String op = getNextArgRequired(); 819 if (op.equals("start")) { 820 return runTraceIpcStart(pw); 821 } else if (op.equals("stop")) { 822 return runTraceIpcStop(pw); 823 } else { 824 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'"); 825 return -1; 826 } 827 } 828 829 int runTraceIpcStart(PrintWriter pw) throws RemoteException { 830 pw.println("Starting IPC tracing."); 831 pw.flush(); 832 mInterface.startBinderTracking(); 833 return 0; 834 } 835 836 int runTraceIpcStop(PrintWriter pw) throws RemoteException { 837 final PrintWriter err = getErrPrintWriter(); 838 String opt; 839 String filename = null; 840 while ((opt=getNextOption()) != null) { 841 if (opt.equals("--dump-file")) { 842 filename = getNextArgRequired(); 843 } else { 844 err.println("Error: Unknown option: " + opt); 845 return -1; 846 } 847 } 848 if (filename == null) { 849 err.println("Error: Specify filename to dump logs to."); 850 return -1; 851 } 852 853 // Writes an error message to stderr on failure 854 ParcelFileDescriptor fd = openFileForSystem(filename, "w"); 855 if (fd == null) { 856 return -1; 857 } 858 859 if (!mInterface.stopBinderTrackingAndDump(fd)) { 860 err.println("STOP TRACE FAILED."); 861 return -1; 862 } 863 864 pw.println("Stopped IPC tracing. Dumping logs to: " + filename); 865 return 0; 866 } 867 868 static void removeWallOption() { 869 String props = SystemProperties.get("dalvik.vm.extra-opts"); 870 if (props != null && props.contains("-Xprofile:wallclock")) { 871 props = props.replace("-Xprofile:wallclock", ""); 872 props = props.trim(); 873 SystemProperties.set("dalvik.vm.extra-opts", props); 874 } 875 } 876 877 private int runProfile(PrintWriter pw) throws RemoteException { 878 final PrintWriter err = getErrPrintWriter(); 879 String profileFile = null; 880 boolean start = false; 881 boolean wall = false; 882 int userId = UserHandle.USER_CURRENT; 883 int profileType = 0; 884 mSamplingInterval = 0; 885 mStreaming = false; 886 887 String process = null; 888 889 String cmd = getNextArgRequired(); 890 891 if ("start".equals(cmd)) { 892 start = true; 893 String opt; 894 while ((opt=getNextOption()) != null) { 895 if (opt.equals("--user")) { 896 userId = UserHandle.parseUserArg(getNextArgRequired()); 897 } else if (opt.equals("--wall")) { 898 wall = true; 899 } else if (opt.equals("--streaming")) { 900 mStreaming = true; 901 } else if (opt.equals("--sampling")) { 902 mSamplingInterval = Integer.parseInt(getNextArgRequired()); 903 } else { 904 err.println("Error: Unknown option: " + opt); 905 return -1; 906 } 907 } 908 process = getNextArgRequired(); 909 } else if ("stop".equals(cmd)) { 910 String opt; 911 while ((opt=getNextOption()) != null) { 912 if (opt.equals("--user")) { 913 userId = UserHandle.parseUserArg(getNextArgRequired()); 914 } else { 915 err.println("Error: Unknown option: " + opt); 916 return -1; 917 } 918 } 919 process = getNextArgRequired(); 920 } else { 921 // Compatibility with old syntax: process is specified first. 922 process = cmd; 923 cmd = getNextArgRequired(); 924 if ("start".equals(cmd)) { 925 start = true; 926 } else if (!"stop".equals(cmd)) { 927 throw new IllegalArgumentException("Profile command " + process + " not valid"); 928 } 929 } 930 931 if (userId == UserHandle.USER_ALL) { 932 err.println("Error: Can't profile with user 'all'"); 933 return -1; 934 } 935 936 ParcelFileDescriptor fd = null; 937 ProfilerInfo profilerInfo = null; 938 939 if (start) { 940 profileFile = getNextArgRequired(); 941 fd = openFileForSystem(profileFile, "w"); 942 if (fd == null) { 943 return -1; 944 } 945 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming, 946 null, false); 947 } 948 949 try { 950 if (wall) { 951 // XXX doesn't work -- this needs to be set before booting. 952 String props = SystemProperties.get("dalvik.vm.extra-opts"); 953 if (props == null || !props.contains("-Xprofile:wallclock")) { 954 props = props + " -Xprofile:wallclock"; 955 //SystemProperties.set("dalvik.vm.extra-opts", props); 956 } 957 } else if (start) { 958 //removeWallOption(); 959 } 960 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) { 961 wall = false; 962 err.println("PROFILE FAILED on process " + process); 963 return -1; 964 } 965 } finally { 966 if (!wall) { 967 //removeWallOption(); 968 } 969 } 970 return 0; 971 } 972 973 @NeverCompile 974 int runCompact(PrintWriter pw) { 975 String processName = getNextArgRequired(); 976 String uid = getNextArgRequired(); 977 String op = getNextArgRequired(); 978 ProcessRecord app; 979 synchronized (mInternal.mProcLock) { 980 app = mInternal.getProcessRecordLocked(processName, Integer.parseInt(uid)); 981 } 982 pw.println("Process record found pid: " + app.mPid); 983 if (op.equals("full")) { 984 pw.println("Executing full compaction for " + app.mPid); 985 synchronized (mInternal.mProcLock) { 986 mInternal.mOomAdjuster.mCachedAppOptimizer.compactAppFull(app, true); 987 } 988 pw.println("Finished full compaction for " + app.mPid); 989 } else if (op.equals("some")) { 990 pw.println("Executing some compaction for " + app.mPid); 991 synchronized (mInternal.mProcLock) { 992 mInternal.mOomAdjuster.mCachedAppOptimizer.compactAppSome(app, true); 993 } 994 pw.println("Finished some compaction for " + app.mPid); 995 } else { 996 getErrPrintWriter().println("Error: unknown compact command '" + op + "'"); 997 return -1; 998 } 999 1000 return 0; 1001 } 1002 1003 int runDumpHeap(PrintWriter pw) throws RemoteException { 1004 final PrintWriter err = getErrPrintWriter(); 1005 boolean managed = true; 1006 boolean mallocInfo = false; 1007 int userId = UserHandle.USER_CURRENT; 1008 boolean runGc = false; 1009 1010 String opt; 1011 while ((opt=getNextOption()) != null) { 1012 if (opt.equals("--user")) { 1013 userId = UserHandle.parseUserArg(getNextArgRequired()); 1014 if (userId == UserHandle.USER_ALL) { 1015 err.println("Error: Can't dump heap with user 'all'"); 1016 return -1; 1017 } 1018 } else if (opt.equals("-n")) { 1019 managed = false; 1020 } else if (opt.equals("-g")) { 1021 runGc = true; 1022 } else if (opt.equals("-m")) { 1023 managed = false; 1024 mallocInfo = true; 1025 } else { 1026 err.println("Error: Unknown option: " + opt); 1027 return -1; 1028 } 1029 } 1030 String process = getNextArgRequired(); 1031 String heapFile = getNextArg(); 1032 if (heapFile == null) { 1033 LocalDateTime localDateTime = LocalDateTime.now(Clock.systemDefaultZone()); 1034 String logNameTimeString = LOG_NAME_TIME_FORMATTER.format(localDateTime); 1035 heapFile = "/data/local/tmp/heapdump-" + logNameTimeString + ".prof"; 1036 } 1037 1038 // Writes an error message to stderr on failure 1039 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w"); 1040 if (fd == null) { 1041 return -1; 1042 } 1043 1044 pw.println("File: " + heapFile); 1045 pw.flush(); 1046 1047 final CountDownLatch latch = new CountDownLatch(1); 1048 1049 final RemoteCallback finishCallback = new RemoteCallback(new OnResultListener() { 1050 @Override 1051 public void onResult(Bundle result) { 1052 latch.countDown(); 1053 } 1054 }, null); 1055 1056 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd, 1057 finishCallback)) { 1058 err.println("HEAP DUMP FAILED on process " + process); 1059 return -1; 1060 } 1061 pw.println("Waiting for dump to finish..."); 1062 pw.flush(); 1063 try { 1064 latch.await(); 1065 } catch (InterruptedException e) { 1066 err.println("Caught InterruptedException"); 1067 } 1068 1069 return 0; 1070 } 1071 1072 int runSetDebugApp(PrintWriter pw) throws RemoteException { 1073 boolean wait = false; 1074 boolean persistent = false; 1075 1076 String opt; 1077 while ((opt=getNextOption()) != null) { 1078 if (opt.equals("-w")) { 1079 wait = true; 1080 } else if (opt.equals("--persistent")) { 1081 persistent = true; 1082 } else { 1083 getErrPrintWriter().println("Error: Unknown option: " + opt); 1084 return -1; 1085 } 1086 } 1087 1088 String pkg = getNextArgRequired(); 1089 mInterface.setDebugApp(pkg, wait, persistent); 1090 return 0; 1091 } 1092 1093 int runSetAgentApp(PrintWriter pw) throws RemoteException { 1094 String pkg = getNextArgRequired(); 1095 String agent = getNextArg(); 1096 mInterface.setAgentApp(pkg, agent); 1097 return 0; 1098 } 1099 1100 int runClearDebugApp(PrintWriter pw) throws RemoteException { 1101 mInterface.setDebugApp(null, false, true); 1102 return 0; 1103 } 1104 1105 int runSetWatchHeap(PrintWriter pw) throws RemoteException { 1106 String proc = getNextArgRequired(); 1107 String limit = getNextArgRequired(); 1108 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null); 1109 return 0; 1110 } 1111 1112 int runClearWatchHeap(PrintWriter pw) throws RemoteException { 1113 String proc = getNextArgRequired(); 1114 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null); 1115 return 0; 1116 } 1117 1118 int runClearExitInfo(PrintWriter pw) throws RemoteException { 1119 mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 1120 "runClearExitInfo()"); 1121 String opt; 1122 int userId = UserHandle.USER_CURRENT; 1123 String packageName = null; 1124 while ((opt = getNextOption()) != null) { 1125 if (opt.equals("--user")) { 1126 userId = UserHandle.parseUserArg(getNextArgRequired()); 1127 } else { 1128 packageName = opt; 1129 } 1130 } 1131 if (userId == UserHandle.USER_CURRENT) { 1132 UserInfo user = mInterface.getCurrentUser(); 1133 if (user == null) { 1134 return -1; 1135 } 1136 userId = user.id; 1137 } 1138 mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(packageName, userId); 1139 return 0; 1140 } 1141 1142 int runBugReport(PrintWriter pw) throws RemoteException { 1143 String opt; 1144 boolean fullBugreport = true; 1145 while ((opt=getNextOption()) != null) { 1146 if (opt.equals("--progress")) { 1147 fullBugreport = false; 1148 mInterface.requestInteractiveBugReport(); 1149 } else if (opt.equals("--telephony")) { 1150 fullBugreport = false; 1151 // no title and description specified 1152 mInterface.requestTelephonyBugReport("" /* no title */, "" /* no descriptions */); 1153 } else { 1154 getErrPrintWriter().println("Error: Unknown option: " + opt); 1155 return -1; 1156 } 1157 } 1158 if (fullBugreport) { 1159 mInterface.requestFullBugReport(); 1160 } 1161 pw.println("Your lovely bug report is being created; please be patient."); 1162 return 0; 1163 } 1164 1165 int runForceStop(PrintWriter pw) throws RemoteException { 1166 int userId = UserHandle.USER_ALL; 1167 1168 String opt; 1169 while ((opt = getNextOption()) != null) { 1170 if (opt.equals("--user")) { 1171 userId = UserHandle.parseUserArg(getNextArgRequired()); 1172 } else { 1173 getErrPrintWriter().println("Error: Unknown option: " + opt); 1174 return -1; 1175 } 1176 } 1177 mInterface.forceStopPackage(getNextArgRequired(), userId); 1178 return 0; 1179 } 1180 1181 int runStopApp(PrintWriter pw) throws RemoteException { 1182 int userId = UserHandle.USER_SYSTEM; 1183 1184 String opt; 1185 while ((opt = getNextOption()) != null) { 1186 if (opt.equals("--user")) { 1187 userId = UserHandle.parseUserArg(getNextArgRequired()); 1188 } else { 1189 getErrPrintWriter().println("Error: Unknown option: " + opt); 1190 return -1; 1191 } 1192 } 1193 mInterface.stopAppForUser(getNextArgRequired(), userId); 1194 return 0; 1195 } 1196 1197 int runClearRecentApps(PrintWriter pw) throws RemoteException { 1198 mTaskInterface.removeAllVisibleRecentTasks(); 1199 return 0; 1200 } 1201 1202 int runFgsNotificationRateLimit(PrintWriter pw) throws RemoteException { 1203 final String toggleValue = getNextArgRequired(); 1204 final boolean enable; 1205 switch (toggleValue) { 1206 case "enable": 1207 enable = true; 1208 break; 1209 case "disable": 1210 enable = false; 1211 break; 1212 default: 1213 throw new IllegalArgumentException( 1214 "Argument must be either 'enable' or 'disable'"); 1215 } 1216 mInterface.enableFgsNotificationRateLimit(enable); 1217 return 0; 1218 } 1219 1220 int runCrash(PrintWriter pw) throws RemoteException { 1221 int userId = UserHandle.USER_ALL; 1222 1223 String opt; 1224 while ((opt=getNextOption()) != null) { 1225 if (opt.equals("--user")) { 1226 userId = UserHandle.parseUserArg(getNextArgRequired()); 1227 } else { 1228 getErrPrintWriter().println("Error: Unknown option: " + opt); 1229 return -1; 1230 } 1231 } 1232 1233 int pid = -1; 1234 String packageName = null; 1235 final String arg = getNextArgRequired(); 1236 // The argument is either a pid or a package name 1237 try { 1238 pid = Integer.parseInt(arg); 1239 } catch (NumberFormatException e) { 1240 packageName = arg; 1241 } 1242 1243 int[] userIds = (userId == UserHandle.USER_ALL) ? mInternal.mUserController.getUserIds() 1244 : new int[]{userId}; 1245 for (int id : userIds) { 1246 if (mInternal.mUserController.hasUserRestriction( 1247 UserManager.DISALLOW_DEBUGGING_FEATURES, id)) { 1248 getOutPrintWriter().println( 1249 "Shell does not have permission to crash packages for user " + id); 1250 continue; 1251 } 1252 mInterface.crashApplicationWithType(-1, pid, packageName, id, "shell-induced crash", 1253 false, CrashedByAdbException.TYPE_ID); 1254 } 1255 return 0; 1256 } 1257 1258 int runKill(PrintWriter pw) throws RemoteException { 1259 int userId = UserHandle.USER_ALL; 1260 1261 String opt; 1262 while ((opt=getNextOption()) != null) { 1263 if (opt.equals("--user")) { 1264 userId = UserHandle.parseUserArg(getNextArgRequired()); 1265 } else { 1266 getErrPrintWriter().println("Error: Unknown option: " + opt); 1267 return -1; 1268 } 1269 } 1270 mInterface.killBackgroundProcesses(getNextArgRequired(), userId); 1271 return 0; 1272 } 1273 1274 int runKillAll(PrintWriter pw) throws RemoteException { 1275 mInterface.killAllBackgroundProcesses(); 1276 return 0; 1277 } 1278 1279 int runMakeIdle(PrintWriter pw) throws RemoteException { 1280 int userId = UserHandle.USER_ALL; 1281 1282 String opt; 1283 while ((opt = getNextOption()) != null) { 1284 if (opt.equals("--user")) { 1285 userId = UserHandle.parseUserArg(getNextArgRequired()); 1286 } else { 1287 getErrPrintWriter().println("Error: Unknown option: " + opt); 1288 return -1; 1289 } 1290 } 1291 mInterface.makePackageIdle(getNextArgRequired(), userId); 1292 return 0; 1293 } 1294 1295 static final class MyActivityController extends IActivityController.Stub { 1296 final IActivityManager mInterface; 1297 final PrintWriter mPw; 1298 final InputStream mInput; 1299 final String mGdbPort; 1300 final boolean mMonkey; 1301 1302 static final int STATE_NORMAL = 0; 1303 static final int STATE_CRASHED = 1; 1304 static final int STATE_EARLY_ANR = 2; 1305 static final int STATE_ANR = 3; 1306 1307 int mState; 1308 1309 static final int RESULT_DEFAULT = 0; 1310 1311 static final int RESULT_CRASH_DIALOG = 0; 1312 static final int RESULT_CRASH_KILL = 1; 1313 1314 static final int RESULT_EARLY_ANR_CONTINUE = 0; 1315 static final int RESULT_EARLY_ANR_KILL = 1; 1316 1317 static final int RESULT_ANR_DIALOG = 0; 1318 static final int RESULT_ANR_KILL = 1; 1319 static final int RESULT_ANR_WAIT = 2; 1320 1321 int mResult; 1322 1323 Process mGdbProcess; 1324 Thread mGdbThread; 1325 boolean mGotGdbPrint; 1326 1327 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input, 1328 String gdbPort, boolean monkey) { 1329 mInterface = iam; 1330 mPw = pw; 1331 mInput = input; 1332 mGdbPort = gdbPort; 1333 mMonkey = monkey; 1334 } 1335 1336 @Override 1337 public boolean activityResuming(String pkg) { 1338 synchronized (this) { 1339 mPw.println("** Activity resuming: " + pkg); 1340 mPw.flush(); 1341 } 1342 return true; 1343 } 1344 1345 @Override 1346 public boolean activityStarting(Intent intent, String pkg) { 1347 synchronized (this) { 1348 mPw.println("** Activity starting: " + pkg); 1349 mPw.flush(); 1350 } 1351 return true; 1352 } 1353 1354 @Override 1355 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg, 1356 long timeMillis, String stackTrace) { 1357 synchronized (this) { 1358 mPw.println("** ERROR: PROCESS CRASHED"); 1359 mPw.println("processName: " + processName); 1360 mPw.println("processPid: " + pid); 1361 mPw.println("shortMsg: " + shortMsg); 1362 mPw.println("longMsg: " + longMsg); 1363 mPw.println("timeMillis: " + timeMillis); 1364 mPw.println("stack:"); 1365 mPw.print(stackTrace); 1366 mPw.println("#"); 1367 mPw.flush(); 1368 int result = waitControllerLocked(pid, STATE_CRASHED); 1369 return result == RESULT_CRASH_KILL ? false : true; 1370 } 1371 } 1372 1373 @Override 1374 public int appEarlyNotResponding(String processName, int pid, String annotation) { 1375 synchronized (this) { 1376 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING"); 1377 mPw.println("processName: " + processName); 1378 mPw.println("processPid: " + pid); 1379 mPw.println("annotation: " + annotation); 1380 mPw.flush(); 1381 int result = waitControllerLocked(pid, STATE_EARLY_ANR); 1382 if (result == RESULT_EARLY_ANR_KILL) return -1; 1383 return 0; 1384 } 1385 } 1386 1387 @Override 1388 public int appNotResponding(String processName, int pid, String processStats) { 1389 synchronized (this) { 1390 mPw.println("** ERROR: PROCESS NOT RESPONDING"); 1391 mPw.println("processName: " + processName); 1392 mPw.println("processPid: " + pid); 1393 mPw.println("processStats:"); 1394 mPw.print(processStats); 1395 mPw.println("#"); 1396 mPw.flush(); 1397 int result = waitControllerLocked(pid, STATE_ANR); 1398 if (result == RESULT_ANR_KILL) return -1; 1399 if (result == RESULT_ANR_WAIT) return 1; 1400 return 0; 1401 } 1402 } 1403 1404 @Override 1405 public int systemNotResponding(String message) { 1406 synchronized (this) { 1407 mPw.println("** ERROR: PROCESS NOT RESPONDING"); 1408 mPw.println("message: " + message); 1409 mPw.println("#"); 1410 mPw.println("Allowing system to die."); 1411 mPw.flush(); 1412 return -1; 1413 } 1414 } 1415 1416 void killGdbLocked() { 1417 mGotGdbPrint = false; 1418 if (mGdbProcess != null) { 1419 mPw.println("Stopping gdbserver"); 1420 mPw.flush(); 1421 mGdbProcess.destroy(); 1422 mGdbProcess = null; 1423 } 1424 if (mGdbThread != null) { 1425 mGdbThread.interrupt(); 1426 mGdbThread = null; 1427 } 1428 } 1429 1430 int waitControllerLocked(int pid, int state) { 1431 if (mGdbPort != null) { 1432 killGdbLocked(); 1433 1434 try { 1435 mPw.println("Starting gdbserver on port " + mGdbPort); 1436 mPw.println("Do the following:"); 1437 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort); 1438 mPw.println(" gdbclient app_process :" + mGdbPort); 1439 mPw.flush(); 1440 1441 mGdbProcess = Runtime.getRuntime().exec(new String[] { 1442 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid) 1443 }); 1444 final InputStreamReader converter = new InputStreamReader( 1445 mGdbProcess.getInputStream()); 1446 mGdbThread = new Thread() { 1447 @Override 1448 public void run() { 1449 BufferedReader in = new BufferedReader(converter); 1450 String line; 1451 int count = 0; 1452 while (true) { 1453 synchronized (MyActivityController.this) { 1454 if (mGdbThread == null) { 1455 return; 1456 } 1457 if (count == 2) { 1458 mGotGdbPrint = true; 1459 MyActivityController.this.notifyAll(); 1460 } 1461 } 1462 try { 1463 line = in.readLine(); 1464 if (line == null) { 1465 return; 1466 } 1467 mPw.println("GDB: " + line); 1468 mPw.flush(); 1469 count++; 1470 } catch (IOException e) { 1471 return; 1472 } 1473 } 1474 } 1475 }; 1476 mGdbThread.start(); 1477 1478 // Stupid waiting for .5s. Doesn't matter if we end early. 1479 try { 1480 this.wait(500); 1481 } catch (InterruptedException e) { 1482 } 1483 1484 } catch (IOException e) { 1485 mPw.println("Failure starting gdbserver: " + e); 1486 mPw.flush(); 1487 killGdbLocked(); 1488 } 1489 } 1490 mState = state; 1491 mPw.println(""); 1492 printMessageForState(); 1493 mPw.flush(); 1494 1495 while (mState != STATE_NORMAL) { 1496 try { 1497 wait(); 1498 } catch (InterruptedException e) { 1499 } 1500 } 1501 1502 killGdbLocked(); 1503 1504 return mResult; 1505 } 1506 1507 void resumeController(int result) { 1508 synchronized (this) { 1509 mState = STATE_NORMAL; 1510 mResult = result; 1511 notifyAll(); 1512 } 1513 } 1514 1515 void printMessageForState() { 1516 switch (mState) { 1517 case STATE_NORMAL: 1518 mPw.println("Monitoring activity manager... available commands:"); 1519 break; 1520 case STATE_CRASHED: 1521 mPw.println("Waiting after crash... available commands:"); 1522 mPw.println("(c)ontinue: show crash dialog"); 1523 mPw.println("(k)ill: immediately kill app"); 1524 break; 1525 case STATE_EARLY_ANR: 1526 mPw.println("Waiting after early ANR... available commands:"); 1527 mPw.println("(c)ontinue: standard ANR processing"); 1528 mPw.println("(k)ill: immediately kill app"); 1529 break; 1530 case STATE_ANR: 1531 mPw.println("Waiting after ANR... available commands:"); 1532 mPw.println("(c)ontinue: show ANR dialog"); 1533 mPw.println("(k)ill: immediately kill app"); 1534 mPw.println("(w)ait: wait some more"); 1535 break; 1536 } 1537 mPw.println("(q)uit: finish monitoring"); 1538 } 1539 1540 void run() throws RemoteException { 1541 try { 1542 printMessageForState(); 1543 mPw.flush(); 1544 1545 mInterface.setActivityController(this, mMonkey); 1546 mState = STATE_NORMAL; 1547 1548 InputStreamReader converter = new InputStreamReader(mInput); 1549 BufferedReader in = new BufferedReader(converter); 1550 String line; 1551 1552 while ((line = in.readLine()) != null) { 1553 boolean addNewline = true; 1554 if (line.length() <= 0) { 1555 addNewline = false; 1556 } else if ("q".equals(line) || "quit".equals(line)) { 1557 resumeController(RESULT_DEFAULT); 1558 break; 1559 } else if (mState == STATE_CRASHED) { 1560 if ("c".equals(line) || "continue".equals(line)) { 1561 resumeController(RESULT_CRASH_DIALOG); 1562 } else if ("k".equals(line) || "kill".equals(line)) { 1563 resumeController(RESULT_CRASH_KILL); 1564 } else { 1565 mPw.println("Invalid command: " + line); 1566 } 1567 } else if (mState == STATE_ANR) { 1568 if ("c".equals(line) || "continue".equals(line)) { 1569 resumeController(RESULT_ANR_DIALOG); 1570 } else if ("k".equals(line) || "kill".equals(line)) { 1571 resumeController(RESULT_ANR_KILL); 1572 } else if ("w".equals(line) || "wait".equals(line)) { 1573 resumeController(RESULT_ANR_WAIT); 1574 } else { 1575 mPw.println("Invalid command: " + line); 1576 } 1577 } else if (mState == STATE_EARLY_ANR) { 1578 if ("c".equals(line) || "continue".equals(line)) { 1579 resumeController(RESULT_EARLY_ANR_CONTINUE); 1580 } else if ("k".equals(line) || "kill".equals(line)) { 1581 resumeController(RESULT_EARLY_ANR_KILL); 1582 } else { 1583 mPw.println("Invalid command: " + line); 1584 } 1585 } else { 1586 mPw.println("Invalid command: " + line); 1587 } 1588 1589 synchronized (this) { 1590 if (addNewline) { 1591 mPw.println(""); 1592 } 1593 printMessageForState(); 1594 mPw.flush(); 1595 } 1596 } 1597 1598 } catch (IOException e) { 1599 e.printStackTrace(mPw); 1600 mPw.flush(); 1601 } finally { 1602 mInterface.setActivityController(null, mMonkey); 1603 } 1604 } 1605 } 1606 1607 int runMonitor(PrintWriter pw) throws RemoteException { 1608 String opt; 1609 String gdbPort = null; 1610 boolean monkey = false; 1611 while ((opt=getNextOption()) != null) { 1612 if (opt.equals("--gdb")) { 1613 gdbPort = getNextArgRequired(); 1614 } else if (opt.equals("-m")) { 1615 monkey = true; 1616 } else { 1617 getErrPrintWriter().println("Error: Unknown option: " + opt); 1618 return -1; 1619 } 1620 } 1621 1622 MyActivityController controller = new MyActivityController(mInterface, pw, 1623 getRawInputStream(), gdbPort, monkey); 1624 controller.run(); 1625 return 0; 1626 } 1627 1628 static final class MyUidObserver extends IUidObserver.Stub 1629 implements ActivityManagerService.OomAdjObserver { 1630 final IActivityManager mInterface; 1631 final ActivityManagerService mInternal; 1632 final PrintWriter mPw; 1633 final InputStream mInput; 1634 final int mUid; 1635 1636 static final int STATE_NORMAL = 0; 1637 1638 int mState; 1639 1640 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) { 1641 mInterface = service; 1642 mInternal = service; 1643 mPw = pw; 1644 mInput = input; 1645 mUid = uid; 1646 } 1647 1648 @Override 1649 public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) 1650 throws RemoteException { 1651 synchronized (this) { 1652 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 1653 try { 1654 mPw.print(uid); 1655 mPw.print(" procstate "); 1656 mPw.print(ProcessList.makeProcStateString(procState)); 1657 mPw.print(" seq "); 1658 mPw.print(procStateSeq); 1659 mPw.print(" capability "); 1660 mPw.println(capability); 1661 mPw.flush(); 1662 } finally { 1663 StrictMode.setThreadPolicy(oldPolicy); 1664 } 1665 } 1666 } 1667 1668 @Override 1669 public void onUidGone(int uid, boolean disabled) throws RemoteException { 1670 synchronized (this) { 1671 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 1672 try { 1673 mPw.print(uid); 1674 mPw.print(" gone"); 1675 if (disabled) { 1676 mPw.print(" disabled"); 1677 } 1678 mPw.println(); 1679 mPw.flush(); 1680 } finally { 1681 StrictMode.setThreadPolicy(oldPolicy); 1682 } 1683 } 1684 } 1685 1686 @Override 1687 public void onUidActive(int uid) throws RemoteException { 1688 synchronized (this) { 1689 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 1690 try { 1691 mPw.print(uid); 1692 mPw.println(" active"); 1693 mPw.flush(); 1694 } finally { 1695 StrictMode.setThreadPolicy(oldPolicy); 1696 } 1697 } 1698 } 1699 1700 @Override 1701 public void onUidIdle(int uid, boolean disabled) throws RemoteException { 1702 synchronized (this) { 1703 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 1704 try { 1705 mPw.print(uid); 1706 mPw.print(" idle"); 1707 if (disabled) { 1708 mPw.print(" disabled"); 1709 } 1710 mPw.println(); 1711 mPw.flush(); 1712 } finally { 1713 StrictMode.setThreadPolicy(oldPolicy); 1714 } 1715 } 1716 } 1717 1718 @Override 1719 public void onUidCachedChanged(int uid, boolean cached) throws RemoteException { 1720 synchronized (this) { 1721 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 1722 try { 1723 mPw.print(uid); 1724 mPw.println(cached ? " cached" : " uncached"); 1725 mPw.flush(); 1726 } finally { 1727 StrictMode.setThreadPolicy(oldPolicy); 1728 } 1729 } 1730 } 1731 1732 @Override 1733 public void onUidProcAdjChanged(int uid) throws RemoteException { 1734 } 1735 1736 @Override 1737 public void onOomAdjMessage(String msg) { 1738 synchronized (this) { 1739 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 1740 try { 1741 mPw.print("# "); 1742 mPw.println(msg); 1743 mPw.flush(); 1744 } finally { 1745 StrictMode.setThreadPolicy(oldPolicy); 1746 } 1747 } 1748 } 1749 1750 void printMessageForState() { 1751 switch (mState) { 1752 case STATE_NORMAL: 1753 mPw.println("Watching uid states... available commands:"); 1754 break; 1755 } 1756 mPw.println("(q)uit: finish watching"); 1757 } 1758 1759 void run() throws RemoteException { 1760 try { 1761 printMessageForState(); 1762 mPw.flush(); 1763 1764 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE 1765 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE 1766 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED, 1767 ActivityManager.PROCESS_STATE_UNKNOWN, null); 1768 if (mUid >= 0) { 1769 mInternal.setOomAdjObserver(mUid, this); 1770 } 1771 mState = STATE_NORMAL; 1772 1773 InputStreamReader converter = new InputStreamReader(mInput); 1774 BufferedReader in = new BufferedReader(converter); 1775 String line; 1776 1777 while ((line = in.readLine()) != null) { 1778 boolean addNewline = true; 1779 if (line.length() <= 0) { 1780 addNewline = false; 1781 } else if ("q".equals(line) || "quit".equals(line)) { 1782 break; 1783 } else { 1784 mPw.println("Invalid command: " + line); 1785 } 1786 1787 synchronized (this) { 1788 if (addNewline) { 1789 mPw.println(""); 1790 } 1791 printMessageForState(); 1792 mPw.flush(); 1793 } 1794 } 1795 1796 } catch (IOException e) { 1797 e.printStackTrace(mPw); 1798 mPw.flush(); 1799 } finally { 1800 if (mUid >= 0) { 1801 mInternal.clearOomAdjObserver(); 1802 } 1803 mInterface.unregisterUidObserver(this); 1804 } 1805 } 1806 } 1807 1808 int runWatchUids(PrintWriter pw) throws RemoteException { 1809 String opt; 1810 int uid = -1; 1811 while ((opt=getNextOption()) != null) { 1812 if (opt.equals("--oom")) { 1813 uid = Integer.parseInt(getNextArgRequired()); 1814 } else { 1815 getErrPrintWriter().println("Error: Unknown option: " + opt); 1816 return -1; 1817 1818 } 1819 } 1820 1821 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid); 1822 controller.run(); 1823 return 0; 1824 } 1825 1826 int runHang(PrintWriter pw) throws RemoteException { 1827 String opt; 1828 boolean allowRestart = false; 1829 while ((opt=getNextOption()) != null) { 1830 if (opt.equals("--allow-restart")) { 1831 allowRestart = true; 1832 } else { 1833 getErrPrintWriter().println("Error: Unknown option: " + opt); 1834 return -1; 1835 } 1836 } 1837 1838 pw.println("Hanging the system..."); 1839 pw.flush(); 1840 try { 1841 mInterface.hang(getShellCallback().getShellCallbackBinder(), allowRestart); 1842 } catch (NullPointerException e) { 1843 pw.println("Hanging failed, since caller " + Binder.getCallingPid() + 1844 " did not provide a ShellCallback!"); 1845 pw.flush(); 1846 return 1; 1847 } 1848 return 0; 1849 } 1850 1851 int runRestart(PrintWriter pw) throws RemoteException { 1852 String opt; 1853 while ((opt=getNextOption()) != null) { 1854 getErrPrintWriter().println("Error: Unknown option: " + opt); 1855 return -1; 1856 } 1857 1858 pw.println("Restart the system..."); 1859 pw.flush(); 1860 mInterface.restart(); 1861 return 0; 1862 } 1863 1864 int runIdleMaintenance(PrintWriter pw) throws RemoteException { 1865 String opt; 1866 while ((opt=getNextOption()) != null) { 1867 getErrPrintWriter().println("Error: Unknown option: " + opt); 1868 return -1; 1869 } 1870 1871 pw.println("Performing idle maintenance..."); 1872 mInterface.sendIdleJobTrigger(); 1873 return 0; 1874 } 1875 1876 int runScreenCompat(PrintWriter pw) throws RemoteException { 1877 String mode = getNextArgRequired(); 1878 boolean enabled; 1879 if ("on".equals(mode)) { 1880 enabled = true; 1881 } else if ("off".equals(mode)) { 1882 enabled = false; 1883 } else { 1884 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode); 1885 return -1; 1886 } 1887 1888 String packageName = getNextArgRequired(); 1889 do { 1890 try { 1891 mInterface.setPackageScreenCompatMode(packageName, enabled 1892 ? ActivityManager.COMPAT_MODE_ENABLED 1893 : ActivityManager.COMPAT_MODE_DISABLED); 1894 } catch (RemoteException e) { 1895 } 1896 packageName = getNextArg(); 1897 } while (packageName != null); 1898 return 0; 1899 } 1900 1901 int runPackageImportance(PrintWriter pw) throws RemoteException { 1902 String packageName = getNextArgRequired(); 1903 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell"); 1904 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState)); 1905 return 0; 1906 } 1907 1908 int runToUri(PrintWriter pw, int flags) throws RemoteException { 1909 Intent intent; 1910 try { 1911 intent = makeIntent(UserHandle.USER_CURRENT); 1912 } catch (URISyntaxException e) { 1913 throw new RuntimeException(e.getMessage(), e); 1914 } 1915 pw.println(intent.toUri(flags)); 1916 return 0; 1917 } 1918 1919 private boolean switchUserAndWaitForComplete(int userId) throws RemoteException { 1920 UserInfo currentUser = mInterface.getCurrentUser(); 1921 if (currentUser != null && userId == currentUser.id) { 1922 // Already switched to the correct user, exit early. 1923 return true; 1924 } 1925 1926 // Register switch observer. 1927 final CountDownLatch switchLatch = new CountDownLatch(1); 1928 mInterface.registerUserSwitchObserver( 1929 new UserSwitchObserver() { 1930 @Override 1931 public void onUserSwitchComplete(int newUserId) { 1932 if (userId == newUserId) { 1933 switchLatch.countDown(); 1934 } 1935 } 1936 }, ActivityManagerShellCommand.class.getName()); 1937 1938 // Switch. 1939 boolean switched = mInterface.switchUser(userId); 1940 if (!switched) { 1941 // Switching failed, don't wait for the user switch observer. 1942 return false; 1943 } 1944 1945 // Wait. 1946 try { 1947 switched = switchLatch.await(USER_OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS); 1948 } catch (InterruptedException e) { 1949 getErrPrintWriter().println("Error: Thread interrupted unexpectedly."); 1950 } 1951 1952 return switched; 1953 } 1954 1955 int runSwitchUser(PrintWriter pw) throws RemoteException { 1956 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class); 1957 final int userSwitchable = userManager.getUserSwitchability(); 1958 if (userSwitchable != UserManager.SWITCHABILITY_STATUS_OK) { 1959 getErrPrintWriter().println("Error: " + userSwitchable); 1960 return -1; 1961 } 1962 boolean wait = false; 1963 String opt; 1964 while ((opt = getNextOption()) != null) { 1965 if ("-w".equals(opt)) { 1966 wait = true; 1967 } else { 1968 getErrPrintWriter().println("Error: unknown option: " + opt); 1969 return -1; 1970 } 1971 } 1972 1973 int userId = Integer.parseInt(getNextArgRequired()); 1974 boolean switched; 1975 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "shell_runSwitchUser"); 1976 try { 1977 if (wait) { 1978 switched = switchUserAndWaitForComplete(userId); 1979 } else { 1980 switched = mInterface.switchUser(userId); 1981 } 1982 if (switched) { 1983 return 0; 1984 } else { 1985 pw.printf("Error: Failed to switch to user %d\n", userId); 1986 return 1; 1987 } 1988 } finally { 1989 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1990 } 1991 } 1992 1993 int runGetCurrentUser(PrintWriter pw) throws RemoteException { 1994 int userId = mInterface.getCurrentUserId(); 1995 if (userId == UserHandle.USER_NULL) { 1996 throw new IllegalStateException("Current user not set"); 1997 } 1998 pw.println(userId); 1999 return 0; 2000 } 2001 2002 int runStartUser(PrintWriter pw) throws RemoteException { 2003 boolean wait = false; 2004 String opt; 2005 while ((opt = getNextOption()) != null) { 2006 if ("-w".equals(opt)) { 2007 wait = true; 2008 } else { 2009 getErrPrintWriter().println("Error: unknown option: " + opt); 2010 return -1; 2011 } 2012 } 2013 int userId = Integer.parseInt(getNextArgRequired()); 2014 2015 final ProgressWaiter waiter = wait ? new ProgressWaiter() : null; 2016 boolean success = mInterface.startUserInBackgroundWithListener(userId, waiter); 2017 if (wait && success) { 2018 success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS); 2019 } 2020 2021 if (success) { 2022 pw.println("Success: user started"); 2023 } else { 2024 getErrPrintWriter().println("Error: could not start user"); 2025 } 2026 return 0; 2027 } 2028 2029 int runUnlockUser(PrintWriter pw) throws RemoteException { 2030 int userId = Integer.parseInt(getNextArgRequired()); 2031 2032 /* 2033 * Originally this command required two more parameters: the hardware 2034 * authentication token and secret needed to unlock the user. However, 2035 * unlockUser() no longer takes a token parameter at all, and there 2036 * isn't really any way for callers of this shell command to get the 2037 * secret if one is needed (i.e., when the user has an LSKF), given that 2038 * the secret must be a cryptographic key derived from the user's 2039 * synthetic password. I.e. the secret is *not* the LSKF here, but 2040 * rather an intermediate value several steps down the chain. 2041 * 2042 * As such, the only supported use for this command is unlocking a user 2043 * who doesn't have an LSKF, with empty or unspecified token and secret. 2044 * 2045 * To preserve previous behavior, an exclamation mark ("!") is also 2046 * accepted for these values; it means the same as an empty string. 2047 */ 2048 String token = getNextArg(); 2049 if (!TextUtils.isEmpty(token) && !"!".equals(token)) { 2050 getErrPrintWriter().println("Error: token parameter not supported"); 2051 return -1; 2052 } 2053 String secret = getNextArg(); 2054 if (!TextUtils.isEmpty(secret) && !"!".equals(secret)) { 2055 getErrPrintWriter().println("Error: secret parameter not supported"); 2056 return -1; 2057 } 2058 2059 boolean success = mInterface.unlockUser(userId, null, null, null); 2060 if (success) { 2061 pw.println("Success: user unlocked"); 2062 } else { 2063 // TODO(b/218389026): we can reach here even if the user's storage 2064 // was successfully unlocked. 2065 getErrPrintWriter().println("Error: could not unlock user"); 2066 } 2067 return 0; 2068 } 2069 2070 static final class StopUserCallback extends IStopUserCallback.Stub { 2071 private boolean mFinished = false; 2072 2073 public synchronized void waitForFinish() { 2074 try { 2075 while (!mFinished) wait(); 2076 } catch (InterruptedException e) { 2077 throw new IllegalStateException(e); 2078 } 2079 } 2080 2081 @Override 2082 public synchronized void userStopped(int userId) { 2083 mFinished = true; 2084 notifyAll(); 2085 } 2086 2087 @Override 2088 public synchronized void userStopAborted(int userId) { 2089 mFinished = true; 2090 notifyAll(); 2091 } 2092 } 2093 2094 int runStopUser(PrintWriter pw) throws RemoteException { 2095 boolean wait = false; 2096 boolean force = false; 2097 String opt; 2098 while ((opt = getNextOption()) != null) { 2099 if ("-w".equals(opt)) { 2100 wait = true; 2101 } else if ("-f".equals(opt)) { 2102 force = true; 2103 } else { 2104 getErrPrintWriter().println("Error: unknown option: " + opt); 2105 return -1; 2106 } 2107 } 2108 int user = Integer.parseInt(getNextArgRequired()); 2109 StopUserCallback callback = wait ? new StopUserCallback() : null; 2110 2111 int res = mInterface.stopUser(user, force, callback); 2112 if (res != ActivityManager.USER_OP_SUCCESS) { 2113 String txt = ""; 2114 switch (res) { 2115 case ActivityManager.USER_OP_IS_CURRENT: 2116 txt = " (Can't stop current user)"; 2117 break; 2118 case ActivityManager.USER_OP_UNKNOWN_USER: 2119 txt = " (Unknown user " + user + ")"; 2120 break; 2121 case ActivityManager.USER_OP_ERROR_IS_SYSTEM: 2122 txt = " (System user cannot be stopped)"; 2123 break; 2124 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP: 2125 txt = " (Can't stop user " + user 2126 + " - one of its related users can't be stopped)"; 2127 break; 2128 } 2129 getErrPrintWriter().println("Switch failed: " + res + txt); 2130 return -1; 2131 } else if (callback != null) { 2132 callback.waitForFinish(); 2133 } 2134 return 0; 2135 } 2136 2137 int runIsUserStopped(PrintWriter pw) { 2138 int userId = UserHandle.parseUserArg(getNextArgRequired()); 2139 boolean stopped = mInternal.isUserStopped(userId); 2140 pw.println(stopped); 2141 return 0; 2142 } 2143 2144 int runGetStartedUserState(PrintWriter pw) throws RemoteException { 2145 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP, 2146 "runGetStartedUserState()"); 2147 final int userId = Integer.parseInt(getNextArgRequired()); 2148 try { 2149 pw.println(mInternal.getStartedUserState(userId)); 2150 } catch (NullPointerException e) { 2151 pw.println("User is not started: " + userId); 2152 } 2153 return 0; 2154 } 2155 2156 int runTrackAssociations(PrintWriter pw) { 2157 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 2158 "runTrackAssociations()"); 2159 synchronized (mInternal) { 2160 if (!mInternal.mTrackingAssociations) { 2161 mInternal.mTrackingAssociations = true; 2162 pw.println("Association tracking started."); 2163 } else { 2164 pw.println("Association tracking already enabled."); 2165 } 2166 } 2167 return 0; 2168 } 2169 2170 int runUntrackAssociations(PrintWriter pw) { 2171 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 2172 "runUntrackAssociations()"); 2173 synchronized (mInternal) { 2174 if (mInternal.mTrackingAssociations) { 2175 mInternal.mTrackingAssociations = false; 2176 mInternal.mAssociations.clear(); 2177 pw.println("Association tracking stopped."); 2178 } else { 2179 pw.println("Association tracking not running."); 2180 } 2181 } 2182 return 0; 2183 } 2184 2185 int getUidState(PrintWriter pw) throws RemoteException { 2186 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP, 2187 "getUidState()"); 2188 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired())); 2189 pw.print(state); 2190 pw.print(" ("); 2191 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state)); 2192 pw.println(")"); 2193 return 0; 2194 } 2195 2196 private List<Configuration> getRecentConfigurations(int days) { 2197 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 2198 Context.USAGE_STATS_SERVICE)); 2199 final long now = System.currentTimeMillis(); 2200 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000); 2201 try { 2202 @SuppressWarnings("unchecked") 2203 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats( 2204 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell"); 2205 if (configStatsSlice == null) { 2206 return Collections.emptyList(); 2207 } 2208 2209 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>(); 2210 final List<ConfigurationStats> configStatsList = configStatsSlice.getList(); 2211 final int configStatsListSize = configStatsList.size(); 2212 for (int i = 0; i < configStatsListSize; i++) { 2213 final ConfigurationStats stats = configStatsList.get(i); 2214 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration()); 2215 if (indexOfKey < 0) { 2216 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount()); 2217 } else { 2218 recentConfigs.setValueAt(indexOfKey, 2219 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount()); 2220 } 2221 } 2222 2223 final Comparator<Configuration> comparator = new Comparator<Configuration>() { 2224 @Override 2225 public int compare(Configuration a, Configuration b) { 2226 return recentConfigs.get(b).compareTo(recentConfigs.get(a)); 2227 } 2228 }; 2229 2230 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size()); 2231 configs.addAll(recentConfigs.keySet()); 2232 Collections.sort(configs, comparator); 2233 return configs; 2234 2235 } catch (RemoteException e) { 2236 return Collections.emptyList(); 2237 } 2238 } 2239 2240 /** 2241 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext 2242 * and EGLSurface and querying extensions. 2243 * 2244 * @param egl An EGL API object 2245 * @param display An EGLDisplay to create a context and surface with 2246 * @param config The EGLConfig to get the extensions for 2247 * @param surfaceSize eglCreatePbufferSurface generic parameters 2248 * @param contextAttribs eglCreateContext generic parameters 2249 * @param glExtensions A Set<String> to add GL extensions to 2250 */ 2251 private static void addExtensionsForConfig( 2252 EGL10 egl, 2253 EGLDisplay display, 2254 EGLConfig config, 2255 int[] surfaceSize, 2256 int[] contextAttribs, 2257 Set<String> glExtensions) { 2258 // Create a context. 2259 EGLContext context = 2260 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs); 2261 // No-op if we can't create a context. 2262 if (context == EGL10.EGL_NO_CONTEXT) { 2263 return; 2264 } 2265 2266 // Create a surface. 2267 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize); 2268 if (surface == EGL10.EGL_NO_SURFACE) { 2269 egl.eglDestroyContext(display, context); 2270 return; 2271 } 2272 2273 // Update the current surface and context. 2274 egl.eglMakeCurrent(display, surface, surface, context); 2275 2276 // Get the list of extensions. 2277 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS); 2278 if (!TextUtils.isEmpty(extensionList)) { 2279 // The list of extensions comes from the driver separated by spaces. 2280 // Split them apart and add them into a Set for deduping purposes. 2281 for (String extension : extensionList.split(" ")) { 2282 glExtensions.add(extension); 2283 } 2284 } 2285 2286 // Tear down the context and surface for this config. 2287 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); 2288 egl.eglDestroySurface(display, surface); 2289 egl.eglDestroyContext(display, context); 2290 } 2291 2292 2293 Set<String> getGlExtensionsFromDriver() { 2294 Set<String> glExtensions = new HashSet<>(); 2295 2296 // Get the EGL implementation. 2297 EGL10 egl = (EGL10) EGLContext.getEGL(); 2298 if (egl == null) { 2299 getErrPrintWriter().println("Warning: couldn't get EGL"); 2300 return glExtensions; 2301 } 2302 2303 // Get the default display and initialize it. 2304 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 2305 int[] version = new int[2]; 2306 egl.eglInitialize(display, version); 2307 2308 // Call getConfigs() in order to find out how many there are. 2309 int[] numConfigs = new int[1]; 2310 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) { 2311 getErrPrintWriter().println("Warning: couldn't get EGL config count"); 2312 return glExtensions; 2313 } 2314 2315 // Allocate space for all configs and ask again. 2316 EGLConfig[] configs = new EGLConfig[numConfigs[0]]; 2317 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) { 2318 getErrPrintWriter().println("Warning: couldn't get EGL configs"); 2319 return glExtensions; 2320 } 2321 2322 // Allocate surface size parameters outside of the main loop to cut down 2323 // on GC thrashing. 1x1 is enough since we are only using it to get at 2324 // the list of extensions. 2325 int[] surfaceSize = 2326 new int[] { 2327 EGL10.EGL_WIDTH, 1, 2328 EGL10.EGL_HEIGHT, 1, 2329 EGL10.EGL_NONE 2330 }; 2331 2332 // For when we need to create a GLES2.0 context. 2333 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 2334 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE}; 2335 2336 // For getting return values from eglGetConfigAttrib 2337 int[] attrib = new int[1]; 2338 2339 for (int i = 0; i < numConfigs[0]; i++) { 2340 // Get caveat for this config in order to skip slow (i.e. software) configs. 2341 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib); 2342 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) { 2343 continue; 2344 } 2345 2346 // If the config does not support pbuffers we cannot do an eglMakeCurrent 2347 // on it in addExtensionsForConfig(), so skip it here. Attempting to make 2348 // it current with a pbuffer will result in an EGL_BAD_MATCH error 2349 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib); 2350 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) { 2351 continue; 2352 } 2353 2354 final int EGL_OPENGL_ES_BIT = 0x0001; 2355 final int EGL_OPENGL_ES2_BIT = 0x0004; 2356 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib); 2357 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) { 2358 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions); 2359 } 2360 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) { 2361 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions); 2362 } 2363 } 2364 2365 // Release all EGL resources. 2366 egl.eglTerminate(display); 2367 2368 return glExtensions; 2369 } 2370 2371 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId, 2372 PrintWriter pw, Configuration config, DisplayMetrics displayMetrics) { 2373 long token = -1; 2374 if (protoOutputStream != null) { 2375 token = protoOutputStream.start(fieldId); 2376 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX, 2377 displayMetrics.widthPixels); 2378 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX, 2379 displayMetrics.heightPixels); 2380 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI, 2381 DisplayMetrics.DENSITY_DEVICE_STABLE); 2382 } 2383 if (pw != null) { 2384 pw.print("stable-width-px: "); pw.println(displayMetrics.widthPixels); 2385 pw.print("stable-height-px: "); pw.println(displayMetrics.heightPixels); 2386 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE); 2387 } 2388 2389 MemInfoReader memreader = new MemInfoReader(); 2390 memreader.readMemInfo(); 2391 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class); 2392 if (protoOutputStream != null) { 2393 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize()); 2394 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM, 2395 ActivityManager.isLowRamDeviceStatic()); 2396 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES, 2397 Runtime.getRuntime().availableProcessors()); 2398 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK, 2399 kgm.isDeviceSecure()); 2400 } 2401 if (pw != null) { 2402 pw.print("total-ram: "); pw.println(memreader.getTotalSize()); 2403 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic()); 2404 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors()); 2405 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure()); 2406 } 2407 2408 ConfigurationInfo configInfo = null; 2409 try { 2410 configInfo = mTaskInterface.getDeviceConfigurationInfo(); 2411 } catch (RemoteException e) { 2412 throw e.rethrowFromSystemServer(); 2413 } 2414 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) { 2415 if (protoOutputStream != null) { 2416 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION, 2417 configInfo.reqGlEsVersion); 2418 } 2419 if (pw != null) { 2420 pw.print("opengl-version: 0x"); 2421 pw.println(Integer.toHexString(configInfo.reqGlEsVersion)); 2422 } 2423 } 2424 2425 Set<String> glExtensionsSet = getGlExtensionsFromDriver(); 2426 String[] glExtensions = new String[glExtensionsSet.size()]; 2427 glExtensions = glExtensionsSet.toArray(glExtensions); 2428 Arrays.sort(glExtensions); 2429 for (int i = 0; i < glExtensions.length; i++) { 2430 if (protoOutputStream != null) { 2431 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS, 2432 glExtensions[i]); 2433 } 2434 if (pw != null) { 2435 pw.print("opengl-extensions: "); pw.println(glExtensions[i]); 2436 } 2437 2438 } 2439 2440 PackageManager pm = mInternal.mContext.getPackageManager(); 2441 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0); 2442 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName)); 2443 for (int i = 0; i < slibs.size(); i++) { 2444 if (protoOutputStream != null) { 2445 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES, 2446 slibs.get(i).getName()); 2447 } 2448 if (pw != null) { 2449 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName()); 2450 } 2451 } 2452 2453 FeatureInfo[] features = pm.getSystemAvailableFeatures(); 2454 Arrays.sort(features, (o1, o2) -> { 2455 if (o1.name == o2.name) return 0; 2456 if (o1.name == null) return -1; 2457 if (o2.name == null) return 1; 2458 return o1.name.compareTo(o2.name); 2459 }); 2460 2461 for (int i = 0; i < features.length; i++) { 2462 if (features[i].name != null) { 2463 if (protoOutputStream != null) { 2464 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name); 2465 } 2466 if (pw != null) { 2467 pw.print("features: "); pw.println(features[i].name); 2468 } 2469 } 2470 } 2471 2472 if (protoOutputStream != null) { 2473 protoOutputStream.end(token); 2474 } 2475 } 2476 2477 int runGetConfig(PrintWriter pw) throws RemoteException { 2478 int days = -1; 2479 int displayId = Display.DEFAULT_DISPLAY; 2480 boolean asProto = false; 2481 boolean inclDevice = false; 2482 2483 String opt; 2484 while ((opt = getNextOption()) != null) { 2485 if (opt.equals("--days")) { 2486 days = Integer.parseInt(getNextArgRequired()); 2487 if (days <= 0) { 2488 throw new IllegalArgumentException("--days must be a positive integer"); 2489 } 2490 } else if (opt.equals("--proto")) { 2491 asProto = true; 2492 } else if (opt.equals("--device")) { 2493 inclDevice = true; 2494 } else if (opt.equals("--display")) { 2495 displayId = Integer.parseInt(getNextArgRequired()); 2496 if (displayId < 0) { 2497 throw new IllegalArgumentException("--display must be a non-negative integer"); 2498 } 2499 } else { 2500 getErrPrintWriter().println("Error: Unknown option: " + opt); 2501 return -1; 2502 } 2503 } 2504 2505 Configuration config = mInterface.getConfiguration(); 2506 if (config == null) { 2507 getErrPrintWriter().println("Activity manager has no configuration"); 2508 return -1; 2509 } 2510 2511 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class); 2512 Display display = dm.getDisplay(displayId); 2513 2514 if (display == null) { 2515 getErrPrintWriter().println("Error: Display does not exist: " + displayId); 2516 return -1; 2517 } 2518 2519 DisplayMetrics metrics = new DisplayMetrics(); 2520 display.getMetrics(metrics); 2521 2522 if (asProto) { 2523 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor()); 2524 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics); 2525 if (inclDevice) { 2526 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, metrics); 2527 } 2528 proto.flush(); 2529 } else { 2530 pw.println("config: " + Configuration.resourceQualifierString(config, metrics)); 2531 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS)); 2532 if (inclDevice) { 2533 writeDeviceConfig(null, -1, pw, config, metrics); 2534 } 2535 2536 if (days >= 0) { 2537 final List<Configuration> recentConfigs = getRecentConfigurations(days); 2538 final int recentConfigSize = recentConfigs.size(); 2539 if (recentConfigSize > 0) { 2540 pw.println("recentConfigs:"); 2541 for (int i = 0; i < recentConfigSize; i++) { 2542 pw.println(" config: " + Configuration.resourceQualifierString( 2543 recentConfigs.get(i))); 2544 } 2545 } 2546 } 2547 2548 } 2549 return 0; 2550 } 2551 2552 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException { 2553 boolean suppress = Boolean.valueOf(getNextArgRequired()); 2554 mTaskInterface.suppressResizeConfigChanges(suppress); 2555 return 0; 2556 } 2557 2558 int runSetInactive(PrintWriter pw) throws RemoteException { 2559 int userId = UserHandle.USER_CURRENT; 2560 2561 String opt; 2562 while ((opt=getNextOption()) != null) { 2563 if (opt.equals("--user")) { 2564 userId = UserHandle.parseUserArg(getNextArgRequired()); 2565 } else { 2566 getErrPrintWriter().println("Error: Unknown option: " + opt); 2567 return -1; 2568 } 2569 } 2570 String packageName = getNextArgRequired(); 2571 String value = getNextArgRequired(); 2572 2573 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 2574 Context.USAGE_STATS_SERVICE)); 2575 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId); 2576 return 0; 2577 } 2578 2579 private int bucketNameToBucketValue(String name) { 2580 String lower = name.toLowerCase(); 2581 if (lower.startsWith("ac")) { 2582 return UsageStatsManager.STANDBY_BUCKET_ACTIVE; 2583 } else if (lower.startsWith("wo")) { 2584 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET; 2585 } else if (lower.startsWith("fr")) { 2586 return UsageStatsManager.STANDBY_BUCKET_FREQUENT; 2587 } else if (lower.startsWith("ra")) { 2588 return UsageStatsManager.STANDBY_BUCKET_RARE; 2589 } else if (lower.startsWith("re")) { 2590 return UsageStatsManager.STANDBY_BUCKET_RESTRICTED; 2591 } else if (lower.startsWith("ne")) { 2592 return UsageStatsManager.STANDBY_BUCKET_NEVER; 2593 } else { 2594 try { 2595 int bucket = Integer.parseInt(lower); 2596 return bucket; 2597 } catch (NumberFormatException nfe) { 2598 getErrPrintWriter().println("Error: Unknown bucket: " + name); 2599 } 2600 } 2601 return -1; 2602 } 2603 2604 int runSetStandbyBucket(PrintWriter pw) throws RemoteException { 2605 int userId = UserHandle.USER_CURRENT; 2606 2607 String opt; 2608 while ((opt=getNextOption()) != null) { 2609 if (opt.equals("--user")) { 2610 userId = UserHandle.parseUserArg(getNextArgRequired()); 2611 } else { 2612 getErrPrintWriter().println("Error: Unknown option: " + opt); 2613 return -1; 2614 } 2615 } 2616 String packageName = getNextArgRequired(); 2617 String value = getNextArgRequired(); 2618 int bucket = bucketNameToBucketValue(value); 2619 if (bucket < 0) return -1; 2620 boolean multiple = peekNextArg() != null; 2621 2622 2623 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 2624 Context.USAGE_STATS_SERVICE)); 2625 if (!multiple) { 2626 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId); 2627 } else { 2628 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>(); 2629 bucketInfoList.add(new AppStandbyInfo(packageName, bucket)); 2630 while ((packageName = getNextArg()) != null) { 2631 value = getNextArgRequired(); 2632 bucket = bucketNameToBucketValue(value); 2633 if (bucket < 0) continue; 2634 bucketInfoList.add(new AppStandbyInfo(packageName, bucket)); 2635 } 2636 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList); 2637 usm.setAppStandbyBuckets(slice, userId); 2638 } 2639 return 0; 2640 } 2641 2642 int runGetStandbyBucket(PrintWriter pw) throws RemoteException { 2643 int userId = UserHandle.USER_CURRENT; 2644 2645 String opt; 2646 while ((opt=getNextOption()) != null) { 2647 if (opt.equals("--user")) { 2648 userId = UserHandle.parseUserArg(getNextArgRequired()); 2649 } else { 2650 getErrPrintWriter().println("Error: Unknown option: " + opt); 2651 return -1; 2652 } 2653 } 2654 String packageName = getNextArg(); 2655 2656 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 2657 Context.USAGE_STATS_SERVICE)); 2658 if (packageName != null) { 2659 int bucket = usm.getAppStandbyBucket(packageName, null, userId); 2660 pw.println(bucket); 2661 } else { 2662 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets( 2663 SHELL_PACKAGE_NAME, userId); 2664 for (AppStandbyInfo bucketInfo : buckets.getList()) { 2665 pw.print(bucketInfo.mPackageName); pw.print(": "); 2666 pw.println(bucketInfo.mStandbyBucket); 2667 } 2668 } 2669 return 0; 2670 } 2671 2672 int runGetInactive(PrintWriter pw) throws RemoteException { 2673 int userId = UserHandle.USER_CURRENT; 2674 2675 String opt; 2676 while ((opt=getNextOption()) != null) { 2677 if (opt.equals("--user")) { 2678 userId = UserHandle.parseUserArg(getNextArgRequired()); 2679 } else { 2680 getErrPrintWriter().println("Error: Unknown option: " + opt); 2681 return -1; 2682 } 2683 } 2684 String packageName = getNextArgRequired(); 2685 2686 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 2687 Context.USAGE_STATS_SERVICE)); 2688 boolean isIdle = usm.isAppInactive(packageName, userId, SHELL_PACKAGE_NAME); 2689 pw.println("Idle=" + isIdle); 2690 return 0; 2691 } 2692 2693 int runSendTrimMemory(PrintWriter pw) throws RemoteException { 2694 int userId = UserHandle.USER_CURRENT; 2695 String opt; 2696 while ((opt = getNextOption()) != null) { 2697 if (opt.equals("--user")) { 2698 userId = UserHandle.parseUserArg(getNextArgRequired()); 2699 if (userId == UserHandle.USER_ALL) { 2700 getErrPrintWriter().println("Error: Can't use user 'all'"); 2701 return -1; 2702 } 2703 } else { 2704 getErrPrintWriter().println("Error: Unknown option: " + opt); 2705 return -1; 2706 } 2707 } 2708 2709 String proc = getNextArgRequired(); 2710 String levelArg = getNextArgRequired(); 2711 int level; 2712 switch (levelArg) { 2713 case "HIDDEN": 2714 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 2715 break; 2716 case "RUNNING_MODERATE": 2717 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 2718 break; 2719 case "BACKGROUND": 2720 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 2721 break; 2722 case "RUNNING_LOW": 2723 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 2724 break; 2725 case "MODERATE": 2726 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 2727 break; 2728 case "RUNNING_CRITICAL": 2729 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 2730 break; 2731 case "COMPLETE": 2732 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 2733 break; 2734 default: 2735 try { 2736 level = Integer.parseInt(levelArg); 2737 } catch (NumberFormatException e) { 2738 getErrPrintWriter().println("Error: Unknown level option: " + levelArg); 2739 return -1; 2740 } 2741 } 2742 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) { 2743 getErrPrintWriter().println("Unknown error: failed to set trim level"); 2744 return -1; 2745 } 2746 return 0; 2747 } 2748 2749 int runDisplay(PrintWriter pw) throws RemoteException { 2750 String op = getNextArgRequired(); 2751 switch (op) { 2752 case "move-stack": 2753 return runDisplayMoveStack(pw); 2754 default: 2755 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 2756 return -1; 2757 } 2758 } 2759 2760 int runStack(PrintWriter pw) throws RemoteException { 2761 String op = getNextArgRequired(); 2762 switch (op) { 2763 case "move-task": 2764 return runStackMoveTask(pw); 2765 case "list": 2766 return runStackList(pw); 2767 case "info": 2768 return runRootTaskInfo(pw); 2769 case "remove": 2770 return runRootTaskRemove(pw); 2771 default: 2772 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 2773 return -1; 2774 } 2775 } 2776 2777 2778 private Rect getBounds() { 2779 String leftStr = getNextArgRequired(); 2780 int left = Integer.parseInt(leftStr); 2781 String topStr = getNextArgRequired(); 2782 int top = Integer.parseInt(topStr); 2783 String rightStr = getNextArgRequired(); 2784 int right = Integer.parseInt(rightStr); 2785 String bottomStr = getNextArgRequired(); 2786 int bottom = Integer.parseInt(bottomStr); 2787 if (left < 0) { 2788 getErrPrintWriter().println("Error: bad left arg: " + leftStr); 2789 return null; 2790 } 2791 if (top < 0) { 2792 getErrPrintWriter().println("Error: bad top arg: " + topStr); 2793 return null; 2794 } 2795 if (right <= 0) { 2796 getErrPrintWriter().println("Error: bad right arg: " + rightStr); 2797 return null; 2798 } 2799 if (bottom <= 0) { 2800 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr); 2801 return null; 2802 } 2803 return new Rect(left, top, right, bottom); 2804 } 2805 2806 int runDisplayMoveStack(PrintWriter pw) throws RemoteException { 2807 String rootTaskIdStr = getNextArgRequired(); 2808 int rootTaskId = Integer.parseInt(rootTaskIdStr); 2809 String displayIdStr = getNextArgRequired(); 2810 int displayId = Integer.parseInt(displayIdStr); 2811 mTaskInterface.moveRootTaskToDisplay(rootTaskId, displayId); 2812 return 0; 2813 } 2814 2815 int runStackMoveTask(PrintWriter pw) throws RemoteException { 2816 String taskIdStr = getNextArgRequired(); 2817 int taskId = Integer.parseInt(taskIdStr); 2818 String rootTaskIdStr = getNextArgRequired(); 2819 int rootTaskId = Integer.parseInt(rootTaskIdStr); 2820 String toTopStr = getNextArgRequired(); 2821 final boolean toTop; 2822 if ("true".equals(toTopStr)) { 2823 toTop = true; 2824 } else if ("false".equals(toTopStr)) { 2825 toTop = false; 2826 } else { 2827 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr); 2828 return -1; 2829 } 2830 2831 mTaskInterface.moveTaskToRootTask(taskId, rootTaskId, toTop); 2832 return 0; 2833 } 2834 2835 int runStackList(PrintWriter pw) throws RemoteException { 2836 List<RootTaskInfo> tasks = mTaskInterface.getAllRootTaskInfos(); 2837 for (RootTaskInfo info : tasks) { 2838 pw.println(info); 2839 } 2840 return 0; 2841 } 2842 2843 int runRootTaskInfo(PrintWriter pw) throws RemoteException { 2844 int windowingMode = Integer.parseInt(getNextArgRequired()); 2845 int activityType = Integer.parseInt(getNextArgRequired()); 2846 RootTaskInfo info = mTaskInterface.getRootTaskInfo(windowingMode, activityType); 2847 pw.println(info); 2848 return 0; 2849 } 2850 2851 int runRootTaskRemove(PrintWriter pw) throws RemoteException { 2852 String taskIdStr = getNextArgRequired(); 2853 int taskId = Integer.parseInt(taskIdStr); 2854 mTaskInterface.removeTask(taskId); 2855 return 0; 2856 } 2857 2858 int runTask(PrintWriter pw) throws RemoteException { 2859 String op = getNextArgRequired(); 2860 if (op.equals("lock")) { 2861 return runTaskLock(pw); 2862 } else if (op.equals("resizeable")) { 2863 return runTaskResizeable(pw); 2864 } else if (op.equals("resize")) { 2865 return runTaskResize(pw); 2866 } else if (op.equals("focus")) { 2867 return runTaskFocus(pw); 2868 } else { 2869 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 2870 return -1; 2871 } 2872 } 2873 2874 int runTaskLock(PrintWriter pw) throws RemoteException { 2875 String taskIdStr = getNextArgRequired(); 2876 if (taskIdStr.equals("stop")) { 2877 mTaskInterface.stopSystemLockTaskMode(); 2878 } else { 2879 int taskId = Integer.parseInt(taskIdStr); 2880 mTaskInterface.startSystemLockTaskMode(taskId); 2881 } 2882 pw.println("Activity manager is " + (mTaskInterface.isInLockTaskMode() ? "" : "not ") + 2883 "in lockTaskMode"); 2884 return 0; 2885 } 2886 2887 int runTaskResizeable(PrintWriter pw) throws RemoteException { 2888 final String taskIdStr = getNextArgRequired(); 2889 final int taskId = Integer.parseInt(taskIdStr); 2890 final String resizeableStr = getNextArgRequired(); 2891 final int resizeableMode = Integer.parseInt(resizeableStr); 2892 mTaskInterface.setTaskResizeable(taskId, resizeableMode); 2893 return 0; 2894 } 2895 2896 int runTaskResize(PrintWriter pw) throws RemoteException { 2897 final String taskIdStr = getNextArgRequired(); 2898 final int taskId = Integer.parseInt(taskIdStr); 2899 final Rect bounds = getBounds(); 2900 if (bounds == null) { 2901 getErrPrintWriter().println("Error: invalid input bounds"); 2902 return -1; 2903 } 2904 taskResize(taskId, bounds, 0, false); 2905 return 0; 2906 } 2907 2908 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize) 2909 throws RemoteException { 2910 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM; 2911 mTaskInterface.resizeTask(taskId, bounds, resizeMode); 2912 try { 2913 Thread.sleep(delay_ms); 2914 } catch (InterruptedException e) { 2915 } 2916 } 2917 2918 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize, 2919 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms) 2920 throws RemoteException { 2921 int maxMove; 2922 if (movingForward) { 2923 while (maxToTravel > 0 2924 && ((horizontal && taskRect.right < stackRect.right) 2925 ||(!horizontal && taskRect.bottom < stackRect.bottom))) { 2926 if (horizontal) { 2927 maxMove = Math.min(stepSize, stackRect.right - taskRect.right); 2928 maxToTravel -= maxMove; 2929 taskRect.right += maxMove; 2930 taskRect.left += maxMove; 2931 } else { 2932 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom); 2933 maxToTravel -= maxMove; 2934 taskRect.top += maxMove; 2935 taskRect.bottom += maxMove; 2936 } 2937 taskResize(taskId, taskRect, delay_ms, false); 2938 } 2939 } else { 2940 while (maxToTravel < 0 2941 && ((horizontal && taskRect.left > stackRect.left) 2942 ||(!horizontal && taskRect.top > stackRect.top))) { 2943 if (horizontal) { 2944 maxMove = Math.min(stepSize, taskRect.left - stackRect.left); 2945 maxToTravel -= maxMove; 2946 taskRect.right -= maxMove; 2947 taskRect.left -= maxMove; 2948 } else { 2949 maxMove = Math.min(stepSize, taskRect.top - stackRect.top); 2950 maxToTravel -= maxMove; 2951 taskRect.top -= maxMove; 2952 taskRect.bottom -= maxMove; 2953 } 2954 taskResize(taskId, taskRect, delay_ms, false); 2955 } 2956 } 2957 // Return the remaining distance we didn't travel because we reached the target location. 2958 return maxToTravel; 2959 } 2960 2961 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) { 2962 int stepSize = 0; 2963 if (greaterThanTarget && target < current) { 2964 current -= inStepSize; 2965 stepSize = inStepSize; 2966 if (target > current) { 2967 stepSize -= (target - current); 2968 } 2969 } 2970 if (!greaterThanTarget && target > current) { 2971 current += inStepSize; 2972 stepSize = inStepSize; 2973 if (target < current) { 2974 stepSize += (current - target); 2975 } 2976 } 2977 return stepSize; 2978 } 2979 2980 int runTaskFocus(PrintWriter pw) throws RemoteException { 2981 final int taskId = Integer.parseInt(getNextArgRequired()); 2982 pw.println("Setting focus to task " + taskId); 2983 mTaskInterface.setFocusedTask(taskId); 2984 return 0; 2985 } 2986 2987 int runWrite(PrintWriter pw) { 2988 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 2989 "registerUidObserver()"); 2990 mInternal.mAtmInternal.flushRecentTasks(); 2991 pw.println("All tasks persisted."); 2992 return 0; 2993 } 2994 2995 int runAttachAgent(PrintWriter pw) { 2996 // TODO: revisit the permissions required for attaching agents 2997 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 2998 "attach-agent"); 2999 String process = getNextArgRequired(); 3000 String agent = getNextArgRequired(); 3001 String opt; 3002 if ((opt = getNextArg()) != null) { 3003 pw.println("Error: Unknown option: " + opt); 3004 return -1; 3005 } 3006 mInternal.attachAgent(process, agent); 3007 return 0; 3008 } 3009 3010 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException { 3011 final Resources res = getResources(pw); 3012 if (res == null) { 3013 return -1; 3014 } 3015 pw.println(ActivityTaskManager.supportsMultiWindow(mInternal.mContext)); 3016 return 0; 3017 } 3018 3019 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException { 3020 final Resources res = getResources(pw); 3021 if (res == null) { 3022 return -1; 3023 } 3024 pw.println(ActivityTaskManager.supportsSplitScreenMultiWindow(mInternal.mContext)); 3025 return 0; 3026 } 3027 3028 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException { 3029 int userid = UserHandle.parseUserArg(getNextArgRequired()); 3030 ArrayList<String> packages = new ArrayList<>(); 3031 packages.add(getNextArgRequired()); 3032 String packageName; 3033 while ((packageName = getNextArg()) != null) { 3034 packages.add(packageName); 3035 } 3036 mInternal.scheduleApplicationInfoChanged(packages, userid); 3037 pw.println("Packages updated with most recent ApplicationInfos."); 3038 return 0; 3039 } 3040 3041 int runNoHomeScreen(PrintWriter pw) throws RemoteException { 3042 final Resources res = getResources(pw); 3043 if (res == null) { 3044 return -1; 3045 } 3046 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen)); 3047 return 0; 3048 } 3049 3050 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException { 3051 mInternal.waitForBroadcastIdle(pw); 3052 return 0; 3053 } 3054 3055 int runRefreshSettingsCache() throws RemoteException { 3056 mInternal.refreshSettingsCache(); 3057 return 0; 3058 } 3059 3060 private int runCompat(PrintWriter pw) throws RemoteException { 3061 final PlatformCompat platformCompat = (PlatformCompat) 3062 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE); 3063 String toggleValue = getNextArgRequired(); 3064 boolean killPackage = !"--no-kill".equals(getNextOption()); 3065 boolean toggleAll = false; 3066 int targetSdkVersion = -1; 3067 long changeId = -1; 3068 3069 if (toggleValue.endsWith("-all")) { 3070 toggleValue = toggleValue.substring(0, toggleValue.lastIndexOf("-all")); 3071 toggleAll = true; 3072 if (!toggleValue.equals("reset")) { 3073 try { 3074 targetSdkVersion = Integer.parseInt(getNextArgRequired()); 3075 } catch (NumberFormatException e) { 3076 pw.println("Invalid targetSdkVersion!"); 3077 return -1; 3078 } 3079 } 3080 } else { 3081 String changeIdString = getNextArgRequired(); 3082 try { 3083 changeId = Long.parseLong(changeIdString); 3084 } catch (NumberFormatException e) { 3085 changeId = platformCompat.lookupChangeId(changeIdString); 3086 } 3087 if (changeId == -1) { 3088 pw.println("Unknown or invalid change: '" + changeIdString + "'."); 3089 return -1; 3090 } 3091 } 3092 String packageName = getNextArgRequired(); 3093 if (!toggleAll && !platformCompat.isKnownChangeId(changeId)) { 3094 pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it" 3095 + " could have no effect."); 3096 } 3097 ArraySet<Long> enabled = new ArraySet<>(); 3098 ArraySet<Long> disabled = new ArraySet<>(); 3099 try { 3100 switch (toggleValue) { 3101 case "enable": 3102 if (toggleAll) { 3103 int numChanges = platformCompat.enableTargetSdkChanges(packageName, 3104 targetSdkVersion); 3105 if (numChanges == 0) { 3106 pw.println("No changes were enabled."); 3107 return -1; 3108 } 3109 pw.println("Enabled " + numChanges + " changes gated by targetSdkVersion " 3110 + targetSdkVersion + " for " + packageName + "."); 3111 } else { 3112 enabled.add(changeId); 3113 CompatibilityChangeConfig overrides = 3114 new CompatibilityChangeConfig( 3115 new Compatibility.ChangeConfig(enabled, disabled)); 3116 if (killPackage) { 3117 platformCompat.setOverrides(overrides, packageName); 3118 } else { 3119 platformCompat.setOverridesForTest(overrides, packageName); 3120 } 3121 pw.println("Enabled change " + changeId + " for " + packageName + "."); 3122 } 3123 return 0; 3124 case "disable": 3125 if (toggleAll) { 3126 int numChanges = platformCompat.disableTargetSdkChanges(packageName, 3127 targetSdkVersion); 3128 if (numChanges == 0) { 3129 pw.println("No changes were disabled."); 3130 return -1; 3131 } 3132 pw.println("Disabled " + numChanges + " changes gated by targetSdkVersion " 3133 + targetSdkVersion + " for " + packageName + "."); 3134 } else { 3135 disabled.add(changeId); 3136 CompatibilityChangeConfig overrides = 3137 new CompatibilityChangeConfig( 3138 new Compatibility.ChangeConfig(enabled, disabled)); 3139 if (killPackage) { 3140 platformCompat.setOverrides(overrides, packageName); 3141 } else { 3142 platformCompat.setOverridesForTest(overrides, packageName); 3143 } 3144 pw.println("Disabled change " + changeId + " for " + packageName + "."); 3145 } 3146 return 0; 3147 case "reset": 3148 if (toggleAll) { 3149 if (killPackage) { 3150 platformCompat.clearOverrides(packageName); 3151 } else { 3152 platformCompat.clearOverridesForTest(packageName); 3153 } 3154 pw.println("Reset all changes for " + packageName + " to default value."); 3155 return 0; 3156 } 3157 boolean existed; 3158 if (killPackage) { 3159 existed = platformCompat.clearOverride(changeId, packageName); 3160 } else { 3161 existed = platformCompat.clearOverrideForTest(changeId, packageName); 3162 } 3163 if (existed) { 3164 pw.println("Reset change " + changeId + " for " + packageName 3165 + " to default value."); 3166 } else { 3167 pw.println("No override exists for changeId " + changeId + "."); 3168 } 3169 return 0; 3170 default: 3171 pw.println("Invalid toggle value: '" + toggleValue + "'."); 3172 } 3173 } catch (SecurityException e) { 3174 pw.println(e.getMessage()); 3175 } 3176 return -1; 3177 } 3178 3179 private int runSetMemoryFactor(PrintWriter pw) throws RemoteException { 3180 final String levelArg = getNextArgRequired(); 3181 @MemFactor int level = ADJ_MEM_FACTOR_NOTHING; 3182 switch (levelArg) { 3183 case "NORMAL": 3184 level = ADJ_MEM_FACTOR_NORMAL; 3185 break; 3186 case "MODERATE": 3187 level = ADJ_MEM_FACTOR_MODERATE; 3188 break; 3189 case "LOW": 3190 level = ADJ_MEM_FACTOR_LOW; 3191 break; 3192 case "CRITICAL": 3193 level = ADJ_MEM_FACTOR_CRITICAL; 3194 break; 3195 default: 3196 try { 3197 level = Integer.parseInt(levelArg); 3198 } catch (NumberFormatException e) { 3199 } 3200 if (level < ADJ_MEM_FACTOR_NORMAL || level > ADJ_MEM_FACTOR_CRITICAL) { 3201 getErrPrintWriter().println("Error: Unknown level option: " + levelArg); 3202 return -1; 3203 } 3204 } 3205 mInternal.setMemFactorOverride(level); 3206 return 0; 3207 } 3208 3209 private int runShowMemoryFactor(PrintWriter pw) throws RemoteException { 3210 final @MemFactor int level = mInternal.getMemoryTrimLevel(); 3211 switch (level) { 3212 case ADJ_MEM_FACTOR_NOTHING: 3213 pw.println("<UNKNOWN>"); 3214 break; 3215 case ADJ_MEM_FACTOR_NORMAL: 3216 pw.println("NORMAL"); 3217 break; 3218 case ADJ_MEM_FACTOR_MODERATE: 3219 pw.println("MODERATE"); 3220 break; 3221 case ADJ_MEM_FACTOR_LOW: 3222 pw.println("LOW"); 3223 break; 3224 case ADJ_MEM_FACTOR_CRITICAL: 3225 pw.println("CRITICAL"); 3226 break; 3227 } 3228 pw.flush(); 3229 return 0; 3230 } 3231 3232 private int runResetMemoryFactor(PrintWriter pw) throws RemoteException { 3233 mInternal.setMemFactorOverride(ADJ_MEM_FACTOR_NOTHING); 3234 return 0; 3235 } 3236 3237 private int runMemoryFactor(PrintWriter pw) throws RemoteException { 3238 mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS, 3239 "runMemoryFactor()"); 3240 3241 final String op = getNextArgRequired(); 3242 switch (op) { 3243 case "set": 3244 return runSetMemoryFactor(pw); 3245 case "show": 3246 return runShowMemoryFactor(pw); 3247 case "reset": 3248 return runResetMemoryFactor(pw); 3249 default: 3250 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 3251 return -1; 3252 } 3253 } 3254 3255 private int runServiceRestartBackoff(PrintWriter pw) throws RemoteException { 3256 mInternal.enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 3257 "runServiceRestartBackoff()"); 3258 3259 final String opt = getNextArgRequired(); 3260 switch (opt) { 3261 case "enable": 3262 mInternal.setServiceRestartBackoffEnabled(getNextArgRequired(), true, "shell"); 3263 return 0; 3264 case "disable": 3265 mInternal.setServiceRestartBackoffEnabled(getNextArgRequired(), false, "shell"); 3266 return 0; 3267 case "show": 3268 pw.println(mInternal.isServiceRestartBackoffEnabled(getNextArgRequired()) 3269 ? "enabled" : "disabled"); 3270 return 0; 3271 default: 3272 getErrPrintWriter().println("Error: unknown command '" + opt + "'"); 3273 return -1; 3274 } 3275 } 3276 3277 private int runGetIsolatedProcesses(PrintWriter pw) throws RemoteException { 3278 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP, 3279 "getIsolatedProcesses()"); 3280 final List<Integer> result = mInternal.mInternal.getIsolatedProcesses( 3281 Integer.parseInt(getNextArgRequired())); 3282 pw.print("["); 3283 if (result != null) { 3284 for (int i = 0, size = result.size(); i < size; i++) { 3285 if (i > 0) { 3286 pw.print(", "); 3287 } 3288 pw.print(result.get(i)); 3289 } 3290 } 3291 pw.println("]"); 3292 return 0; 3293 } 3294 3295 private int runSetStopUserOnSwitch(PrintWriter pw) throws RemoteException { 3296 mInternal.enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 3297 "setStopUserOnSwitch()"); 3298 String arg = getNextArg(); 3299 if (arg == null) { 3300 Slogf.i(TAG, "setStopUserOnSwitch(): resetting to default value"); 3301 mInternal.setStopUserOnSwitch(ActivityManager.STOP_USER_ON_SWITCH_DEFAULT); 3302 pw.println("Reset to default value"); 3303 return 0; 3304 } 3305 3306 boolean stop = Boolean.parseBoolean(arg); 3307 int value = stop 3308 ? ActivityManager.STOP_USER_ON_SWITCH_TRUE 3309 : ActivityManager.STOP_USER_ON_SWITCH_FALSE; 3310 3311 Slogf.i(TAG, "runSetStopUserOnSwitch(): setting to %d (%b)", value, stop); 3312 mInternal.setStopUserOnSwitch(value); 3313 pw.println("Set to " + stop); 3314 3315 return 0; 3316 } 3317 3318 // TODO(b/203105544) STOPSHIP - For debugging only, to be removed before shipping. 3319 private int runSetBgAbusiveUids(PrintWriter pw) throws RemoteException { 3320 final String arg = getNextArg(); 3321 final AppBatteryTracker batteryTracker = 3322 mInternal.mAppRestrictionController.getAppStateTracker(AppBatteryTracker.class); 3323 if (batteryTracker == null) { 3324 getErrPrintWriter().println("Unable to get bg battery tracker"); 3325 return -1; 3326 } 3327 if (arg == null) { 3328 batteryTracker.clearDebugUidPercentage(); 3329 return 0; 3330 } 3331 String[] pairs = arg.split(","); 3332 int[] uids = new int[pairs.length]; 3333 double[][] values = new double[pairs.length][]; 3334 try { 3335 for (int i = 0; i < pairs.length; i++) { 3336 String[] pair = pairs[i].split("="); 3337 if (pair.length != 2) { 3338 getErrPrintWriter().println("Malformed input"); 3339 return -1; 3340 } 3341 uids[i] = Integer.parseInt(pair[0]); 3342 final String[] vals = pair[1].split(":"); 3343 if (vals.length != BATTERY_USAGE_COUNT) { 3344 getErrPrintWriter().println("Malformed input"); 3345 return -1; 3346 } 3347 values[i] = new double[vals.length]; 3348 for (int j = 0; j < vals.length; j++) { 3349 values[i][j] = Double.parseDouble(vals[j]); 3350 } 3351 } 3352 } catch (NumberFormatException e) { 3353 getErrPrintWriter().println("Malformed input"); 3354 return -1; 3355 } 3356 batteryTracker.setDebugUidPercentage(uids, values); 3357 return 0; 3358 } 3359 3360 private int runListBgExemptionsConfig(PrintWriter pw) throws RemoteException { 3361 final ArraySet<String> sysConfigs = mInternal.mAppRestrictionController 3362 .mBgRestrictionExemptioFromSysConfig; 3363 if (sysConfigs != null) { 3364 for (int i = 0, size = sysConfigs.size(); i < size; i++) { 3365 pw.print(sysConfigs.valueAt(i)); 3366 pw.print(' '); 3367 } 3368 pw.println(); 3369 } 3370 return 0; 3371 } 3372 3373 private Resources getResources(PrintWriter pw) throws RemoteException { 3374 // system resources does not contain all the device configuration, construct it manually. 3375 Configuration config = mInterface.getConfiguration(); 3376 if (config == null) { 3377 pw.println("Error: Activity manager has no configuration"); 3378 return null; 3379 } 3380 3381 final DisplayMetrics metrics = new DisplayMetrics(); 3382 metrics.setToDefaults(); 3383 3384 return new Resources(AssetManager.getSystem(), metrics, config); 3385 } 3386 3387 @Override 3388 public void onHelp() { 3389 PrintWriter pw = getOutPrintWriter(); 3390 dumpHelp(pw, mDumping); 3391 } 3392 3393 @NeverCompile // Avoid size overhead of debugging code. 3394 static void dumpHelp(PrintWriter pw, boolean dumping) { 3395 if (dumping) { 3396 pw.println("Activity manager dump options:"); 3397 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ..."); 3398 pw.println(" WHAT may be one of:"); 3399 pw.println(" a[ctivities]: activity stack state"); 3400 pw.println(" r[recents]: recent activities state"); 3401 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 3402 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics"); 3403 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 3404 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 3405 pw.println(" o[om]: out of memory management"); 3406 pw.println(" perm[issions]: URI permission grant state"); 3407 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 3408 pw.println(" provider [COMP_SPEC]: provider client-side state"); 3409 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 3410 pw.println(" allowed-associations: current package association restrictions"); 3411 pw.println(" as[sociations]: tracked app associations"); 3412 pw.println(" exit-info [PACKAGE_NAME]: historical process exit information"); 3413 pw.println(" lmk: stats on low memory killer"); 3414 pw.println(" lru: raw LRU process list"); 3415 pw.println(" binder-proxies: stats on binder objects and IPCs"); 3416 pw.println(" settings: currently applied config settings"); 3417 pw.println(" service [COMP_SPEC]: service client-side state"); 3418 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 3419 pw.println(" all: dump all activities"); 3420 pw.println(" top: dump the top activity"); 3421 pw.println(" WHAT may also be a COMP_SPEC to dump activities."); 3422 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 3423 pw.println(" a partial substring in a component name, a"); 3424 pw.println(" hex object identifier."); 3425 pw.println(" -a: include all available server state."); 3426 pw.println(" -c: include client state."); 3427 pw.println(" -p: limit output to given package."); 3428 pw.println(" --checkin: output checkin format, resetting data."); 3429 pw.println(" --C: output checkin format, not resetting data."); 3430 pw.println(" --proto: output dump in protocol buffer format."); 3431 pw.printf(" %s: dump just the DUMPABLE-related state of an activity. Use the %s " 3432 + "option to list the supported DUMPABLEs\n", Activity.DUMP_ARG_DUMP_DUMPABLE, 3433 Activity.DUMP_ARG_LIST_DUMPABLES); 3434 pw.printf(" %s: show the available dumpables in an activity\n", 3435 Activity.DUMP_ARG_LIST_DUMPABLES); 3436 } else { 3437 pw.println("Activity manager (activity) commands:"); 3438 pw.println(" help"); 3439 pw.println(" Print this help text."); 3440 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]"); 3441 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]"); 3442 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>"); 3443 pw.println(" Start an Activity. Options are:"); 3444 pw.println(" -D: enable debugging"); 3445 pw.println(" -N: enable native debugging"); 3446 pw.println(" -W: wait for launch to complete"); 3447 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>"); 3448 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds"); 3449 pw.println(" between samples (use with --start-profiler)"); 3450 pw.println(" --streaming: stream the profiling output to the specified file"); 3451 pw.println(" (use with --start-profiler)"); 3452 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle"); 3453 pw.println(" --attach-agent <agent>: attach the given agent before binding"); 3454 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding"); 3455 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,"); 3456 pw.println(" the top activity will be finished."); 3457 pw.println(" -S: force stop the target app before starting the activity"); 3458 pw.println(" --track-allocation: enable tracking of object allocations"); 3459 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 3460 pw.println(" specified then run as the current user."); 3461 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into."); 3462 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as."); 3463 pw.println(" --display <DISPLAY_ID>: The display to launch the activity into."); 3464 pw.println(" --splashscreen-icon: Show the splash screen icon on launch."); 3465 pw.println(" start-service [--user <USER_ID> | current] <INTENT>"); 3466 pw.println(" Start a Service. Options are:"); 3467 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 3468 pw.println(" specified then run as the current user."); 3469 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>"); 3470 pw.println(" Start a foreground Service. Options are:"); 3471 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 3472 pw.println(" specified then run as the current user."); 3473 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>"); 3474 pw.println(" Stop a Service. Options are:"); 3475 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 3476 pw.println(" specified then run as the current user."); 3477 pw.println(" broadcast [--user <USER_ID> | all | current]"); 3478 pw.println(" [--receiver-permission <PERMISSION>]"); 3479 pw.println(" [--allow-background-activity-starts]"); 3480 pw.println(" [--async] <INTENT>"); 3481 pw.println(" Send a broadcast Intent. Options are:"); 3482 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not"); 3483 pw.println(" specified then send to all users."); 3484 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission."); 3485 pw.println(" --allow-background-activity-starts: The receiver may start activities"); 3486 pw.println(" even if in the background."); 3487 pw.println(" --async: Send without waiting for the completion of the receiver."); 3488 pw.println(" compact <process_name> <Package UID> [some|full]"); 3489 pw.println(" Force process compaction."); 3490 pw.println(" some: execute file compaction."); 3491 pw.println(" full: execute anon + file compaction."); 3492 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]"); 3493 pw.println(" [--user <USER_ID> | current]"); 3494 pw.println(" [--no-hidden-api-checks [--no-test-api-access]]"); 3495 pw.println(" [--no-isolated-storage]"); 3496 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>"); 3497 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the"); 3498 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there"); 3499 pw.println(" is only one instrumentation. Options are:"); 3500 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with"); 3501 pw.println(" [-e perf true] to generate raw output for performance measurements."); 3502 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a"); 3503 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]]."); 3504 pw.println(" -p <FILE>: write profiling data to <FILE>"); 3505 pw.println(" -m: Write output as protobuf to stdout (machine readable)"); 3506 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine"); 3507 pw.println(" readable). If path is not specified, default directory and file name will"); 3508 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto"); 3509 pw.println(" -w: wait for instrumentation to finish before returning. Required for"); 3510 pw.println(" test runners."); 3511 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;"); 3512 pw.println(" current user if not specified."); 3513 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API."); 3514 pw.println(" --no-test-api-access: do not allow access to test APIs, if hidden"); 3515 pw.println(" API checks are enabled."); 3516 pw.println(" --no-isolated-storage: don't use isolated storage sandbox and "); 3517 pw.println(" mount full external storage"); 3518 pw.println(" --no-window-animation: turn off window animations while running."); 3519 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI."); 3520 pw.println(" This assumes that the process supports the selected ABI."); 3521 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]"); 3522 pw.println(" Trace IPC transactions."); 3523 pw.println(" start: start tracing IPC transactions."); 3524 pw.println(" stop: stop tracing IPC transactions and dump the results to file."); 3525 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to."); 3526 pw.println(" profile start [--user <USER_ID> current]"); 3527 pw.println(" [--sampling INTERVAL | --streaming] <PROCESS> <FILE>"); 3528 pw.println(" Start profiler on a process. The given <PROCESS> argument"); 3529 pw.println(" may be either a process name or pid. Options are:"); 3530 pw.println(" --user <USER_ID> | current: When supplying a process name,"); 3531 pw.println(" specify user of process to profile; uses current user if not"); 3532 pw.println(" specified."); 3533 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds"); 3534 pw.println(" between samples."); 3535 pw.println(" --streaming: stream the profiling output to the specified file."); 3536 pw.println(" profile stop [--user <USER_ID> current] <PROCESS>"); 3537 pw.println(" Stop profiler on a process. The given <PROCESS> argument"); 3538 pw.println(" may be either a process name or pid. Options are:"); 3539 pw.println(" --user <USER_ID> | current: When supplying a process name,"); 3540 pw.println(" specify user of process to profile; uses current user if not"); 3541 pw.println(" specified."); 3542 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>"); 3543 pw.println(" Dump the heap of a process. The given <PROCESS> argument may"); 3544 pw.println(" be either a process name or pid. Options are:"); 3545 pw.println(" -n: dump native heap instead of managed heap"); 3546 pw.println(" -g: force GC before dumping the heap"); 3547 pw.println(" --user <USER_ID> | current: When supplying a process name,"); 3548 pw.println(" specify user of process to dump; uses current user if not specified."); 3549 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>"); 3550 pw.println(" Set application <PACKAGE> to debug. Options are:"); 3551 pw.println(" -w: wait for debugger when application starts"); 3552 pw.println(" --persistent: retain this value"); 3553 pw.println(" clear-debug-app"); 3554 pw.println(" Clear the previously set-debug-app."); 3555 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>"); 3556 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or"); 3557 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report."); 3558 pw.println(" clear-watch-heap"); 3559 pw.println(" Clear the previously set-watch-heap."); 3560 pw.println(" clear-exit-info [--user <USER_ID> | all | current] [package]"); 3561 pw.println(" Clear the process exit-info for given package"); 3562 pw.println(" bug-report [--progress | --telephony]"); 3563 pw.println(" Request bug report generation; will launch a notification"); 3564 pw.println(" when done to select where it should be delivered. Options are:"); 3565 pw.println(" --progress: will launch a notification right away to show its progress."); 3566 pw.println(" --telephony: will dump only telephony sections."); 3567 pw.println(" fgs-notification-rate-limit {enable | disable}"); 3568 pw.println(" Enable/disable rate limit on FGS notification deferral policy."); 3569 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>"); 3570 pw.println(" Completely stop the given application package."); 3571 pw.println(" stop-app [--user <USER_ID> | all | current] <PACKAGE>"); 3572 pw.println(" Stop an app and all of its services. Unlike `force-stop` this does"); 3573 pw.println(" not cancel the app's scheduled alarms and jobs."); 3574 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>"); 3575 pw.println(" Induce a VM crash in the specified package or process"); 3576 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>"); 3577 pw.println(" Kill all background processes associated with the given application."); 3578 pw.println(" kill-all"); 3579 pw.println(" Kill all processes that are safe to kill (cached, etc)."); 3580 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>"); 3581 pw.println(" If the given application's uid is in the background and waiting to"); 3582 pw.println(" become idle (not allowing background services), do that now."); 3583 pw.println(" monitor [--gdb <port>]"); 3584 pw.println(" Start monitoring for crashes or ANRs."); 3585 pw.println(" --gdb: start gdbserv on the given port at crash/ANR"); 3586 pw.println(" watch-uids [--oom <uid>]"); 3587 pw.println(" Start watching for and reporting uid state changes."); 3588 pw.println(" --oom: specify a uid for which to report detailed change messages."); 3589 pw.println(" hang [--allow-restart]"); 3590 pw.println(" Hang the system."); 3591 pw.println(" --allow-restart: allow watchdog to perform normal system restart"); 3592 pw.println(" restart"); 3593 pw.println(" Restart the user-space system."); 3594 pw.println(" idle-maintenance"); 3595 pw.println(" Perform idle maintenance now."); 3596 pw.println(" screen-compat [on|off] <PACKAGE>"); 3597 pw.println(" Control screen compatibility mode of <PACKAGE>."); 3598 pw.println(" package-importance <PACKAGE>"); 3599 pw.println(" Print current importance of <PACKAGE>."); 3600 pw.println(" to-uri [INTENT]"); 3601 pw.println(" Print the given Intent specification as a URI."); 3602 pw.println(" to-intent-uri [INTENT]"); 3603 pw.println(" Print the given Intent specification as an intent: URI."); 3604 pw.println(" to-app-uri [INTENT]"); 3605 pw.println(" Print the given Intent specification as an android-app: URI."); 3606 pw.println(" switch-user <USER_ID>"); 3607 pw.println(" Switch to put USER_ID in the foreground, starting"); 3608 pw.println(" execution of that user if it is currently stopped."); 3609 pw.println(" get-current-user"); 3610 pw.println(" Returns id of the current foreground user."); 3611 pw.println(" start-user [-w] <USER_ID>"); 3612 pw.println(" Start USER_ID in background if it is currently stopped;"); 3613 pw.println(" use switch-user if you want to start the user in foreground."); 3614 pw.println(" -w: wait for start-user to complete and the user to be unlocked."); 3615 pw.println(" unlock-user <USER_ID>"); 3616 pw.println(" Unlock the given user. This will only work if the user doesn't"); 3617 pw.println(" have an LSKF (PIN/pattern/password)."); 3618 pw.println(" stop-user [-w] [-f] <USER_ID>"); 3619 pw.println(" Stop execution of USER_ID, not allowing it to run any"); 3620 pw.println(" code until a later explicit start or switch to it."); 3621 pw.println(" -w: wait for stop-user to complete."); 3622 pw.println(" -f: force stop even if there are related users that cannot be stopped."); 3623 pw.println(" is-user-stopped <USER_ID>"); 3624 pw.println(" Returns whether <USER_ID> has been stopped or not."); 3625 pw.println(" get-started-user-state <USER_ID>"); 3626 pw.println(" Gets the current state of the given started user."); 3627 pw.println(" track-associations"); 3628 pw.println(" Enable association tracking."); 3629 pw.println(" untrack-associations"); 3630 pw.println(" Disable and clear association tracking."); 3631 pw.println(" get-uid-state <UID>"); 3632 pw.println(" Gets the process state of an app given its <UID>."); 3633 pw.println(" attach-agent <PROCESS> <FILE>"); 3634 pw.println(" Attach an agent to the specified <PROCESS>, which may be either a process name or a PID."); 3635 pw.println(" get-config [--days N] [--device] [--proto] [--display <DISPLAY_ID>]"); 3636 pw.println(" Retrieve the configuration and any recent configurations of the device."); 3637 pw.println(" --days: also return last N days of configurations that have been seen."); 3638 pw.println(" --device: also output global device configuration info."); 3639 pw.println(" --proto: return result as a proto; does not include --days info."); 3640 pw.println(" --display: Specify for which display to run the command; if not "); 3641 pw.println(" specified then run for the default display."); 3642 pw.println(" supports-multiwindow"); 3643 pw.println(" Returns true if the device supports multiwindow."); 3644 pw.println(" supports-split-screen-multi-window"); 3645 pw.println(" Returns true if the device supports split screen multiwindow."); 3646 pw.println(" suppress-resize-config-changes <true|false>"); 3647 pw.println(" Suppresses configuration changes due to user resizing an activity/task."); 3648 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false"); 3649 pw.println(" Sets the inactive state of an app."); 3650 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>"); 3651 pw.println(" Returns the inactive state of an app."); 3652 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare|restricted"); 3653 pw.println(" Puts an app in the standby bucket."); 3654 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>"); 3655 pw.println(" Returns the standby bucket of an app."); 3656 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>"); 3657 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]"); 3658 pw.println(" Send a memory trim event to a <PROCESS>. May also supply a raw trim int level."); 3659 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays."); 3660 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>"); 3661 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>."); 3662 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks."); 3663 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]"); 3664 pw.println(" Move <TASK_ID> from its current stack to the top (true) or"); 3665 pw.println(" bottom (false) of <STACK_ID>."); 3666 pw.println(" list"); 3667 pw.println(" List all of the activity stacks and their sizes."); 3668 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>"); 3669 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>."); 3670 pw.println(" remove <STACK_ID>"); 3671 pw.println(" Remove stack <STACK_ID>."); 3672 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks."); 3673 pw.println(" lock <TASK_ID>"); 3674 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run."); 3675 pw.println(" lock stop"); 3676 pw.println(" End the current task lock."); 3677 pw.println(" resizeable <TASK_ID> [0|1|2|3]"); 3678 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:"); 3679 pw.println(" 0: unresizeable"); 3680 pw.println(" 1: crop_windows"); 3681 pw.println(" 2: resizeable"); 3682 pw.println(" 3: resizeable_and_pipable"); 3683 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>"); 3684 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds."); 3685 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack"); 3686 pw.println(" has the specified bounds."); 3687 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]"); 3688 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>"); 3689 pw.println(" without restarting any processes."); 3690 pw.println(" write"); 3691 pw.println(" Write all pending state to storage."); 3692 pw.println(" compat [COMMAND] [...]: sub-commands for toggling app-compat changes."); 3693 pw.println(" enable|disable [--no-kill] <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>"); 3694 pw.println(" Toggles a change either by id or by name for <PACKAGE_NAME>."); 3695 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect) unless --no-kill is provided."); 3696 pw.println(" reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>"); 3697 pw.println(" Toggles a change either by id or by name for <PACKAGE_NAME>."); 3698 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect)."); 3699 pw.println(" enable-all|disable-all <targetSdkVersion> <PACKAGE_NAME>"); 3700 pw.println(" Toggles all changes that are gated by <targetSdkVersion>."); 3701 pw.println(" reset-all [--no-kill] <PACKAGE_NAME>"); 3702 pw.println(" Removes all existing overrides for all changes for "); 3703 pw.println(" <PACKAGE_NAME> (back to default behaviour)."); 3704 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect) unless --no-kill is provided."); 3705 pw.println(" memory-factor [command] [...]: sub-commands for overriding memory pressure factor"); 3706 pw.println(" set <NORMAL|MODERATE|LOW|CRITICAL>"); 3707 pw.println(" Overrides memory pressure factor. May also supply a raw int level"); 3708 pw.println(" show"); 3709 pw.println(" Shows the existing memory pressure factor"); 3710 pw.println(" reset"); 3711 pw.println(" Removes existing override for memory pressure factor"); 3712 pw.println(" service-restart-backoff <COMMAND> [...]: sub-commands to toggle service restart backoff policy."); 3713 pw.println(" enable|disable <PACKAGE_NAME>"); 3714 pw.println(" Toggles the restart backoff policy on/off for <PACKAGE_NAME>."); 3715 pw.println(" show <PACKAGE_NAME>"); 3716 pw.println(" Shows the restart backoff policy state for <PACKAGE_NAME>."); 3717 pw.println(" get-isolated-pids <UID>"); 3718 pw.println(" Get the PIDs of isolated processes with packages in this <UID>"); 3719 pw.println(" set-stop-user-on-switch [true|false]"); 3720 pw.println(" Sets whether the current user (and its profiles) should be stopped" 3721 + " when switching to a different user."); 3722 pw.println(" Without arguments, it resets to the value defined by platform."); 3723 pw.println(" set-bg-abusive-uids [uid=percentage][,uid=percentage...]"); 3724 pw.println(" Force setting the battery usage of the given UID."); 3725 pw.println(); 3726 Intent.printIntentArgsHelp(pw, ""); 3727 } 3728 } 3729 } 3730