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