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