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