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