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