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 17package com.android.server.am; 18 19import android.app.ActivityManager; 20import android.app.ActivityOptions; 21import android.app.AppGlobals; 22import android.app.IActivityContainer; 23import android.app.IActivityController; 24import android.app.IActivityManager; 25import android.app.IStopUserCallback; 26import android.app.ProfilerInfo; 27import android.app.WaitResult; 28import android.app.usage.ConfigurationStats; 29import android.app.usage.IUsageStatsManager; 30import android.app.usage.UsageStatsManager; 31import android.content.ComponentCallbacks2; 32import android.content.ComponentName; 33import android.content.Context; 34import android.content.IIntentReceiver; 35import android.content.Intent; 36import android.content.pm.IPackageManager; 37import android.content.pm.ParceledListSlice; 38import android.content.pm.ResolveInfo; 39import android.content.pm.UserInfo; 40import android.content.res.AssetManager; 41import android.content.res.Configuration; 42import android.content.res.Resources; 43import android.graphics.Rect; 44import android.os.Binder; 45import android.os.Build; 46import android.os.Bundle; 47import android.os.ParcelFileDescriptor; 48import android.os.RemoteException; 49import android.os.ServiceManager; 50import android.os.ShellCommand; 51import android.os.SystemClock; 52import android.os.SystemProperties; 53import android.os.UserHandle; 54import android.text.TextUtils; 55import android.util.ArrayMap; 56import android.util.DebugUtils; 57import android.util.DisplayMetrics; 58import android.view.IWindowManager; 59 60import com.android.internal.util.HexDump; 61import com.android.internal.util.Preconditions; 62 63import java.io.BufferedReader; 64import java.io.File; 65import java.io.IOException; 66import java.io.InputStream; 67import java.io.InputStreamReader; 68import java.io.PrintWriter; 69import java.net.URISyntaxException; 70import java.util.ArrayList; 71import java.util.Collections; 72import java.util.Comparator; 73import java.util.List; 74 75import static android.app.ActivityManager.RESIZE_MODE_SYSTEM; 76import static android.app.ActivityManager.RESIZE_MODE_USER; 77import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; 78import static android.app.ActivityManager.StackId.INVALID_STACK_ID; 79import static android.view.Display.INVALID_DISPLAY; 80 81import static com.android.server.am.TaskRecord.INVALID_TASK_ID; 82 83final class ActivityManagerShellCommand extends ShellCommand { 84 public static final String NO_CLASS_ERROR_CODE = "Error type 3"; 85 private static final String SHELL_PACKAGE_NAME = "com.android.shell"; 86 87 // Is the object moving in a positive direction? 88 private static final boolean MOVING_FORWARD = true; 89 // Is the object moving in the horizontal plan? 90 private static final boolean MOVING_HORIZONTALLY = true; 91 // Is the object current point great then its target point? 92 private static final boolean GREATER_THAN_TARGET = true; 93 // Amount we reduce the stack size by when testing a task re-size. 94 private static final int STACK_BOUNDS_INSET = 10; 95 96 // IPC interface to activity manager -- don't need to do additional security checks. 97 final IActivityManager mInterface; 98 99 // Internal service impl -- must perform security checks before touching. 100 final ActivityManagerService mInternal; 101 102 // Convenience for interacting with package manager. 103 final IPackageManager mPm; 104 105 private int mStartFlags = 0; 106 private boolean mWaitOption = false; 107 private boolean mStopOption = false; 108 109 private int mRepeat = 0; 110 private int mUserId; 111 private String mReceiverPermission; 112 113 private String mProfileFile; 114 private int mSamplingInterval; 115 private boolean mAutoStop; 116 private boolean mStreaming; // Streaming the profiling output to a file. 117 private int mDisplayId; 118 private int mStackId; 119 private int mTaskId; 120 private boolean mIsTaskOverlay; 121 122 final boolean mDumping; 123 124 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) { 125 mInterface = service; 126 mInternal = service; 127 mPm = AppGlobals.getPackageManager(); 128 mDumping = dumping; 129 } 130 131 @Override 132 public int onCommand(String cmd) { 133 if (cmd == null) { 134 return handleDefaultCommands(cmd); 135 } 136 PrintWriter pw = getOutPrintWriter(); 137 try { 138 switch (cmd) { 139 case "start": 140 case "start-activity": 141 return runStartActivity(pw); 142 case "startservice": 143 case "start-service": 144 return runStartService(pw, false); 145 case "startforegroundservice": 146 case "startfgservice": 147 case "start-foreground-service": 148 case "start-fg-service": 149 return runStartService(pw, true); 150 case "stopservice": 151 case "stop-service": 152 return runStopService(pw); 153 case "broadcast": 154 return runSendBroadcast(pw); 155 case "instrument": 156 getOutPrintWriter().println("Error: must be invoked through 'am instrument'."); 157 return -1; 158 case "trace-ipc": 159 return runTraceIpc(pw); 160 case "profile": 161 return runProfile(pw); 162 case "dumpheap": 163 return runDumpHeap(pw); 164 case "set-debug-app": 165 return runSetDebugApp(pw); 166 case "clear-debug-app": 167 return runClearDebugApp(pw); 168 case "set-watch-heap": 169 return runSetWatchHeap(pw); 170 case "clear-watch-heap": 171 return runClearWatchHeap(pw); 172 case "bug-report": 173 return runBugReport(pw); 174 case "force-stop": 175 return runForceStop(pw); 176 case "crash": 177 return runCrash(pw); 178 case "kill": 179 return runKill(pw); 180 case "kill-all": 181 return runKillAll(pw); 182 case "make-uid-idle": 183 return runMakeIdle(pw); 184 case "monitor": 185 return runMonitor(pw); 186 case "hang": 187 return runHang(pw); 188 case "restart": 189 return runRestart(pw); 190 case "idle-maintenance": 191 return runIdleMaintenance(pw); 192 case "screen-compat": 193 return runScreenCompat(pw); 194 case "package-importance": 195 return runPackageImportance(pw); 196 case "to-uri": 197 return runToUri(pw, 0); 198 case "to-intent-uri": 199 return runToUri(pw, Intent.URI_INTENT_SCHEME); 200 case "to-app-uri": 201 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME); 202 case "switch-user": 203 return runSwitchUser(pw); 204 case "get-current-user": 205 return runGetCurrentUser(pw); 206 case "start-user": 207 return runStartUser(pw); 208 case "unlock-user": 209 return runUnlockUser(pw); 210 case "stop-user": 211 return runStopUser(pw); 212 case "is-user-stopped": 213 return runIsUserStopped(pw); 214 case "get-started-user-state": 215 return runGetStartedUserState(pw); 216 case "track-associations": 217 return runTrackAssociations(pw); 218 case "untrack-associations": 219 return runUntrackAssociations(pw); 220 case "get-uid-state": 221 return getUidState(pw); 222 case "get-config": 223 return runGetConfig(pw); 224 case "suppress-resize-config-changes": 225 return runSuppressResizeConfigChanges(pw); 226 case "set-inactive": 227 return runSetInactive(pw); 228 case "get-inactive": 229 return runGetInactive(pw); 230 case "send-trim-memory": 231 return runSendTrimMemory(pw); 232 case "display": 233 return runDisplay(pw); 234 case "stack": 235 return runStack(pw); 236 case "task": 237 return runTask(pw); 238 case "write": 239 return runWrite(pw); 240 case "attach-agent": 241 return runAttachAgent(pw); 242 case "supports-multiwindow": 243 return runSupportsMultiwindow(pw); 244 case "supports-split-screen-multi-window": 245 return runSupportsSplitScreenMultiwindow(pw); 246 case "update-appinfo": 247 return runUpdateApplicationInfo(pw); 248 case "no-home-screen": 249 return runNoHomeScreen(pw); 250 case "wait-for-broadcast-idle": 251 return runWaitForBroadcastIdle(pw); 252 default: 253 return handleDefaultCommands(cmd); 254 } 255 } catch (RemoteException e) { 256 pw.println("Remote exception: " + e); 257 } 258 return -1; 259 } 260 261 private Intent makeIntent(int defUser) throws URISyntaxException { 262 mStartFlags = 0; 263 mWaitOption = false; 264 mStopOption = false; 265 mRepeat = 0; 266 mProfileFile = null; 267 mSamplingInterval = 0; 268 mAutoStop = false; 269 mStreaming = false; 270 mUserId = defUser; 271 mDisplayId = INVALID_DISPLAY; 272 mStackId = INVALID_STACK_ID; 273 mTaskId = INVALID_TASK_ID; 274 mIsTaskOverlay = false; 275 276 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { 277 @Override 278 public boolean handleOption(String opt, ShellCommand cmd) { 279 if (opt.equals("-D")) { 280 mStartFlags |= ActivityManager.START_FLAG_DEBUG; 281 } else if (opt.equals("-N")) { 282 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING; 283 } else if (opt.equals("-W")) { 284 mWaitOption = true; 285 } else if (opt.equals("-P")) { 286 mProfileFile = getNextArgRequired(); 287 mAutoStop = true; 288 } else if (opt.equals("--start-profiler")) { 289 mProfileFile = getNextArgRequired(); 290 mAutoStop = false; 291 } else if (opt.equals("--sampling")) { 292 mSamplingInterval = Integer.parseInt(getNextArgRequired()); 293 } else if (opt.equals("--streaming")) { 294 mStreaming = true; 295 } else if (opt.equals("-R")) { 296 mRepeat = Integer.parseInt(getNextArgRequired()); 297 } else if (opt.equals("-S")) { 298 mStopOption = true; 299 } else if (opt.equals("--track-allocation")) { 300 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION; 301 } else if (opt.equals("--user")) { 302 mUserId = UserHandle.parseUserArg(getNextArgRequired()); 303 } else if (opt.equals("--receiver-permission")) { 304 mReceiverPermission = getNextArgRequired(); 305 } else if (opt.equals("--display")) { 306 mDisplayId = Integer.parseInt(getNextArgRequired()); 307 } else if (opt.equals("--stack")) { 308 mStackId = Integer.parseInt(getNextArgRequired()); 309 } else if (opt.equals("--task")) { 310 mTaskId = Integer.parseInt(getNextArgRequired()); 311 } else if (opt.equals("--task-overlay")) { 312 mIsTaskOverlay = true; 313 } else { 314 return false; 315 } 316 return true; 317 } 318 }); 319 } 320 321 int runStartActivity(PrintWriter pw) throws RemoteException { 322 Intent intent; 323 try { 324 intent = makeIntent(UserHandle.USER_CURRENT); 325 } catch (URISyntaxException e) { 326 throw new RuntimeException(e.getMessage(), e); 327 } 328 329 if (mUserId == UserHandle.USER_ALL) { 330 getErrPrintWriter().println("Error: Can't start service with user 'all'"); 331 return 1; 332 } 333 334 String mimeType = intent.getType(); 335 if (mimeType == null && intent.getData() != null 336 && "content".equals(intent.getData().getScheme())) { 337 mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId); 338 } 339 340 do { 341 if (mStopOption) { 342 String packageName; 343 if (intent.getComponent() != null) { 344 packageName = intent.getComponent().getPackageName(); 345 } else { 346 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0, 347 mUserId).getList(); 348 if (activities == null || activities.size() <= 0) { 349 getErrPrintWriter().println("Error: Intent does not match any activities: " 350 + intent); 351 return 1; 352 } else if (activities.size() > 1) { 353 getErrPrintWriter().println( 354 "Error: Intent matches multiple activities; can't stop: " 355 + intent); 356 return 1; 357 } 358 packageName = activities.get(0).activityInfo.packageName; 359 } 360 pw.println("Stopping: " + packageName); 361 pw.flush(); 362 mInterface.forceStopPackage(packageName, mUserId); 363 try { 364 Thread.sleep(250); 365 } catch (InterruptedException e) { 366 } 367 } 368 369 ProfilerInfo profilerInfo = null; 370 371 if (mProfileFile != null) { 372 ParcelFileDescriptor fd = openOutputFileForSystem(mProfileFile); 373 if (fd == null) { 374 return 1; 375 } 376 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, 377 mStreaming); 378 } 379 380 pw.println("Starting: " + intent); 381 pw.flush(); 382 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 383 384 WaitResult result = null; 385 int res; 386 final long startTime = SystemClock.uptimeMillis(); 387 ActivityOptions options = null; 388 if (mDisplayId != INVALID_DISPLAY) { 389 options = ActivityOptions.makeBasic(); 390 options.setLaunchDisplayId(mDisplayId); 391 } 392 if (mStackId != INVALID_STACK_ID) { 393 options = ActivityOptions.makeBasic(); 394 options.setLaunchStackId(mStackId); 395 } 396 if (mTaskId != INVALID_TASK_ID) { 397 options = ActivityOptions.makeBasic(); 398 options.setLaunchTaskId(mTaskId); 399 400 if (mIsTaskOverlay) { 401 options.setTaskOverlay(true, true /* canResume */); 402 } 403 } 404 if (mWaitOption) { 405 result = mInterface.startActivityAndWait(null, null, intent, mimeType, 406 null, null, 0, mStartFlags, profilerInfo, 407 options != null ? options.toBundle() : null, mUserId); 408 res = result.result; 409 } else { 410 res = mInterface.startActivityAsUser(null, null, intent, mimeType, 411 null, null, 0, mStartFlags, profilerInfo, 412 options != null ? options.toBundle() : null, mUserId); 413 } 414 final long endTime = SystemClock.uptimeMillis(); 415 PrintWriter out = mWaitOption ? pw : getErrPrintWriter(); 416 boolean launched = false; 417 switch (res) { 418 case ActivityManager.START_SUCCESS: 419 launched = true; 420 break; 421 case ActivityManager.START_SWITCHES_CANCELED: 422 launched = true; 423 out.println( 424 "Warning: Activity not started because the " 425 + " current activity is being kept for the user."); 426 break; 427 case ActivityManager.START_DELIVERED_TO_TOP: 428 launched = true; 429 out.println( 430 "Warning: Activity not started, intent has " 431 + "been delivered to currently running " 432 + "top-most instance."); 433 break; 434 case ActivityManager.START_RETURN_INTENT_TO_CALLER: 435 launched = true; 436 out.println( 437 "Warning: Activity not started because intent " 438 + "should be handled by the caller"); 439 break; 440 case ActivityManager.START_TASK_TO_FRONT: 441 launched = true; 442 out.println( 443 "Warning: Activity not started, its current " 444 + "task has been brought to the front"); 445 break; 446 case ActivityManager.START_INTENT_NOT_RESOLVED: 447 out.println( 448 "Error: Activity not started, unable to " 449 + "resolve " + intent.toString()); 450 break; 451 case ActivityManager.START_CLASS_NOT_FOUND: 452 out.println(NO_CLASS_ERROR_CODE); 453 out.println("Error: Activity class " + 454 intent.getComponent().toShortString() 455 + " does not exist."); 456 break; 457 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: 458 out.println( 459 "Error: Activity not started, you requested to " 460 + "both forward and receive its result"); 461 break; 462 case ActivityManager.START_PERMISSION_DENIED: 463 out.println( 464 "Error: Activity not started, you do not " 465 + "have permission to access it."); 466 break; 467 case ActivityManager.START_NOT_VOICE_COMPATIBLE: 468 out.println( 469 "Error: Activity not started, voice control not allowed for: " 470 + intent); 471 break; 472 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY: 473 out.println( 474 "Error: Not allowed to start background user activity" 475 + " that shouldn't be displayed for all users."); 476 break; 477 default: 478 out.println( 479 "Error: Activity not started, unknown error code " + res); 480 break; 481 } 482 out.flush(); 483 if (mWaitOption && launched) { 484 if (result == null) { 485 result = new WaitResult(); 486 result.who = intent.getComponent(); 487 } 488 pw.println("Status: " + (result.timeout ? "timeout" : "ok")); 489 if (result.who != null) { 490 pw.println("Activity: " + result.who.flattenToShortString()); 491 } 492 if (result.thisTime >= 0) { 493 pw.println("ThisTime: " + result.thisTime); 494 } 495 if (result.totalTime >= 0) { 496 pw.println("TotalTime: " + result.totalTime); 497 } 498 pw.println("WaitTime: " + (endTime-startTime)); 499 pw.println("Complete"); 500 pw.flush(); 501 } 502 mRepeat--; 503 if (mRepeat > 0) { 504 mInterface.unhandledBack(); 505 } 506 } while (mRepeat > 0); 507 return 0; 508 } 509 510 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException { 511 final PrintWriter err = getErrPrintWriter(); 512 Intent intent; 513 try { 514 intent = makeIntent(UserHandle.USER_CURRENT); 515 } catch (URISyntaxException e) { 516 throw new RuntimeException(e.getMessage(), e); 517 } 518 if (mUserId == UserHandle.USER_ALL) { 519 err.println("Error: Can't start activity with user 'all'"); 520 return -1; 521 } 522 pw.println("Starting service: " + intent); 523 pw.flush(); 524 ComponentName cn = mInterface.startService(null, intent, intent.getType(), 525 asForeground, SHELL_PACKAGE_NAME, mUserId); 526 if (cn == null) { 527 err.println("Error: Not found; no service started."); 528 return -1; 529 } else if (cn.getPackageName().equals("!")) { 530 err.println("Error: Requires permission " + cn.getClassName()); 531 return -1; 532 } else if (cn.getPackageName().equals("!!")) { 533 err.println("Error: " + cn.getClassName()); 534 return -1; 535 } else if (cn.getPackageName().equals("?")) { 536 err.println("Error: " + cn.getClassName()); 537 return -1; 538 } 539 return 0; 540 } 541 542 int runStopService(PrintWriter pw) throws RemoteException { 543 final PrintWriter err = getErrPrintWriter(); 544 Intent intent; 545 try { 546 intent = makeIntent(UserHandle.USER_CURRENT); 547 } catch (URISyntaxException e) { 548 throw new RuntimeException(e.getMessage(), e); 549 } 550 if (mUserId == UserHandle.USER_ALL) { 551 err.println("Error: Can't stop activity with user 'all'"); 552 return -1; 553 } 554 pw.println("Stopping service: " + intent); 555 pw.flush(); 556 int result = mInterface.stopService(null, intent, intent.getType(), mUserId); 557 if (result == 0) { 558 err.println("Service not stopped: was not running."); 559 return -1; 560 } else if (result == 1) { 561 err.println("Service stopped"); 562 return -1; 563 } else if (result == -1) { 564 err.println("Error stopping service"); 565 return -1; 566 } 567 return 0; 568 } 569 570 final static class IntentReceiver extends IIntentReceiver.Stub { 571 private final PrintWriter mPw; 572 private boolean mFinished = false; 573 574 IntentReceiver(PrintWriter pw) { 575 mPw = pw; 576 } 577 578 @Override 579 public void performReceive(Intent intent, int resultCode, String data, Bundle extras, 580 boolean ordered, boolean sticky, int sendingUser) { 581 String line = "Broadcast completed: result=" + resultCode; 582 if (data != null) line = line + ", data=\"" + data + "\""; 583 if (extras != null) line = line + ", extras: " + extras; 584 mPw.println(line); 585 mPw.flush(); 586 synchronized (this) { 587 mFinished = true; 588 notifyAll(); 589 } 590 } 591 592 public synchronized void waitForFinish() { 593 try { 594 while (!mFinished) wait(); 595 } catch (InterruptedException e) { 596 throw new IllegalStateException(e); 597 } 598 } 599 } 600 601 int runSendBroadcast(PrintWriter pw) throws RemoteException { 602 Intent intent; 603 try { 604 intent = makeIntent(UserHandle.USER_CURRENT); 605 } catch (URISyntaxException e) { 606 throw new RuntimeException(e.getMessage(), e); 607 } 608 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL); 609 IntentReceiver receiver = new IntentReceiver(pw); 610 String[] requiredPermissions = mReceiverPermission == null ? null 611 : new String[] {mReceiverPermission}; 612 pw.println("Broadcasting: " + intent); 613 pw.flush(); 614 mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions, 615 android.app.AppOpsManager.OP_NONE, null, true, false, mUserId); 616 receiver.waitForFinish(); 617 return 0; 618 } 619 620 int runTraceIpc(PrintWriter pw) throws RemoteException { 621 String op = getNextArgRequired(); 622 if (op.equals("start")) { 623 return runTraceIpcStart(pw); 624 } else if (op.equals("stop")) { 625 return runTraceIpcStop(pw); 626 } else { 627 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'"); 628 return -1; 629 } 630 } 631 632 int runTraceIpcStart(PrintWriter pw) throws RemoteException { 633 pw.println("Starting IPC tracing."); 634 pw.flush(); 635 mInterface.startBinderTracking(); 636 return 0; 637 } 638 639 int runTraceIpcStop(PrintWriter pw) throws RemoteException { 640 final PrintWriter err = getErrPrintWriter(); 641 String opt; 642 String filename = null; 643 while ((opt=getNextOption()) != null) { 644 if (opt.equals("--dump-file")) { 645 filename = getNextArgRequired(); 646 } else { 647 err.println("Error: Unknown option: " + opt); 648 return -1; 649 } 650 } 651 if (filename == null) { 652 err.println("Error: Specify filename to dump logs to."); 653 return -1; 654 } 655 656 File file = new File(filename); 657 file.delete(); 658 ParcelFileDescriptor fd = openOutputFileForSystem(filename); 659 if (fd == null) { 660 return -1; 661 } 662 663 ; 664 if (!mInterface.stopBinderTrackingAndDump(fd)) { 665 err.println("STOP TRACE FAILED."); 666 return -1; 667 } 668 669 pw.println("Stopped IPC tracing. Dumping logs to: " + filename); 670 return 0; 671 } 672 673 static void removeWallOption() { 674 String props = SystemProperties.get("dalvik.vm.extra-opts"); 675 if (props != null && props.contains("-Xprofile:wallclock")) { 676 props = props.replace("-Xprofile:wallclock", ""); 677 props = props.trim(); 678 SystemProperties.set("dalvik.vm.extra-opts", props); 679 } 680 } 681 682 private int runProfile(PrintWriter pw) throws RemoteException { 683 final PrintWriter err = getErrPrintWriter(); 684 String profileFile = null; 685 boolean start = false; 686 boolean wall = false; 687 int userId = UserHandle.USER_CURRENT; 688 int profileType = 0; 689 mSamplingInterval = 0; 690 mStreaming = false; 691 692 String process = null; 693 694 String cmd = getNextArgRequired(); 695 696 if ("start".equals(cmd)) { 697 start = true; 698 String opt; 699 while ((opt=getNextOption()) != null) { 700 if (opt.equals("--user")) { 701 userId = UserHandle.parseUserArg(getNextArgRequired()); 702 } else if (opt.equals("--wall")) { 703 wall = true; 704 } else if (opt.equals("--streaming")) { 705 mStreaming = true; 706 } else if (opt.equals("--sampling")) { 707 mSamplingInterval = Integer.parseInt(getNextArgRequired()); 708 } else { 709 err.println("Error: Unknown option: " + opt); 710 return -1; 711 } 712 } 713 process = getNextArgRequired(); 714 } else if ("stop".equals(cmd)) { 715 String opt; 716 while ((opt=getNextOption()) != null) { 717 if (opt.equals("--user")) { 718 userId = UserHandle.parseUserArg(getNextArgRequired()); 719 } else { 720 err.println("Error: Unknown option: " + opt); 721 return -1; 722 } 723 } 724 process = getNextArg(); 725 } else { 726 // Compatibility with old syntax: process is specified first. 727 process = cmd; 728 cmd = getNextArgRequired(); 729 if ("start".equals(cmd)) { 730 start = true; 731 } else if (!"stop".equals(cmd)) { 732 throw new IllegalArgumentException("Profile command " + process + " not valid"); 733 } 734 } 735 736 if (userId == UserHandle.USER_ALL) { 737 err.println("Error: Can't profile with user 'all'"); 738 return -1; 739 } 740 741 ParcelFileDescriptor fd = null; 742 ProfilerInfo profilerInfo = null; 743 744 if (start) { 745 profileFile = getNextArgRequired(); 746 fd = openOutputFileForSystem(profileFile); 747 if (fd == null) { 748 return -1; 749 } 750 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming); 751 } 752 753 try { 754 if (wall) { 755 // XXX doesn't work -- this needs to be set before booting. 756 String props = SystemProperties.get("dalvik.vm.extra-opts"); 757 if (props == null || !props.contains("-Xprofile:wallclock")) { 758 props = props + " -Xprofile:wallclock"; 759 //SystemProperties.set("dalvik.vm.extra-opts", props); 760 } 761 } else if (start) { 762 //removeWallOption(); 763 } 764 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) { 765 wall = false; 766 err.println("PROFILE FAILED on process " + process); 767 return -1; 768 } 769 } finally { 770 if (!wall) { 771 //removeWallOption(); 772 } 773 } 774 return 0; 775 } 776 777 int runDumpHeap(PrintWriter pw) throws RemoteException { 778 final PrintWriter err = getErrPrintWriter(); 779 boolean managed = true; 780 int userId = UserHandle.USER_CURRENT; 781 782 String opt; 783 while ((opt=getNextOption()) != null) { 784 if (opt.equals("--user")) { 785 userId = UserHandle.parseUserArg(getNextArgRequired()); 786 if (userId == UserHandle.USER_ALL) { 787 err.println("Error: Can't dump heap with user 'all'"); 788 return -1; 789 } 790 } else if (opt.equals("-n")) { 791 managed = false; 792 } else { 793 err.println("Error: Unknown option: " + opt); 794 return -1; 795 } 796 } 797 String process = getNextArgRequired(); 798 String heapFile = getNextArgRequired(); 799 800 File file = new File(heapFile); 801 file.delete(); 802 ParcelFileDescriptor fd = openOutputFileForSystem(heapFile); 803 if (fd == null) { 804 return -1; 805 } 806 807 if (!mInterface.dumpHeap(process, userId, managed, heapFile, fd)) { 808 err.println("HEAP DUMP FAILED on process " + process); 809 return -1; 810 } 811 return 0; 812 } 813 814 int runSetDebugApp(PrintWriter pw) throws RemoteException { 815 boolean wait = false; 816 boolean persistent = false; 817 818 String opt; 819 while ((opt=getNextOption()) != null) { 820 if (opt.equals("-w")) { 821 wait = true; 822 } else if (opt.equals("--persistent")) { 823 persistent = true; 824 } else { 825 getErrPrintWriter().println("Error: Unknown option: " + opt); 826 return -1; 827 } 828 } 829 830 String pkg = getNextArgRequired(); 831 mInterface.setDebugApp(pkg, wait, persistent); 832 return 0; 833 } 834 835 int runClearDebugApp(PrintWriter pw) throws RemoteException { 836 mInterface.setDebugApp(null, false, true); 837 return 0; 838 } 839 840 int runSetWatchHeap(PrintWriter pw) throws RemoteException { 841 String proc = getNextArgRequired(); 842 String limit = getNextArgRequired(); 843 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null); 844 return 0; 845 } 846 847 int runClearWatchHeap(PrintWriter pw) throws RemoteException { 848 String proc = getNextArgRequired(); 849 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null); 850 return 0; 851 } 852 853 int runBugReport(PrintWriter pw) throws RemoteException { 854 String opt; 855 int bugreportType = ActivityManager.BUGREPORT_OPTION_FULL; 856 while ((opt=getNextOption()) != null) { 857 if (opt.equals("--progress")) { 858 bugreportType = ActivityManager.BUGREPORT_OPTION_INTERACTIVE; 859 } else if (opt.equals("--telephony")) { 860 bugreportType = ActivityManager.BUGREPORT_OPTION_TELEPHONY; 861 } else { 862 getErrPrintWriter().println("Error: Unknown option: " + opt); 863 return -1; 864 } 865 } 866 mInterface.requestBugReport(bugreportType); 867 pw.println("Your lovely bug report is being created; please be patient."); 868 return 0; 869 } 870 871 int runForceStop(PrintWriter pw) throws RemoteException { 872 int userId = UserHandle.USER_ALL; 873 874 String opt; 875 while ((opt = getNextOption()) != null) { 876 if (opt.equals("--user")) { 877 userId = UserHandle.parseUserArg(getNextArgRequired()); 878 } else { 879 getErrPrintWriter().println("Error: Unknown option: " + opt); 880 return -1; 881 } 882 } 883 mInterface.forceStopPackage(getNextArgRequired(), userId); 884 return 0; 885 } 886 887 int runCrash(PrintWriter pw) throws RemoteException { 888 int userId = UserHandle.USER_ALL; 889 890 String opt; 891 while ((opt=getNextOption()) != null) { 892 if (opt.equals("--user")) { 893 userId = UserHandle.parseUserArg(getNextArgRequired()); 894 } else { 895 getErrPrintWriter().println("Error: Unknown option: " + opt); 896 return -1; 897 } 898 } 899 900 int pid = -1; 901 String packageName = null; 902 final String arg = getNextArgRequired(); 903 // The argument is either a pid or a package name 904 try { 905 pid = Integer.parseInt(arg); 906 } catch (NumberFormatException e) { 907 packageName = arg; 908 } 909 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash"); 910 return 0; 911 } 912 913 int runKill(PrintWriter pw) throws RemoteException { 914 int userId = UserHandle.USER_ALL; 915 916 String opt; 917 while ((opt=getNextOption()) != null) { 918 if (opt.equals("--user")) { 919 userId = UserHandle.parseUserArg(getNextArgRequired()); 920 } else { 921 getErrPrintWriter().println("Error: Unknown option: " + opt); 922 return -1; 923 } 924 } 925 mInterface.killBackgroundProcesses(getNextArgRequired(), userId); 926 return 0; 927 } 928 929 int runKillAll(PrintWriter pw) throws RemoteException { 930 mInterface.killAllBackgroundProcesses(); 931 return 0; 932 } 933 934 int runMakeIdle(PrintWriter pw) throws RemoteException { 935 int userId = UserHandle.USER_ALL; 936 937 String opt; 938 while ((opt = getNextOption()) != null) { 939 if (opt.equals("--user")) { 940 userId = UserHandle.parseUserArg(getNextArgRequired()); 941 } else { 942 getErrPrintWriter().println("Error: Unknown option: " + opt); 943 return -1; 944 } 945 } 946 mInterface.makePackageIdle(getNextArgRequired(), userId); 947 return 0; 948 } 949 950 static final class MyActivityController extends IActivityController.Stub { 951 final IActivityManager mInterface; 952 final PrintWriter mPw; 953 final InputStream mInput; 954 final String mGdbPort; 955 final boolean mMonkey; 956 957 static final int STATE_NORMAL = 0; 958 static final int STATE_CRASHED = 1; 959 static final int STATE_EARLY_ANR = 2; 960 static final int STATE_ANR = 3; 961 962 int mState; 963 964 static final int RESULT_DEFAULT = 0; 965 966 static final int RESULT_CRASH_DIALOG = 0; 967 static final int RESULT_CRASH_KILL = 1; 968 969 static final int RESULT_EARLY_ANR_CONTINUE = 0; 970 static final int RESULT_EARLY_ANR_KILL = 1; 971 972 static final int RESULT_ANR_DIALOG = 0; 973 static final int RESULT_ANR_KILL = 1; 974 static final int RESULT_ANR_WAIT = 1; 975 976 int mResult; 977 978 Process mGdbProcess; 979 Thread mGdbThread; 980 boolean mGotGdbPrint; 981 982 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input, 983 String gdbPort, boolean monkey) { 984 mInterface = iam; 985 mPw = pw; 986 mInput = input; 987 mGdbPort = gdbPort; 988 mMonkey = monkey; 989 } 990 991 @Override 992 public boolean activityResuming(String pkg) { 993 synchronized (this) { 994 mPw.println("** Activity resuming: " + pkg); 995 mPw.flush(); 996 } 997 return true; 998 } 999 1000 @Override 1001 public boolean activityStarting(Intent intent, String pkg) { 1002 synchronized (this) { 1003 mPw.println("** Activity starting: " + pkg); 1004 mPw.flush(); 1005 } 1006 return true; 1007 } 1008 1009 @Override 1010 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg, 1011 long timeMillis, String stackTrace) { 1012 synchronized (this) { 1013 mPw.println("** ERROR: PROCESS CRASHED"); 1014 mPw.println("processName: " + processName); 1015 mPw.println("processPid: " + pid); 1016 mPw.println("shortMsg: " + shortMsg); 1017 mPw.println("longMsg: " + longMsg); 1018 mPw.println("timeMillis: " + timeMillis); 1019 mPw.println("stack:"); 1020 mPw.print(stackTrace); 1021 mPw.println("#"); 1022 mPw.flush(); 1023 int result = waitControllerLocked(pid, STATE_CRASHED); 1024 return result == RESULT_CRASH_KILL ? false : true; 1025 } 1026 } 1027 1028 @Override 1029 public int appEarlyNotResponding(String processName, int pid, String annotation) { 1030 synchronized (this) { 1031 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING"); 1032 mPw.println("processName: " + processName); 1033 mPw.println("processPid: " + pid); 1034 mPw.println("annotation: " + annotation); 1035 mPw.flush(); 1036 int result = waitControllerLocked(pid, STATE_EARLY_ANR); 1037 if (result == RESULT_EARLY_ANR_KILL) return -1; 1038 return 0; 1039 } 1040 } 1041 1042 @Override 1043 public int appNotResponding(String processName, int pid, String processStats) { 1044 synchronized (this) { 1045 mPw.println("** ERROR: PROCESS NOT RESPONDING"); 1046 mPw.println("processName: " + processName); 1047 mPw.println("processPid: " + pid); 1048 mPw.println("processStats:"); 1049 mPw.print(processStats); 1050 mPw.println("#"); 1051 mPw.flush(); 1052 int result = waitControllerLocked(pid, STATE_ANR); 1053 if (result == RESULT_ANR_KILL) return -1; 1054 if (result == RESULT_ANR_WAIT) return 1; 1055 return 0; 1056 } 1057 } 1058 1059 @Override 1060 public int systemNotResponding(String message) { 1061 synchronized (this) { 1062 mPw.println("** ERROR: PROCESS NOT RESPONDING"); 1063 mPw.println("message: " + message); 1064 mPw.println("#"); 1065 mPw.println("Allowing system to die."); 1066 mPw.flush(); 1067 return -1; 1068 } 1069 } 1070 1071 void killGdbLocked() { 1072 mGotGdbPrint = false; 1073 if (mGdbProcess != null) { 1074 mPw.println("Stopping gdbserver"); 1075 mPw.flush(); 1076 mGdbProcess.destroy(); 1077 mGdbProcess = null; 1078 } 1079 if (mGdbThread != null) { 1080 mGdbThread.interrupt(); 1081 mGdbThread = null; 1082 } 1083 } 1084 1085 int waitControllerLocked(int pid, int state) { 1086 if (mGdbPort != null) { 1087 killGdbLocked(); 1088 1089 try { 1090 mPw.println("Starting gdbserver on port " + mGdbPort); 1091 mPw.println("Do the following:"); 1092 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort); 1093 mPw.println(" gdbclient app_process :" + mGdbPort); 1094 mPw.flush(); 1095 1096 mGdbProcess = Runtime.getRuntime().exec(new String[] { 1097 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid) 1098 }); 1099 final InputStreamReader converter = new InputStreamReader( 1100 mGdbProcess.getInputStream()); 1101 mGdbThread = new Thread() { 1102 @Override 1103 public void run() { 1104 BufferedReader in = new BufferedReader(converter); 1105 String line; 1106 int count = 0; 1107 while (true) { 1108 synchronized (MyActivityController.this) { 1109 if (mGdbThread == null) { 1110 return; 1111 } 1112 if (count == 2) { 1113 mGotGdbPrint = true; 1114 MyActivityController.this.notifyAll(); 1115 } 1116 } 1117 try { 1118 line = in.readLine(); 1119 if (line == null) { 1120 return; 1121 } 1122 mPw.println("GDB: " + line); 1123 mPw.flush(); 1124 count++; 1125 } catch (IOException e) { 1126 return; 1127 } 1128 } 1129 } 1130 }; 1131 mGdbThread.start(); 1132 1133 // Stupid waiting for .5s. Doesn't matter if we end early. 1134 try { 1135 this.wait(500); 1136 } catch (InterruptedException e) { 1137 } 1138 1139 } catch (IOException e) { 1140 mPw.println("Failure starting gdbserver: " + e); 1141 mPw.flush(); 1142 killGdbLocked(); 1143 } 1144 } 1145 mState = state; 1146 mPw.println(""); 1147 printMessageForState(); 1148 mPw.flush(); 1149 1150 while (mState != STATE_NORMAL) { 1151 try { 1152 wait(); 1153 } catch (InterruptedException e) { 1154 } 1155 } 1156 1157 killGdbLocked(); 1158 1159 return mResult; 1160 } 1161 1162 void resumeController(int result) { 1163 synchronized (this) { 1164 mState = STATE_NORMAL; 1165 mResult = result; 1166 notifyAll(); 1167 } 1168 } 1169 1170 void printMessageForState() { 1171 switch (mState) { 1172 case STATE_NORMAL: 1173 mPw.println("Monitoring activity manager... available commands:"); 1174 break; 1175 case STATE_CRASHED: 1176 mPw.println("Waiting after crash... available commands:"); 1177 mPw.println("(c)ontinue: show crash dialog"); 1178 mPw.println("(k)ill: immediately kill app"); 1179 break; 1180 case STATE_EARLY_ANR: 1181 mPw.println("Waiting after early ANR... available commands:"); 1182 mPw.println("(c)ontinue: standard ANR processing"); 1183 mPw.println("(k)ill: immediately kill app"); 1184 break; 1185 case STATE_ANR: 1186 mPw.println("Waiting after ANR... available commands:"); 1187 mPw.println("(c)ontinue: show ANR dialog"); 1188 mPw.println("(k)ill: immediately kill app"); 1189 mPw.println("(w)ait: wait some more"); 1190 break; 1191 } 1192 mPw.println("(q)uit: finish monitoring"); 1193 } 1194 1195 void run() throws RemoteException { 1196 try { 1197 printMessageForState(); 1198 mPw.flush(); 1199 1200 mInterface.setActivityController(this, mMonkey); 1201 mState = STATE_NORMAL; 1202 1203 InputStreamReader converter = new InputStreamReader(mInput); 1204 BufferedReader in = new BufferedReader(converter); 1205 String line; 1206 1207 while ((line = in.readLine()) != null) { 1208 boolean addNewline = true; 1209 if (line.length() <= 0) { 1210 addNewline = false; 1211 } else if ("q".equals(line) || "quit".equals(line)) { 1212 resumeController(RESULT_DEFAULT); 1213 break; 1214 } else if (mState == STATE_CRASHED) { 1215 if ("c".equals(line) || "continue".equals(line)) { 1216 resumeController(RESULT_CRASH_DIALOG); 1217 } else if ("k".equals(line) || "kill".equals(line)) { 1218 resumeController(RESULT_CRASH_KILL); 1219 } else { 1220 mPw.println("Invalid command: " + line); 1221 } 1222 } else if (mState == STATE_ANR) { 1223 if ("c".equals(line) || "continue".equals(line)) { 1224 resumeController(RESULT_ANR_DIALOG); 1225 } else if ("k".equals(line) || "kill".equals(line)) { 1226 resumeController(RESULT_ANR_KILL); 1227 } else if ("w".equals(line) || "wait".equals(line)) { 1228 resumeController(RESULT_ANR_WAIT); 1229 } else { 1230 mPw.println("Invalid command: " + line); 1231 } 1232 } else if (mState == STATE_EARLY_ANR) { 1233 if ("c".equals(line) || "continue".equals(line)) { 1234 resumeController(RESULT_EARLY_ANR_CONTINUE); 1235 } else if ("k".equals(line) || "kill".equals(line)) { 1236 resumeController(RESULT_EARLY_ANR_KILL); 1237 } else { 1238 mPw.println("Invalid command: " + line); 1239 } 1240 } else { 1241 mPw.println("Invalid command: " + line); 1242 } 1243 1244 synchronized (this) { 1245 if (addNewline) { 1246 mPw.println(""); 1247 } 1248 printMessageForState(); 1249 mPw.flush(); 1250 } 1251 } 1252 1253 } catch (IOException e) { 1254 e.printStackTrace(mPw); 1255 mPw.flush(); 1256 } finally { 1257 mInterface.setActivityController(null, mMonkey); 1258 } 1259 } 1260 } 1261 1262 int runMonitor(PrintWriter pw) throws RemoteException { 1263 String opt; 1264 String gdbPort = null; 1265 boolean monkey = false; 1266 while ((opt=getNextOption()) != null) { 1267 if (opt.equals("--gdb")) { 1268 gdbPort = getNextArgRequired(); 1269 } else if (opt.equals("-m")) { 1270 monkey = true; 1271 } else { 1272 getErrPrintWriter().println("Error: Unknown option: " + opt); 1273 return -1; 1274 } 1275 } 1276 1277 MyActivityController controller = new MyActivityController(mInterface, pw, 1278 getRawInputStream(), gdbPort, monkey); 1279 controller.run(); 1280 return 0; 1281 } 1282 1283 int runHang(PrintWriter pw) throws RemoteException { 1284 String opt; 1285 boolean allowRestart = false; 1286 while ((opt=getNextOption()) != null) { 1287 if (opt.equals("--allow-restart")) { 1288 allowRestart = true; 1289 } else { 1290 getErrPrintWriter().println("Error: Unknown option: " + opt); 1291 return -1; 1292 } 1293 } 1294 1295 pw.println("Hanging the system..."); 1296 pw.flush(); 1297 mInterface.hang(new Binder(), allowRestart); 1298 return 0; 1299 } 1300 1301 int runRestart(PrintWriter pw) throws RemoteException { 1302 String opt; 1303 while ((opt=getNextOption()) != null) { 1304 getErrPrintWriter().println("Error: Unknown option: " + opt); 1305 return -1; 1306 } 1307 1308 pw.println("Restart the system..."); 1309 pw.flush(); 1310 mInterface.restart(); 1311 return 0; 1312 } 1313 1314 int runIdleMaintenance(PrintWriter pw) throws RemoteException { 1315 String opt; 1316 while ((opt=getNextOption()) != null) { 1317 getErrPrintWriter().println("Error: Unknown option: " + opt); 1318 return -1; 1319 } 1320 1321 pw.println("Performing idle maintenance..."); 1322 mInterface.sendIdleJobTrigger(); 1323 return 0; 1324 } 1325 1326 int runScreenCompat(PrintWriter pw) throws RemoteException { 1327 String mode = getNextArgRequired(); 1328 boolean enabled; 1329 if ("on".equals(mode)) { 1330 enabled = true; 1331 } else if ("off".equals(mode)) { 1332 enabled = false; 1333 } else { 1334 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode); 1335 return -1; 1336 } 1337 1338 String packageName = getNextArgRequired(); 1339 do { 1340 try { 1341 mInterface.setPackageScreenCompatMode(packageName, enabled 1342 ? ActivityManager.COMPAT_MODE_ENABLED 1343 : ActivityManager.COMPAT_MODE_DISABLED); 1344 } catch (RemoteException e) { 1345 } 1346 packageName = getNextArg(); 1347 } while (packageName != null); 1348 return 0; 1349 } 1350 1351 int runPackageImportance(PrintWriter pw) throws RemoteException { 1352 String packageName = getNextArgRequired(); 1353 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell"); 1354 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState)); 1355 return 0; 1356 } 1357 1358 int runToUri(PrintWriter pw, int flags) throws RemoteException { 1359 Intent intent; 1360 try { 1361 intent = makeIntent(UserHandle.USER_CURRENT); 1362 } catch (URISyntaxException e) { 1363 throw new RuntimeException(e.getMessage(), e); 1364 } 1365 pw.println(intent.toUri(flags)); 1366 return 0; 1367 } 1368 1369 int runSwitchUser(PrintWriter pw) throws RemoteException { 1370 String user = getNextArgRequired(); 1371 mInterface.switchUser(Integer.parseInt(user)); 1372 return 0; 1373 } 1374 1375 int runGetCurrentUser(PrintWriter pw) throws RemoteException { 1376 UserInfo currentUser = Preconditions.checkNotNull(mInterface.getCurrentUser(), 1377 "Current user not set"); 1378 pw.println(currentUser.id); 1379 return 0; 1380 } 1381 1382 int runStartUser(PrintWriter pw) throws RemoteException { 1383 String user = getNextArgRequired(); 1384 boolean success = mInterface.startUserInBackground(Integer.parseInt(user)); 1385 if (success) { 1386 pw.println("Success: user started"); 1387 } else { 1388 getErrPrintWriter().println("Error: could not start user"); 1389 } 1390 return 0; 1391 } 1392 1393 private static byte[] argToBytes(String arg) { 1394 if (arg.equals("!")) { 1395 return null; 1396 } else { 1397 return HexDump.hexStringToByteArray(arg); 1398 } 1399 } 1400 1401 int runUnlockUser(PrintWriter pw) throws RemoteException { 1402 int userId = Integer.parseInt(getNextArgRequired()); 1403 byte[] token = argToBytes(getNextArgRequired()); 1404 byte[] secret = argToBytes(getNextArgRequired()); 1405 boolean success = mInterface.unlockUser(userId, token, secret, null); 1406 if (success) { 1407 pw.println("Success: user unlocked"); 1408 } else { 1409 getErrPrintWriter().println("Error: could not unlock user"); 1410 } 1411 return 0; 1412 } 1413 1414 static final class StopUserCallback extends IStopUserCallback.Stub { 1415 private boolean mFinished = false; 1416 1417 public synchronized void waitForFinish() { 1418 try { 1419 while (!mFinished) wait(); 1420 } catch (InterruptedException e) { 1421 throw new IllegalStateException(e); 1422 } 1423 } 1424 1425 @Override 1426 public synchronized void userStopped(int userId) { 1427 mFinished = true; 1428 notifyAll(); 1429 } 1430 1431 @Override 1432 public synchronized void userStopAborted(int userId) { 1433 mFinished = true; 1434 notifyAll(); 1435 } 1436 } 1437 1438 int runStopUser(PrintWriter pw) throws RemoteException { 1439 boolean wait = false; 1440 boolean force = false; 1441 String opt; 1442 while ((opt = getNextOption()) != null) { 1443 if ("-w".equals(opt)) { 1444 wait = true; 1445 } else if ("-f".equals(opt)) { 1446 force = true; 1447 } else { 1448 getErrPrintWriter().println("Error: unknown option: " + opt); 1449 return -1; 1450 } 1451 } 1452 int user = Integer.parseInt(getNextArgRequired()); 1453 StopUserCallback callback = wait ? new StopUserCallback() : null; 1454 1455 int res = mInterface.stopUser(user, force, callback); 1456 if (res != ActivityManager.USER_OP_SUCCESS) { 1457 String txt = ""; 1458 switch (res) { 1459 case ActivityManager.USER_OP_IS_CURRENT: 1460 txt = " (Can't stop current user)"; 1461 break; 1462 case ActivityManager.USER_OP_UNKNOWN_USER: 1463 txt = " (Unknown user " + user + ")"; 1464 break; 1465 case ActivityManager.USER_OP_ERROR_IS_SYSTEM: 1466 txt = " (System user cannot be stopped)"; 1467 break; 1468 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP: 1469 txt = " (Can't stop user " + user 1470 + " - one of its related users can't be stopped)"; 1471 break; 1472 } 1473 getErrPrintWriter().println("Switch failed: " + res + txt); 1474 return -1; 1475 } else if (callback != null) { 1476 callback.waitForFinish(); 1477 } 1478 return 0; 1479 } 1480 1481 int runIsUserStopped(PrintWriter pw) { 1482 int userId = UserHandle.parseUserArg(getNextArgRequired()); 1483 boolean stopped = mInternal.isUserStopped(userId); 1484 pw.println(stopped); 1485 return 0; 1486 } 1487 1488 int runGetStartedUserState(PrintWriter pw) throws RemoteException { 1489 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP, 1490 "runGetStartedUserState()"); 1491 final int userId = Integer.parseInt(getNextArgRequired()); 1492 try { 1493 pw.println(mInternal.getStartedUserState(userId)); 1494 } catch (NullPointerException e) { 1495 pw.println("User is not started: " + userId); 1496 } 1497 return 0; 1498 } 1499 1500 int runTrackAssociations(PrintWriter pw) { 1501 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 1502 "registerUidObserver()"); 1503 synchronized (mInternal) { 1504 if (!mInternal.mTrackingAssociations) { 1505 mInternal.mTrackingAssociations = true; 1506 pw.println("Association tracking started."); 1507 } else { 1508 pw.println("Association tracking already enabled."); 1509 } 1510 } 1511 return 0; 1512 } 1513 1514 int runUntrackAssociations(PrintWriter pw) { 1515 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 1516 "registerUidObserver()"); 1517 synchronized (mInternal) { 1518 if (mInternal.mTrackingAssociations) { 1519 mInternal.mTrackingAssociations = false; 1520 mInternal.mAssociations.clear(); 1521 pw.println("Association tracking stopped."); 1522 } else { 1523 pw.println("Association tracking not running."); 1524 } 1525 } 1526 return 0; 1527 } 1528 1529 int getUidState(PrintWriter pw) throws RemoteException { 1530 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP, 1531 "getUidState()"); 1532 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired())); 1533 pw.print(state); 1534 pw.print(" ("); 1535 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state)); 1536 pw.println(")"); 1537 return 0; 1538 } 1539 1540 private List<Configuration> getRecentConfigurations(int days) { 1541 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 1542 Context.USAGE_STATS_SERVICE)); 1543 final long now = System.currentTimeMillis(); 1544 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000); 1545 try { 1546 @SuppressWarnings("unchecked") 1547 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats( 1548 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell"); 1549 if (configStatsSlice == null) { 1550 return Collections.emptyList(); 1551 } 1552 1553 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>(); 1554 final List<ConfigurationStats> configStatsList = configStatsSlice.getList(); 1555 final int configStatsListSize = configStatsList.size(); 1556 for (int i = 0; i < configStatsListSize; i++) { 1557 final ConfigurationStats stats = configStatsList.get(i); 1558 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration()); 1559 if (indexOfKey < 0) { 1560 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount()); 1561 } else { 1562 recentConfigs.setValueAt(indexOfKey, 1563 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount()); 1564 } 1565 } 1566 1567 final Comparator<Configuration> comparator = new Comparator<Configuration>() { 1568 @Override 1569 public int compare(Configuration a, Configuration b) { 1570 return recentConfigs.get(b).compareTo(recentConfigs.get(a)); 1571 } 1572 }; 1573 1574 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size()); 1575 configs.addAll(recentConfigs.keySet()); 1576 Collections.sort(configs, comparator); 1577 return configs; 1578 1579 } catch (RemoteException e) { 1580 return Collections.emptyList(); 1581 } 1582 } 1583 1584 int runGetConfig(PrintWriter pw) throws RemoteException { 1585 int days = 14; 1586 String option = getNextOption(); 1587 if (option != null) { 1588 if (!option.equals("--days")) { 1589 throw new IllegalArgumentException("unrecognized option " + option); 1590 } 1591 1592 days = Integer.parseInt(getNextArgRequired()); 1593 if (days <= 0) { 1594 throw new IllegalArgumentException("--days must be a positive integer"); 1595 } 1596 } 1597 1598 Configuration config = mInterface.getConfiguration(); 1599 if (config == null) { 1600 getErrPrintWriter().println("Activity manager has no configuration"); 1601 return -1; 1602 } 1603 1604 pw.println("config: " + Configuration.resourceQualifierString(config)); 1605 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS)); 1606 1607 final List<Configuration> recentConfigs = getRecentConfigurations(days); 1608 final int recentConfigSize = recentConfigs.size(); 1609 if (recentConfigSize > 0) { 1610 pw.println("recentConfigs:"); 1611 } 1612 1613 for (int i = 0; i < recentConfigSize; i++) { 1614 pw.println(" config: " + Configuration.resourceQualifierString( 1615 recentConfigs.get(i))); 1616 } 1617 return 0; 1618 } 1619 1620 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException { 1621 boolean suppress = Boolean.valueOf(getNextArgRequired()); 1622 mInterface.suppressResizeConfigChanges(suppress); 1623 return 0; 1624 } 1625 1626 int runSetInactive(PrintWriter pw) throws RemoteException { 1627 int userId = UserHandle.USER_CURRENT; 1628 1629 String opt; 1630 while ((opt=getNextOption()) != null) { 1631 if (opt.equals("--user")) { 1632 userId = UserHandle.parseUserArg(getNextArgRequired()); 1633 } else { 1634 getErrPrintWriter().println("Error: Unknown option: " + opt); 1635 return -1; 1636 } 1637 } 1638 String packageName = getNextArgRequired(); 1639 String value = getNextArgRequired(); 1640 1641 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 1642 Context.USAGE_STATS_SERVICE)); 1643 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId); 1644 return 0; 1645 } 1646 1647 int runGetInactive(PrintWriter pw) throws RemoteException { 1648 int userId = UserHandle.USER_CURRENT; 1649 1650 String opt; 1651 while ((opt=getNextOption()) != null) { 1652 if (opt.equals("--user")) { 1653 userId = UserHandle.parseUserArg(getNextArgRequired()); 1654 } else { 1655 getErrPrintWriter().println("Error: Unknown option: " + opt); 1656 return -1; 1657 } 1658 } 1659 String packageName = getNextArgRequired(); 1660 1661 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService( 1662 Context.USAGE_STATS_SERVICE)); 1663 boolean isIdle = usm.isAppInactive(packageName, userId); 1664 pw.println("Idle=" + isIdle); 1665 return 0; 1666 } 1667 1668 int runSendTrimMemory(PrintWriter pw) throws RemoteException { 1669 int userId = UserHandle.USER_CURRENT; 1670 String opt; 1671 while ((opt = getNextOption()) != null) { 1672 if (opt.equals("--user")) { 1673 userId = UserHandle.parseUserArg(getNextArgRequired()); 1674 if (userId == UserHandle.USER_ALL) { 1675 getErrPrintWriter().println("Error: Can't use user 'all'"); 1676 return -1; 1677 } 1678 } else { 1679 getErrPrintWriter().println("Error: Unknown option: " + opt); 1680 return -1; 1681 } 1682 } 1683 1684 String proc = getNextArgRequired(); 1685 String levelArg = getNextArgRequired(); 1686 int level; 1687 switch (levelArg) { 1688 case "HIDDEN": 1689 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 1690 break; 1691 case "RUNNING_MODERATE": 1692 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 1693 break; 1694 case "BACKGROUND": 1695 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 1696 break; 1697 case "RUNNING_LOW": 1698 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 1699 break; 1700 case "MODERATE": 1701 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 1702 break; 1703 case "RUNNING_CRITICAL": 1704 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 1705 break; 1706 case "COMPLETE": 1707 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 1708 break; 1709 default: 1710 getErrPrintWriter().println("Error: Unknown level option: " + levelArg); 1711 return -1; 1712 } 1713 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) { 1714 getErrPrintWriter().println("Unknown error: failed to set trim level"); 1715 return -1; 1716 } 1717 return 0; 1718 } 1719 1720 int runDisplay(PrintWriter pw) throws RemoteException { 1721 String op = getNextArgRequired(); 1722 switch (op) { 1723 case "move-stack": 1724 return runDisplayMoveStack(pw); 1725 default: 1726 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 1727 return -1; 1728 } 1729 } 1730 1731 int runStack(PrintWriter pw) throws RemoteException { 1732 String op = getNextArgRequired(); 1733 switch (op) { 1734 case "start": 1735 return runStackStart(pw); 1736 case "move-task": 1737 return runStackMoveTask(pw); 1738 case "resize": 1739 return runStackResize(pw); 1740 case "resize-animated": 1741 return runStackResizeAnimated(pw); 1742 case "resize-docked-stack": 1743 return runStackResizeDocked(pw); 1744 case "positiontask": 1745 return runStackPositionTask(pw); 1746 case "list": 1747 return runStackList(pw); 1748 case "info": 1749 return runStackInfo(pw); 1750 case "move-top-activity-to-pinned-stack": 1751 return runMoveTopActivityToPinnedStack(pw); 1752 case "size-docked-stack-test": 1753 return runStackSizeDockedStackTest(pw); 1754 case "remove": 1755 return runStackRemove(pw); 1756 default: 1757 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 1758 return -1; 1759 } 1760 } 1761 1762 1763 private Rect getBounds() { 1764 String leftStr = getNextArgRequired(); 1765 int left = Integer.parseInt(leftStr); 1766 String topStr = getNextArgRequired(); 1767 int top = Integer.parseInt(topStr); 1768 String rightStr = getNextArgRequired(); 1769 int right = Integer.parseInt(rightStr); 1770 String bottomStr = getNextArgRequired(); 1771 int bottom = Integer.parseInt(bottomStr); 1772 if (left < 0) { 1773 getErrPrintWriter().println("Error: bad left arg: " + leftStr); 1774 return null; 1775 } 1776 if (top < 0) { 1777 getErrPrintWriter().println("Error: bad top arg: " + topStr); 1778 return null; 1779 } 1780 if (right <= 0) { 1781 getErrPrintWriter().println("Error: bad right arg: " + rightStr); 1782 return null; 1783 } 1784 if (bottom <= 0) { 1785 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr); 1786 return null; 1787 } 1788 return new Rect(left, top, right, bottom); 1789 } 1790 1791 int runDisplayMoveStack(PrintWriter pw) throws RemoteException { 1792 String stackIdStr = getNextArgRequired(); 1793 int stackId = Integer.parseInt(stackIdStr); 1794 String displayIdStr = getNextArgRequired(); 1795 int displayId = Integer.parseInt(displayIdStr); 1796 mInterface.moveStackToDisplay(stackId, displayId); 1797 return 0; 1798 } 1799 1800 int runStackStart(PrintWriter pw) throws RemoteException { 1801 String displayIdStr = getNextArgRequired(); 1802 int displayId = Integer.parseInt(displayIdStr); 1803 Intent intent; 1804 try { 1805 intent = makeIntent(UserHandle.USER_CURRENT); 1806 } catch (URISyntaxException e) { 1807 throw new RuntimeException(e.getMessage(), e); 1808 } 1809 1810 IActivityContainer container = mInterface.createStackOnDisplay(displayId); 1811 if (container != null) { 1812 container.startActivity(intent); 1813 } 1814 return 0; 1815 } 1816 1817 int runStackMoveTask(PrintWriter pw) throws RemoteException { 1818 String taskIdStr = getNextArgRequired(); 1819 int taskId = Integer.parseInt(taskIdStr); 1820 String stackIdStr = getNextArgRequired(); 1821 int stackId = Integer.parseInt(stackIdStr); 1822 String toTopStr = getNextArgRequired(); 1823 final boolean toTop; 1824 if ("true".equals(toTopStr)) { 1825 toTop = true; 1826 } else if ("false".equals(toTopStr)) { 1827 toTop = false; 1828 } else { 1829 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr); 1830 return -1; 1831 } 1832 1833 mInterface.moveTaskToStack(taskId, stackId, toTop); 1834 return 0; 1835 } 1836 1837 int runStackResize(PrintWriter pw) throws RemoteException { 1838 String stackIdStr = getNextArgRequired(); 1839 int stackId = Integer.parseInt(stackIdStr); 1840 final Rect bounds = getBounds(); 1841 if (bounds == null) { 1842 getErrPrintWriter().println("Error: invalid input bounds"); 1843 return -1; 1844 } 1845 return resizeStack(stackId, bounds, 0); 1846 } 1847 1848 int runStackResizeAnimated(PrintWriter pw) throws RemoteException { 1849 String stackIdStr = getNextArgRequired(); 1850 int stackId = Integer.parseInt(stackIdStr); 1851 final Rect bounds; 1852 if ("null".equals(peekNextArg())) { 1853 bounds = null; 1854 } else { 1855 bounds = getBounds(); 1856 if (bounds == null) { 1857 getErrPrintWriter().println("Error: invalid input bounds"); 1858 return -1; 1859 } 1860 } 1861 return resizeStackUnchecked(stackId, bounds, 0, true); 1862 } 1863 1864 int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate) 1865 throws RemoteException { 1866 try { 1867 mInterface.resizeStack(stackId, bounds, false, false, animate, -1); 1868 Thread.sleep(delayMs); 1869 } catch (InterruptedException e) { 1870 } 1871 return 0; 1872 } 1873 1874 int runStackResizeDocked(PrintWriter pw) throws RemoteException { 1875 final Rect bounds = getBounds(); 1876 final Rect taskBounds = getBounds(); 1877 if (bounds == null || taskBounds == null) { 1878 getErrPrintWriter().println("Error: invalid input bounds"); 1879 return -1; 1880 } 1881 mInterface.resizeDockedStack(bounds, taskBounds, null, null, null); 1882 return 0; 1883 } 1884 1885 int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException { 1886 if (bounds == null) { 1887 getErrPrintWriter().println("Error: invalid input bounds"); 1888 return -1; 1889 } 1890 return resizeStackUnchecked(stackId, bounds, delayMs, false); 1891 } 1892 1893 int runStackPositionTask(PrintWriter pw) throws RemoteException { 1894 String taskIdStr = getNextArgRequired(); 1895 int taskId = Integer.parseInt(taskIdStr); 1896 String stackIdStr = getNextArgRequired(); 1897 int stackId = Integer.parseInt(stackIdStr); 1898 String positionStr = getNextArgRequired(); 1899 int position = Integer.parseInt(positionStr); 1900 1901 mInterface.positionTaskInStack(taskId, stackId, position); 1902 return 0; 1903 } 1904 1905 int runStackList(PrintWriter pw) throws RemoteException { 1906 List<ActivityManager.StackInfo> stacks = mInterface.getAllStackInfos(); 1907 for (ActivityManager.StackInfo info : stacks) { 1908 pw.println(info); 1909 } 1910 return 0; 1911 } 1912 1913 int runStackInfo(PrintWriter pw) throws RemoteException { 1914 String stackIdStr = getNextArgRequired(); 1915 int stackId = Integer.parseInt(stackIdStr); 1916 ActivityManager.StackInfo info = mInterface.getStackInfo(stackId); 1917 pw.println(info); 1918 return 0; 1919 } 1920 1921 int runStackRemove(PrintWriter pw) throws RemoteException { 1922 String stackIdStr = getNextArgRequired(); 1923 int stackId = Integer.parseInt(stackIdStr); 1924 mInterface.removeStack(stackId); 1925 return 0; 1926 } 1927 1928 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException { 1929 int stackId = Integer.parseInt(getNextArgRequired()); 1930 final Rect bounds = getBounds(); 1931 if (bounds == null) { 1932 getErrPrintWriter().println("Error: invalid input bounds"); 1933 return -1; 1934 } 1935 1936 if (!mInterface.moveTopActivityToPinnedStack(stackId, bounds)) { 1937 getErrPrintWriter().println("Didn't move top activity to pinned stack."); 1938 return -1; 1939 } 1940 return 0; 1941 } 1942 1943 int runStackSizeDockedStackTest(PrintWriter pw) throws RemoteException { 1944 final PrintWriter err = getErrPrintWriter(); 1945 final int stepSize = Integer.parseInt(getNextArgRequired()); 1946 final String side = getNextArgRequired(); 1947 final String delayStr = getNextArg(); 1948 final int delayMs = (delayStr != null) ? Integer.parseInt(delayStr) : 0; 1949 1950 ActivityManager.StackInfo info = mInterface.getStackInfo(DOCKED_STACK_ID); 1951 if (info == null) { 1952 err.println("Docked stack doesn't exist"); 1953 return -1; 1954 } 1955 if (info.bounds == null) { 1956 err.println("Docked stack doesn't have a bounds"); 1957 return -1; 1958 } 1959 Rect bounds = info.bounds; 1960 1961 final boolean horizontalGrowth = "l".equals(side) || "r".equals(side); 1962 final int changeSize = (horizontalGrowth ? bounds.width() : bounds.height()) / 2; 1963 int currentPoint; 1964 switch (side) { 1965 case "l": 1966 currentPoint = bounds.left; 1967 break; 1968 case "r": 1969 currentPoint = bounds.right; 1970 break; 1971 case "t": 1972 currentPoint = bounds.top; 1973 break; 1974 case "b": 1975 currentPoint = bounds.bottom; 1976 break; 1977 default: 1978 err.println("Unknown growth side: " + side); 1979 return -1; 1980 } 1981 1982 final int startPoint = currentPoint; 1983 final int minPoint = currentPoint - changeSize; 1984 final int maxPoint = currentPoint + changeSize; 1985 1986 int maxChange; 1987 pw.println("Shrinking docked stack side=" + side); 1988 pw.flush(); 1989 while (currentPoint > minPoint) { 1990 maxChange = Math.min(stepSize, currentPoint - minPoint); 1991 currentPoint -= maxChange; 1992 setBoundsSide(bounds, side, currentPoint); 1993 int res = resizeStack(DOCKED_STACK_ID, bounds, delayMs); 1994 if (res < 0) { 1995 return res; 1996 } 1997 } 1998 1999 pw.println("Growing docked stack side=" + side); 2000 pw.flush(); 2001 while (currentPoint < maxPoint) { 2002 maxChange = Math.min(stepSize, maxPoint - currentPoint); 2003 currentPoint += maxChange; 2004 setBoundsSide(bounds, side, currentPoint); 2005 int res = resizeStack(DOCKED_STACK_ID, bounds, delayMs); 2006 if (res < 0) { 2007 return res; 2008 } 2009 } 2010 2011 pw.println("Back to Original size side=" + side); 2012 pw.flush(); 2013 while (currentPoint > startPoint) { 2014 maxChange = Math.min(stepSize, currentPoint - startPoint); 2015 currentPoint -= maxChange; 2016 setBoundsSide(bounds, side, currentPoint); 2017 int res = resizeStack(DOCKED_STACK_ID, bounds, delayMs); 2018 if (res < 0) { 2019 return res; 2020 } 2021 } 2022 return 0; 2023 } 2024 2025 void setBoundsSide(Rect bounds, String side, int value) { 2026 switch (side) { 2027 case "l": 2028 bounds.left = value; 2029 break; 2030 case "r": 2031 bounds.right = value; 2032 break; 2033 case "t": 2034 bounds.top = value; 2035 break; 2036 case "b": 2037 bounds.bottom = value; 2038 break; 2039 default: 2040 getErrPrintWriter().println("Unknown set side: " + side); 2041 break; 2042 } 2043 } 2044 2045 int runTask(PrintWriter pw) throws RemoteException { 2046 String op = getNextArgRequired(); 2047 if (op.equals("lock")) { 2048 return runTaskLock(pw); 2049 } else if (op.equals("resizeable")) { 2050 return runTaskResizeable(pw); 2051 } else if (op.equals("resize")) { 2052 return runTaskResize(pw); 2053 } else if (op.equals("drag-task-test")) { 2054 return runTaskDragTaskTest(pw); 2055 } else if (op.equals("size-task-test")) { 2056 return runTaskSizeTaskTest(pw); 2057 } else if (op.equals("focus")) { 2058 return runTaskFocus(pw); 2059 } else { 2060 getErrPrintWriter().println("Error: unknown command '" + op + "'"); 2061 return -1; 2062 } 2063 } 2064 2065 int runTaskLock(PrintWriter pw) throws RemoteException { 2066 String taskIdStr = getNextArgRequired(); 2067 if (taskIdStr.equals("stop")) { 2068 mInterface.stopLockTaskMode(); 2069 } else { 2070 int taskId = Integer.parseInt(taskIdStr); 2071 mInterface.startSystemLockTaskMode(taskId); 2072 } 2073 pw.println("Activity manager is " + (mInterface.isInLockTaskMode() ? "" : "not ") + 2074 "in lockTaskMode"); 2075 return 0; 2076 } 2077 2078 int runTaskResizeable(PrintWriter pw) throws RemoteException { 2079 final String taskIdStr = getNextArgRequired(); 2080 final int taskId = Integer.parseInt(taskIdStr); 2081 final String resizeableStr = getNextArgRequired(); 2082 final int resizeableMode = Integer.parseInt(resizeableStr); 2083 mInterface.setTaskResizeable(taskId, resizeableMode); 2084 return 0; 2085 } 2086 2087 int runTaskResize(PrintWriter pw) throws RemoteException { 2088 final String taskIdStr = getNextArgRequired(); 2089 final int taskId = Integer.parseInt(taskIdStr); 2090 final Rect bounds = getBounds(); 2091 if (bounds == null) { 2092 getErrPrintWriter().println("Error: invalid input bounds"); 2093 return -1; 2094 } 2095 taskResize(taskId, bounds, 0, false); 2096 return 0; 2097 } 2098 2099 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize) 2100 throws RemoteException { 2101 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM; 2102 mInterface.resizeTask(taskId, bounds, resizeMode); 2103 try { 2104 Thread.sleep(delay_ms); 2105 } catch (InterruptedException e) { 2106 } 2107 } 2108 2109 int runTaskDragTaskTest(PrintWriter pw) throws RemoteException { 2110 final int taskId = Integer.parseInt(getNextArgRequired()); 2111 final int stepSize = Integer.parseInt(getNextArgRequired()); 2112 final String delayStr = getNextArg(); 2113 final int delay_ms = (delayStr != null) ? Integer.parseInt(delayStr) : 0; 2114 final ActivityManager.StackInfo stackInfo; 2115 Rect taskBounds; 2116 stackInfo = mInterface.getStackInfo(mInterface.getFocusedStackId()); 2117 taskBounds = mInterface.getTaskBounds(taskId); 2118 final Rect stackBounds = stackInfo.bounds; 2119 int travelRight = stackBounds.width() - taskBounds.width(); 2120 int travelLeft = -travelRight; 2121 int travelDown = stackBounds.height() - taskBounds.height(); 2122 int travelUp = -travelDown; 2123 int passes = 0; 2124 2125 // We do 2 passes to get back to the original location of the task. 2126 while (passes < 2) { 2127 // Move right 2128 pw.println("Moving right..."); 2129 pw.flush(); 2130 travelRight = moveTask(taskId, taskBounds, stackBounds, stepSize, 2131 travelRight, MOVING_FORWARD, MOVING_HORIZONTALLY, delay_ms); 2132 pw.println("Still need to travel right by " + travelRight); 2133 2134 // Move down 2135 pw.println("Moving down..."); 2136 pw.flush(); 2137 travelDown = moveTask(taskId, taskBounds, stackBounds, stepSize, 2138 travelDown, MOVING_FORWARD, !MOVING_HORIZONTALLY, delay_ms); 2139 pw.println("Still need to travel down by " + travelDown); 2140 2141 // Move left 2142 pw.println("Moving left..."); 2143 pw.flush(); 2144 travelLeft = moveTask(taskId, taskBounds, stackBounds, stepSize, 2145 travelLeft, !MOVING_FORWARD, MOVING_HORIZONTALLY, delay_ms); 2146 pw.println("Still need to travel left by " + travelLeft); 2147 2148 // Move up 2149 pw.println("Moving up..."); 2150 pw.flush(); 2151 travelUp = moveTask(taskId, taskBounds, stackBounds, stepSize, 2152 travelUp, !MOVING_FORWARD, !MOVING_HORIZONTALLY, delay_ms); 2153 pw.println("Still need to travel up by " + travelUp); 2154 2155 taskBounds = mInterface.getTaskBounds(taskId); 2156 passes++; 2157 } 2158 return 0; 2159 } 2160 2161 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize, 2162 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms) 2163 throws RemoteException { 2164 int maxMove; 2165 if (movingForward) { 2166 while (maxToTravel > 0 2167 && ((horizontal && taskRect.right < stackRect.right) 2168 ||(!horizontal && taskRect.bottom < stackRect.bottom))) { 2169 if (horizontal) { 2170 maxMove = Math.min(stepSize, stackRect.right - taskRect.right); 2171 maxToTravel -= maxMove; 2172 taskRect.right += maxMove; 2173 taskRect.left += maxMove; 2174 } else { 2175 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom); 2176 maxToTravel -= maxMove; 2177 taskRect.top += maxMove; 2178 taskRect.bottom += maxMove; 2179 } 2180 taskResize(taskId, taskRect, delay_ms, false); 2181 } 2182 } else { 2183 while (maxToTravel < 0 2184 && ((horizontal && taskRect.left > stackRect.left) 2185 ||(!horizontal && taskRect.top > stackRect.top))) { 2186 if (horizontal) { 2187 maxMove = Math.min(stepSize, taskRect.left - stackRect.left); 2188 maxToTravel -= maxMove; 2189 taskRect.right -= maxMove; 2190 taskRect.left -= maxMove; 2191 } else { 2192 maxMove = Math.min(stepSize, taskRect.top - stackRect.top); 2193 maxToTravel -= maxMove; 2194 taskRect.top -= maxMove; 2195 taskRect.bottom -= maxMove; 2196 } 2197 taskResize(taskId, taskRect, delay_ms, false); 2198 } 2199 } 2200 // Return the remaining distance we didn't travel because we reached the target location. 2201 return maxToTravel; 2202 } 2203 2204 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) { 2205 int stepSize = 0; 2206 if (greaterThanTarget && target < current) { 2207 current -= inStepSize; 2208 stepSize = inStepSize; 2209 if (target > current) { 2210 stepSize -= (target - current); 2211 } 2212 } 2213 if (!greaterThanTarget && target > current) { 2214 current += inStepSize; 2215 stepSize = inStepSize; 2216 if (target < current) { 2217 stepSize += (current - target); 2218 } 2219 } 2220 return stepSize; 2221 } 2222 2223 int runTaskSizeTaskTest(PrintWriter pw) throws RemoteException { 2224 final int taskId = Integer.parseInt(getNextArgRequired()); 2225 final int stepSize = Integer.parseInt(getNextArgRequired()); 2226 final String delayStr = getNextArg(); 2227 final int delay_ms = (delayStr != null) ? Integer.parseInt(delayStr) : 0; 2228 final ActivityManager.StackInfo stackInfo; 2229 final Rect initialTaskBounds; 2230 stackInfo = mInterface.getStackInfo(mInterface.getFocusedStackId()); 2231 initialTaskBounds = mInterface.getTaskBounds(taskId); 2232 final Rect stackBounds = stackInfo.bounds; 2233 stackBounds.inset(STACK_BOUNDS_INSET, STACK_BOUNDS_INSET); 2234 final Rect currentTaskBounds = new Rect(initialTaskBounds); 2235 2236 // Size by top-left 2237 pw.println("Growing top-left"); 2238 pw.flush(); 2239 do { 2240 currentTaskBounds.top -= getStepSize( 2241 currentTaskBounds.top, stackBounds.top, stepSize, GREATER_THAN_TARGET); 2242 2243 currentTaskBounds.left -= getStepSize( 2244 currentTaskBounds.left, stackBounds.left, stepSize, GREATER_THAN_TARGET); 2245 2246 taskResize(taskId, currentTaskBounds, delay_ms, true); 2247 } while (stackBounds.top < currentTaskBounds.top 2248 || stackBounds.left < currentTaskBounds.left); 2249 2250 // Back to original size 2251 pw.println("Shrinking top-left"); 2252 pw.flush(); 2253 do { 2254 currentTaskBounds.top += getStepSize( 2255 currentTaskBounds.top, initialTaskBounds.top, stepSize, !GREATER_THAN_TARGET); 2256 2257 currentTaskBounds.left += getStepSize( 2258 currentTaskBounds.left, initialTaskBounds.left, stepSize, !GREATER_THAN_TARGET); 2259 2260 taskResize(taskId, currentTaskBounds, delay_ms, true); 2261 } while (initialTaskBounds.top > currentTaskBounds.top 2262 || initialTaskBounds.left > currentTaskBounds.left); 2263 2264 // Size by top-right 2265 pw.println("Growing top-right"); 2266 pw.flush(); 2267 do { 2268 currentTaskBounds.top -= getStepSize( 2269 currentTaskBounds.top, stackBounds.top, stepSize, GREATER_THAN_TARGET); 2270 2271 currentTaskBounds.right += getStepSize( 2272 currentTaskBounds.right, stackBounds.right, stepSize, !GREATER_THAN_TARGET); 2273 2274 taskResize(taskId, currentTaskBounds, delay_ms, true); 2275 } while (stackBounds.top < currentTaskBounds.top 2276 || stackBounds.right > currentTaskBounds.right); 2277 2278 // Back to original size 2279 pw.println("Shrinking top-right"); 2280 pw.flush(); 2281 do { 2282 currentTaskBounds.top += getStepSize( 2283 currentTaskBounds.top, initialTaskBounds.top, stepSize, !GREATER_THAN_TARGET); 2284 2285 currentTaskBounds.right -= getStepSize(currentTaskBounds.right, initialTaskBounds.right, 2286 stepSize, GREATER_THAN_TARGET); 2287 2288 taskResize(taskId, currentTaskBounds, delay_ms, true); 2289 } while (initialTaskBounds.top > currentTaskBounds.top 2290 || initialTaskBounds.right < currentTaskBounds.right); 2291 2292 // Size by bottom-left 2293 pw.println("Growing bottom-left"); 2294 pw.flush(); 2295 do { 2296 currentTaskBounds.bottom += getStepSize( 2297 currentTaskBounds.bottom, stackBounds.bottom, stepSize, !GREATER_THAN_TARGET); 2298 2299 currentTaskBounds.left -= getStepSize( 2300 currentTaskBounds.left, stackBounds.left, stepSize, GREATER_THAN_TARGET); 2301 2302 taskResize(taskId, currentTaskBounds, delay_ms, true); 2303 } while (stackBounds.bottom > currentTaskBounds.bottom 2304 || stackBounds.left < currentTaskBounds.left); 2305 2306 // Back to original size 2307 pw.println("Shrinking bottom-left"); 2308 pw.flush(); 2309 do { 2310 currentTaskBounds.bottom -= getStepSize(currentTaskBounds.bottom, 2311 initialTaskBounds.bottom, stepSize, GREATER_THAN_TARGET); 2312 2313 currentTaskBounds.left += getStepSize( 2314 currentTaskBounds.left, initialTaskBounds.left, stepSize, !GREATER_THAN_TARGET); 2315 2316 taskResize(taskId, currentTaskBounds, delay_ms, true); 2317 } while (initialTaskBounds.bottom < currentTaskBounds.bottom 2318 || initialTaskBounds.left > currentTaskBounds.left); 2319 2320 // Size by bottom-right 2321 pw.println("Growing bottom-right"); 2322 pw.flush(); 2323 do { 2324 currentTaskBounds.bottom += getStepSize( 2325 currentTaskBounds.bottom, stackBounds.bottom, stepSize, !GREATER_THAN_TARGET); 2326 2327 currentTaskBounds.right += getStepSize( 2328 currentTaskBounds.right, stackBounds.right, stepSize, !GREATER_THAN_TARGET); 2329 2330 taskResize(taskId, currentTaskBounds, delay_ms, true); 2331 } while (stackBounds.bottom > currentTaskBounds.bottom 2332 || stackBounds.right > currentTaskBounds.right); 2333 2334 // Back to original size 2335 pw.println("Shrinking bottom-right"); 2336 pw.flush(); 2337 do { 2338 currentTaskBounds.bottom -= getStepSize(currentTaskBounds.bottom, 2339 initialTaskBounds.bottom, stepSize, GREATER_THAN_TARGET); 2340 2341 currentTaskBounds.right -= getStepSize(currentTaskBounds.right, initialTaskBounds.right, 2342 stepSize, GREATER_THAN_TARGET); 2343 2344 taskResize(taskId, currentTaskBounds, delay_ms, true); 2345 } while (initialTaskBounds.bottom < currentTaskBounds.bottom 2346 || initialTaskBounds.right < currentTaskBounds.right); 2347 return 0; 2348 } 2349 2350 int runTaskFocus(PrintWriter pw) throws RemoteException { 2351 final int taskId = Integer.parseInt(getNextArgRequired()); 2352 pw.println("Setting focus to task " + taskId); 2353 mInterface.setFocusedTask(taskId); 2354 return 0; 2355 } 2356 2357 int runWrite(PrintWriter pw) { 2358 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 2359 "registerUidObserver()"); 2360 mInternal.mRecentTasks.flush(); 2361 pw.println("All tasks persisted."); 2362 return 0; 2363 } 2364 2365 int runAttachAgent(PrintWriter pw) { 2366 // TODO: revisit the permissions required for attaching agents 2367 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 2368 "attach-agent"); 2369 String process = getNextArgRequired(); 2370 String agent = getNextArgRequired(); 2371 String opt; 2372 if ((opt = getNextArg()) != null) { 2373 pw.println("Error: Unknown option: " + opt); 2374 return -1; 2375 } 2376 mInternal.attachAgent(process, agent); 2377 return 0; 2378 } 2379 2380 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException { 2381 final Resources res = getResources(pw); 2382 if (res == null) { 2383 return -1; 2384 } 2385 pw.println(ActivityManager.supportsMultiWindow(mInternal.mContext)); 2386 return 0; 2387 } 2388 2389 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException { 2390 final Resources res = getResources(pw); 2391 if (res == null) { 2392 return -1; 2393 } 2394 pw.println(ActivityManager.supportsSplitScreenMultiWindow(mInternal.mContext)); 2395 return 0; 2396 } 2397 2398 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException { 2399 int userid = UserHandle.parseUserArg(getNextArgRequired()); 2400 ArrayList<String> packages = new ArrayList<>(); 2401 packages.add(getNextArgRequired()); 2402 String packageName; 2403 while ((packageName = getNextArg()) != null) { 2404 packages.add(packageName); 2405 } 2406 mInternal.scheduleApplicationInfoChanged(packages, userid); 2407 pw.println("Packages updated with most recent ApplicationInfos."); 2408 return 0; 2409 } 2410 2411 int runNoHomeScreen(PrintWriter pw) throws RemoteException { 2412 final Resources res = getResources(pw); 2413 if (res == null) { 2414 return -1; 2415 } 2416 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen)); 2417 return 0; 2418 } 2419 2420 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException { 2421 mInternal.waitForBroadcastIdle(pw); 2422 return 0; 2423 } 2424 2425 private Resources getResources(PrintWriter pw) throws RemoteException { 2426 // system resources does not contain all the device configuration, construct it manually. 2427 Configuration config = mInterface.getConfiguration(); 2428 if (config == null) { 2429 pw.println("Error: Activity manager has no configuration"); 2430 return null; 2431 } 2432 2433 final DisplayMetrics metrics = new DisplayMetrics(); 2434 metrics.setToDefaults(); 2435 2436 return new Resources(AssetManager.getSystem(), metrics, config); 2437 } 2438 2439 @Override 2440 public void onHelp() { 2441 PrintWriter pw = getOutPrintWriter(); 2442 dumpHelp(pw, mDumping); 2443 } 2444 2445 static void dumpHelp(PrintWriter pw, boolean dumping) { 2446 if (dumping) { 2447 pw.println("Activity manager dump options:"); 2448 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ..."); 2449 pw.println(" WHAT may be one of:"); 2450 pw.println(" a[ctivities]: activity stack state"); 2451 pw.println(" r[recents]: recent activities state"); 2452 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 2453 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics"); 2454 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 2455 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 2456 pw.println(" o[om]: out of memory management"); 2457 pw.println(" perm[issions]: URI permission grant state"); 2458 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 2459 pw.println(" provider [COMP_SPEC]: provider client-side state"); 2460 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 2461 pw.println(" as[sociations]: tracked app associations"); 2462 pw.println(" settings: currently applied config settings"); 2463 pw.println(" service [COMP_SPEC]: service client-side state"); 2464 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 2465 pw.println(" all: dump all activities"); 2466 pw.println(" top: dump the top activity"); 2467 pw.println(" WHAT may also be a COMP_SPEC to dump activities."); 2468 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 2469 pw.println(" a partial substring in a component name, a"); 2470 pw.println(" hex object identifier."); 2471 pw.println(" -a: include all available server state."); 2472 pw.println(" -c: include client state."); 2473 pw.println(" -p: limit output to given package."); 2474 pw.println(" --checkin: output checkin format, resetting data."); 2475 pw.println(" --C: output checkin format, not resetting data."); 2476 } else { 2477 pw.println("Activity manager (activity) commands:"); 2478 pw.println(" help"); 2479 pw.println(" Print this help text."); 2480 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]"); 2481 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]"); 2482 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>"); 2483 pw.println(" Start an Activity. Options are:"); 2484 pw.println(" -D: enable debugging"); 2485 pw.println(" -N: enable native debugging"); 2486 pw.println(" -W: wait for launch to complete"); 2487 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>"); 2488 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds"); 2489 pw.println(" between samples (use with --start-profiler)"); 2490 pw.println(" --streaming: stream the profiling output to the specified file"); 2491 pw.println(" (use with --start-profiler)"); 2492 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle"); 2493 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,"); 2494 pw.println(" the top activity will be finished."); 2495 pw.println(" -S: force stop the target app before starting the activity"); 2496 pw.println(" --track-allocation: enable tracking of object allocations"); 2497 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 2498 pw.println(" specified then run as the current user."); 2499 pw.println(" --stack <STACK_ID>: Specify into which stack should the activity be put."); 2500 pw.println(" start-service [--user <USER_ID> | current] <INTENT>"); 2501 pw.println(" Start a Service. Options are:"); 2502 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 2503 pw.println(" specified then run as the current user."); 2504 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>"); 2505 pw.println(" Start a foreground Service. Options are:"); 2506 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 2507 pw.println(" specified then run as the current user."); 2508 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>"); 2509 pw.println(" Stop a Service. Options are:"); 2510 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not"); 2511 pw.println(" specified then run as the current user."); 2512 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>"); 2513 pw.println(" Send a broadcast Intent. Options are:"); 2514 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not"); 2515 pw.println(" specified then send to all users."); 2516 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission."); 2517 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]"); 2518 pw.println(" [--user <USER_ID> | current]"); 2519 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>"); 2520 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the"); 2521 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there"); 2522 pw.println(" is only one instrumentation. Options are:"); 2523 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with"); 2524 pw.println(" [-e perf true] to generate raw output for performance measurements."); 2525 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a"); 2526 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]]."); 2527 pw.println(" -p <FILE>: write profiling data to <FILE>"); 2528 pw.println(" -m: Write output as protobuf (machine readable)"); 2529 pw.println(" -w: wait for instrumentation to finish before returning. Required for"); 2530 pw.println(" test runners."); 2531 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;"); 2532 pw.println(" current user if not specified."); 2533 pw.println(" --no-window-animation: turn off window animations while running."); 2534 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI."); 2535 pw.println(" This assumes that the process supports the selected ABI."); 2536 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]"); 2537 pw.println(" Trace IPC transactions."); 2538 pw.println(" start: start tracing IPC transactions."); 2539 pw.println(" stop: stop tracing IPC transactions and dump the results to file."); 2540 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to."); 2541 pw.println(" profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]"); 2542 pw.println(" [--streaming] <PROCESS> <FILE>"); 2543 pw.println(" Start and stop profiler on a process. The given <PROCESS> argument"); 2544 pw.println(" may be either a process name or pid. Options are:"); 2545 pw.println(" --user <USER_ID> | current: When supplying a process name,"); 2546 pw.println(" specify user of process to profile; uses current user if not specified."); 2547 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds"); 2548 pw.println(" between samples"); 2549 pw.println(" --streaming: stream the profiling output to the specified file"); 2550 pw.println(" dumpheap [--user <USER_ID> current] [-n] <PROCESS> <FILE>"); 2551 pw.println(" Dump the heap of a process. The given <PROCESS> argument may"); 2552 pw.println(" be either a process name or pid. Options are:"); 2553 pw.println(" -n: dump native heap instead of managed heap"); 2554 pw.println(" --user <USER_ID> | current: When supplying a process name,"); 2555 pw.println(" specify user of process to dump; uses current user if not specified."); 2556 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>"); 2557 pw.println(" Set application <PACKAGE> to debug. Options are:"); 2558 pw.println(" -w: wait for debugger when application starts"); 2559 pw.println(" --persistent: retain this value"); 2560 pw.println(" clear-debug-app"); 2561 pw.println(" Clear the previously set-debug-app."); 2562 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>"); 2563 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or"); 2564 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report."); 2565 pw.println(" clear-watch-heap"); 2566 pw.println(" Clear the previously set-watch-heap."); 2567 pw.println(" bug-report [--progress | --telephony]"); 2568 pw.println(" Request bug report generation; will launch a notification"); 2569 pw.println(" when done to select where it should be delivered. Options are:"); 2570 pw.println(" --progress: will launch a notification right away to show its progress."); 2571 pw.println(" --telephony: will dump only telephony sections."); 2572 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>"); 2573 pw.println(" Completely stop the given application package."); 2574 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>"); 2575 pw.println(" Induce a VM crash in the specified package or process"); 2576 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>"); 2577 pw.println(" Kill all processes associated with the given application."); 2578 pw.println(" kill-all"); 2579 pw.println(" Kill all processes that are safe to kill (cached, etc)."); 2580 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>"); 2581 pw.println(" If the given application's uid is in the background and waiting to"); 2582 pw.println(" become idle (not allowing background services), do that now."); 2583 pw.println(" monitor [--gdb <port>]"); 2584 pw.println(" Start monitoring for crashes or ANRs."); 2585 pw.println(" --gdb: start gdbserv on the given port at crash/ANR"); 2586 pw.println(" hang [--allow-restart]"); 2587 pw.println(" Hang the system."); 2588 pw.println(" --allow-restart: allow watchdog to perform normal system restart"); 2589 pw.println(" restart"); 2590 pw.println(" Restart the user-space system."); 2591 pw.println(" idle-maintenance"); 2592 pw.println(" Perform idle maintenance now."); 2593 pw.println(" screen-compat [on|off] <PACKAGE>"); 2594 pw.println(" Control screen compatibility mode of <PACKAGE>."); 2595 pw.println(" package-importance <PACKAGE>"); 2596 pw.println(" Print current importance of <PACKAGE>."); 2597 pw.println(" to-uri [INTENT]"); 2598 pw.println(" Print the given Intent specification as a URI."); 2599 pw.println(" to-intent-uri [INTENT]"); 2600 pw.println(" Print the given Intent specification as an intent: URI."); 2601 pw.println(" to-app-uri [INTENT]"); 2602 pw.println(" Print the given Intent specification as an android-app: URI."); 2603 pw.println(" switch-user <USER_ID>"); 2604 pw.println(" Switch to put USER_ID in the foreground, starting"); 2605 pw.println(" execution of that user if it is currently stopped."); 2606 pw.println(" get-current-user"); 2607 pw.println(" Returns id of the current foreground user."); 2608 pw.println(" start-user <USER_ID>"); 2609 pw.println(" Start USER_ID in background if it is currently stopped;"); 2610 pw.println(" use switch-user if you want to start the user in foreground"); 2611 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]"); 2612 pw.println(" Attempt to unlock the given user using the given authorization token."); 2613 pw.println(" stop-user [-w] [-f] <USER_ID>"); 2614 pw.println(" Stop execution of USER_ID, not allowing it to run any"); 2615 pw.println(" code until a later explicit start or switch to it."); 2616 pw.println(" -w: wait for stop-user to complete."); 2617 pw.println(" -f: force stop even if there are related users that cannot be stopped."); 2618 pw.println(" is-user-stopped <USER_ID>"); 2619 pw.println(" Returns whether <USER_ID> has been stopped or not."); 2620 pw.println(" get-started-user-state <USER_ID>"); 2621 pw.println(" Gets the current state of the given started user."); 2622 pw.println(" track-associations"); 2623 pw.println(" Enable association tracking."); 2624 pw.println(" untrack-associations"); 2625 pw.println(" Disable and clear association tracking."); 2626 pw.println(" get-uid-state <UID>"); 2627 pw.println(" Gets the process state of an app given its <UID>."); 2628 pw.println(" attach-agent <PROCESS> <FILE>"); 2629 pw.println(" Attach an agent to the specified <PROCESS>, which may be either a process name or a PID."); 2630 pw.println(" get-config"); 2631 pw.println(" Rtrieve the configuration and any recent configurations of the device."); 2632 pw.println(" supports-multiwindow"); 2633 pw.println(" Returns true if the device supports multiwindow."); 2634 pw.println(" supports-split-screen-multi-window"); 2635 pw.println(" Returns true if the device supports split screen multiwindow."); 2636 pw.println(" suppress-resize-config-changes <true|false>"); 2637 pw.println(" Suppresses configuration changes due to user resizing an activity/task."); 2638 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false"); 2639 pw.println(" Sets the inactive state of an app."); 2640 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>"); 2641 pw.println(" Returns the inactive state of an app."); 2642 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>"); 2643 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]"); 2644 pw.println(" Send a memory trim event to a <PROCESS>."); 2645 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays."); 2646 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>"); 2647 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>."); 2648 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks."); 2649 pw.println(" start <DISPLAY_ID> <INTENT>"); 2650 pw.println(" Start a new activity on <DISPLAY_ID> using <INTENT>"); 2651 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]"); 2652 pw.println(" Move <TASK_ID> from its current stack to the top (true) or"); 2653 pw.println(" bottom (false) of <STACK_ID>."); 2654 pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>"); 2655 pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>."); 2656 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>"); 2657 pw.println(" Same as resize, but allow animation."); 2658 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]"); 2659 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>"); 2660 pw.println(" and supplying temporary different task bounds indicated by"); 2661 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>"); 2662 pw.println(" size-docked-stack-test: <STEP_SIZE> <l|t|r|b> [DELAY_MS]"); 2663 pw.println(" Test command for sizing docked stack by"); 2664 pw.println(" <STEP_SIZE> increments from the side <l>eft, <t>op, <r>ight, or <b>ottom"); 2665 pw.println(" applying the optional [DELAY_MS] between each step."); 2666 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>"); 2667 pw.println(" Moves the top activity from"); 2668 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the"); 2669 pw.println(" bounds of the pinned stack."); 2670 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>"); 2671 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>"); 2672 pw.println(" list"); 2673 pw.println(" List all of the activity stacks and their sizes."); 2674 pw.println(" info <STACK_ID>"); 2675 pw.println(" Display the information about activity stack <STACK_ID>."); 2676 pw.println(" remove <STACK_ID>"); 2677 pw.println(" Remove stack <STACK_ID>."); 2678 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks."); 2679 pw.println(" lock <TASK_ID>"); 2680 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run."); 2681 pw.println(" lock stop"); 2682 pw.println(" End the current task lock."); 2683 pw.println(" resizeable <TASK_ID> [0|1|2|3]"); 2684 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:"); 2685 pw.println(" 0: unresizeable"); 2686 pw.println(" 1: crop_windows"); 2687 pw.println(" 2: resizeable"); 2688 pw.println(" 3: resizeable_and_pipable"); 2689 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>"); 2690 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds."); 2691 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack"); 2692 pw.println(" has the specified bounds."); 2693 pw.println(" drag-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]"); 2694 pw.println(" Test command for dragging/moving <TASK_ID> by"); 2695 pw.println(" <STEP_SIZE> increments around the screen applying the optional [DELAY_MS]"); 2696 pw.println(" between each step."); 2697 pw.println(" size-task-test <TASK_ID> <STEP_SIZE> [DELAY_MS]"); 2698 pw.println(" Test command for sizing <TASK_ID> by <STEP_SIZE>"); 2699 pw.println(" increments within the screen applying the optional [DELAY_MS] between"); 2700 pw.println(" each step."); 2701 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]"); 2702 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>"); 2703 pw.println(" without restarting any processes."); 2704 pw.println(" write"); 2705 pw.println(" Write all pending state to storage."); 2706 pw.println(); 2707 Intent.printIntentArgsHelp(pw, ""); 2708 } 2709 } 2710} 2711