blob: 07e27bc5c36726f6d8ed8b5a487d1dd9b393c40b [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;
Suprabh Shukla868bde22018-02-20 20:59:52 -080028import android.app.usage.AppStandbyInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070029import android.app.usage.ConfigurationStats;
30import android.app.usage.IUsageStatsManager;
31import android.app.usage.UsageStatsManager;
32import android.content.ComponentCallbacks2;
33import android.content.ComponentName;
34import android.content.Context;
35import android.content.IIntentReceiver;
Dianne Hackborn354736e2016-08-22 17:00:05 -070036import android.content.Intent;
37import android.content.pm.IPackageManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070038import android.content.pm.ParceledListSlice;
Dianne Hackborn354736e2016-08-22 17:00:05 -070039import android.content.pm.ResolveInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070040import android.content.pm.UserInfo;
Michael Kwan94438b72016-11-03 15:30:34 -070041import android.content.res.AssetManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070042import android.content.res.Configuration;
Michael Kwan94438b72016-11-03 15:30:34 -070043import android.content.res.Resources;
Dianne Hackborn331084d2016-10-07 17:57:00 -070044import android.graphics.Rect;
45import android.os.Binder;
46import android.os.Build;
47import android.os.Bundle;
Dianne Hackborn354736e2016-08-22 17:00:05 -070048import android.os.ParcelFileDescriptor;
Dianne Hackborn2e441072015-10-28 18:00:57 -070049import android.os.RemoteException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070050import android.os.ServiceManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -070051import android.os.ShellCommand;
Dianne Hackborn5c3296a2017-12-13 17:52:26 -080052import android.os.StrictMode;
Dianne Hackborn354736e2016-08-22 17:00:05 -070053import android.os.SystemClock;
Dianne Hackborn331084d2016-10-07 17:57:00 -070054import android.os.SystemProperties;
Dianne Hackborn2e441072015-10-28 18:00:57 -070055import android.os.UserHandle;
Dianne Hackborn331084d2016-10-07 17:57:00 -070056import android.text.TextUtils;
57import android.util.ArrayMap;
Felipe Leme2f1b2272016-03-25 16:15:02 -070058import android.util.DebugUtils;
Michael Kwan94438b72016-11-03 15:30:34 -070059import android.util.DisplayMetrics;
Dianne Hackborn2e441072015-10-28 18:00:57 -070060
Dianne Hackborn331084d2016-10-07 17:57:00 -070061import com.android.internal.util.HexDump;
62import com.android.internal.util.Preconditions;
63
64import java.io.BufferedReader;
65import java.io.File;
66import java.io.IOException;
67import java.io.InputStream;
68import java.io.InputStreamReader;
Dianne Hackborn2e441072015-10-28 18:00:57 -070069import java.io.PrintWriter;
Dianne Hackborn354736e2016-08-22 17:00:05 -070070import java.net.URISyntaxException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070071import java.util.ArrayList;
72import java.util.Collections;
73import java.util.Comparator;
Amith Yamasanie8789312017-12-10 14:34:26 -080074import java.util.HashMap;
Dianne Hackborn354736e2016-08-22 17:00:05 -070075import java.util.List;
Amith Yamasanie8789312017-12-10 14:34:26 -080076import java.util.Map;
Dianne Hackborn354736e2016-08-22 17:00:05 -070077
Dianne Hackborn331084d2016-10-07 17:57:00 -070078import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
79import static android.app.ActivityManager.RESIZE_MODE_USER;
Dianne Hackborn354736e2016-08-22 17:00:05 -070080import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070081import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
82import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Andrii Kulian16802aa2016-11-02 12:21:33 -070083import static android.view.Display.INVALID_DISPLAY;
Dianne Hackborn2e441072015-10-28 18:00:57 -070084
Winson Chung6954fc92017-03-24 16:22:12 -070085import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
86
Dianne Hackborn331084d2016-10-07 17:57:00 -070087final class ActivityManagerShellCommand extends ShellCommand {
Dianne Hackborn354736e2016-08-22 17:00:05 -070088 public static final String NO_CLASS_ERROR_CODE = "Error type 3";
Dianne Hackborn331084d2016-10-07 17:57:00 -070089 private static final String SHELL_PACKAGE_NAME = "com.android.shell";
90
Dianne Hackborn2e441072015-10-28 18:00:57 -070091 // IPC interface to activity manager -- don't need to do additional security checks.
92 final IActivityManager mInterface;
93
94 // Internal service impl -- must perform security checks before touching.
95 final ActivityManagerService mInternal;
96
Dianne Hackborn354736e2016-08-22 17:00:05 -070097 // Convenience for interacting with package manager.
98 final IPackageManager mPm;
99
100 private int mStartFlags = 0;
101 private boolean mWaitOption = false;
102 private boolean mStopOption = false;
103
104 private int mRepeat = 0;
105 private int mUserId;
106 private String mReceiverPermission;
107
108 private String mProfileFile;
109 private int mSamplingInterval;
110 private boolean mAutoStop;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800111 private boolean mStreaming; // Streaming the profiling output to a file.
Andreas Gampe83085bb2017-06-26 17:54:11 -0700112 private String mAgent; // Agent to attach on startup.
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800113 private boolean mAttachAgentDuringBind; // Whether agent should be attached late.
Andrii Kulian16802aa2016-11-02 12:21:33 -0700114 private int mDisplayId;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700115 private int mWindowingMode;
116 private int mActivityType;
Winson Chung6954fc92017-03-24 16:22:12 -0700117 private int mTaskId;
118 private boolean mIsTaskOverlay;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000119 private boolean mIsLockTask;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700120
Dianne Hackborn2e441072015-10-28 18:00:57 -0700121 final boolean mDumping;
122
123 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
124 mInterface = service;
125 mInternal = service;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700126 mPm = AppGlobals.getPackageManager();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700127 mDumping = dumping;
128 }
129
130 @Override
131 public int onCommand(String cmd) {
132 if (cmd == null) {
133 return handleDefaultCommands(cmd);
134 }
Dianne Hackborn5c3296a2017-12-13 17:52:26 -0800135 final PrintWriter pw = getOutPrintWriter();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700136 try {
137 switch (cmd) {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700138 case "start":
139 case "start-activity":
140 return runStartActivity(pw);
141 case "startservice":
142 case "start-service":
Christopher Tate7e1368d2017-03-30 17:20:12 -0700143 return runStartService(pw, false);
144 case "startforegroundservice":
145 case "startfgservice":
146 case "start-foreground-service":
147 case "start-fg-service":
148 return runStartService(pw, true);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700149 case "stopservice":
150 case "stop-service":
Dianne Hackborn331084d2016-10-07 17:57:00 -0700151 return runStopService(pw);
152 case "broadcast":
153 return runSendBroadcast(pw);
154 case "instrument":
Dianne Hackborn28824062016-10-18 13:19:20 -0700155 getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");
156 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700157 case "trace-ipc":
158 return runTraceIpc(pw);
159 case "profile":
160 return runProfile(pw);
161 case "dumpheap":
162 return runDumpHeap(pw);
163 case "set-debug-app":
164 return runSetDebugApp(pw);
Andreas Gampe5b495d52018-01-22 15:15:54 -0800165 case "set-agent-app":
166 return runSetAgentApp(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700167 case "clear-debug-app":
168 return runClearDebugApp(pw);
169 case "set-watch-heap":
170 return runSetWatchHeap(pw);
171 case "clear-watch-heap":
172 return runClearWatchHeap(pw);
173 case "bug-report":
174 return runBugReport(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700175 case "force-stop":
176 return runForceStop(pw);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800177 case "crash":
178 return runCrash(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700179 case "kill":
180 return runKill(pw);
181 case "kill-all":
182 return runKillAll(pw);
Dianne Hackborn85e35642017-01-12 15:10:57 -0800183 case "make-uid-idle":
Dianne Hackborne07641d2016-11-09 15:07:23 -0800184 return runMakeIdle(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700185 case "monitor":
186 return runMonitor(pw);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +0100187 case "watch-uids":
188 return runWatchUids(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700189 case "hang":
190 return runHang(pw);
191 case "restart":
192 return runRestart(pw);
193 case "idle-maintenance":
194 return runIdleMaintenance(pw);
195 case "screen-compat":
196 return runScreenCompat(pw);
197 case "package-importance":
198 return runPackageImportance(pw);
199 case "to-uri":
200 return runToUri(pw, 0);
201 case "to-intent-uri":
202 return runToUri(pw, Intent.URI_INTENT_SCHEME);
203 case "to-app-uri":
204 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME);
205 case "switch-user":
206 return runSwitchUser(pw);
207 case "get-current-user":
208 return runGetCurrentUser(pw);
209 case "start-user":
210 return runStartUser(pw);
211 case "unlock-user":
212 return runUnlockUser(pw);
213 case "stop-user":
214 return runStopUser(pw);
215 case "is-user-stopped":
216 return runIsUserStopped(pw);
217 case "get-started-user-state":
218 return runGetStartedUserState(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700219 case "track-associations":
220 return runTrackAssociations(pw);
221 case "untrack-associations":
222 return runUntrackAssociations(pw);
Felipe Leme2f1b2272016-03-25 16:15:02 -0700223 case "get-uid-state":
224 return getUidState(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700225 case "get-config":
226 return runGetConfig(pw);
227 case "suppress-resize-config-changes":
228 return runSuppressResizeConfigChanges(pw);
229 case "set-inactive":
230 return runSetInactive(pw);
231 case "get-inactive":
232 return runGetInactive(pw);
Amith Yamasani17fffee2017-09-29 13:17:43 -0700233 case "set-standby-bucket":
234 return runSetStandbyBucket(pw);
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800235 case "get-standby-bucket":
236 return runGetStandbyBucket(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700237 case "send-trim-memory":
238 return runSendTrimMemory(pw);
Andrii Kulian839def92016-11-02 10:58:58 -0700239 case "display":
240 return runDisplay(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700241 case "stack":
242 return runStack(pw);
243 case "task":
244 return runTask(pw);
245 case "write":
246 return runWrite(pw);
Leonard Mosescuf3409ce2016-10-06 17:32:05 -0700247 case "attach-agent":
248 return runAttachAgent(pw);
Michael Kwan94438b72016-11-03 15:30:34 -0700249 case "supports-multiwindow":
250 return runSupportsMultiwindow(pw);
Matthew Ng626e0cc2016-12-07 17:25:53 -0800251 case "supports-split-screen-multi-window":
252 return runSupportsSplitScreenMultiwindow(pw);
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +0100253 case "update-appinfo":
254 return runUpdateApplicationInfo(pw);
Arthur Hsuf3f3a602017-02-21 14:01:53 -0800255 case "no-home-screen":
256 return runNoHomeScreen(pw);
Jeff Sharkeyfd658132017-05-03 11:38:01 -0600257 case "wait-for-broadcast-idle":
258 return runWaitForBroadcastIdle(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700259 default:
260 return handleDefaultCommands(cmd);
261 }
262 } catch (RemoteException e) {
263 pw.println("Remote exception: " + e);
264 }
265 return -1;
266 }
267
Dianne Hackborn354736e2016-08-22 17:00:05 -0700268 private Intent makeIntent(int defUser) throws URISyntaxException {
269 mStartFlags = 0;
270 mWaitOption = false;
271 mStopOption = false;
272 mRepeat = 0;
273 mProfileFile = null;
274 mSamplingInterval = 0;
275 mAutoStop = false;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800276 mStreaming = false;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700277 mUserId = defUser;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700278 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700279 mWindowingMode = WINDOWING_MODE_UNDEFINED;
280 mActivityType = ACTIVITY_TYPE_UNDEFINED;
Winson Chung6954fc92017-03-24 16:22:12 -0700281 mTaskId = INVALID_TASK_ID;
282 mIsTaskOverlay = false;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000283 mIsLockTask = false;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700284
285 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
286 @Override
287 public boolean handleOption(String opt, ShellCommand cmd) {
288 if (opt.equals("-D")) {
289 mStartFlags |= ActivityManager.START_FLAG_DEBUG;
290 } else if (opt.equals("-N")) {
291 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING;
292 } else if (opt.equals("-W")) {
293 mWaitOption = true;
294 } else if (opt.equals("-P")) {
295 mProfileFile = getNextArgRequired();
296 mAutoStop = true;
297 } else if (opt.equals("--start-profiler")) {
298 mProfileFile = getNextArgRequired();
299 mAutoStop = false;
300 } else if (opt.equals("--sampling")) {
301 mSamplingInterval = Integer.parseInt(getNextArgRequired());
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800302 } else if (opt.equals("--streaming")) {
303 mStreaming = true;
Andreas Gampe83085bb2017-06-26 17:54:11 -0700304 } else if (opt.equals("--attach-agent")) {
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800305 if (mAgent != null) {
306 cmd.getErrPrintWriter().println(
307 "Multiple --attach-agent(-bind) not supported");
308 return false;
309 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700310 mAgent = getNextArgRequired();
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800311 mAttachAgentDuringBind = false;
312 } else if (opt.equals("--attach-agent-bind")) {
313 if (mAgent != null) {
314 cmd.getErrPrintWriter().println(
315 "Multiple --attach-agent(-bind) not supported");
316 return false;
317 }
318 mAgent = getNextArgRequired();
319 mAttachAgentDuringBind = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700320 } else if (opt.equals("-R")) {
321 mRepeat = Integer.parseInt(getNextArgRequired());
322 } else if (opt.equals("-S")) {
323 mStopOption = true;
324 } else if (opt.equals("--track-allocation")) {
325 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
326 } else if (opt.equals("--user")) {
327 mUserId = UserHandle.parseUserArg(getNextArgRequired());
328 } else if (opt.equals("--receiver-permission")) {
329 mReceiverPermission = getNextArgRequired();
Andrii Kulian16802aa2016-11-02 12:21:33 -0700330 } else if (opt.equals("--display")) {
331 mDisplayId = Integer.parseInt(getNextArgRequired());
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700332 } else if (opt.equals("--windowingMode")) {
333 mWindowingMode = Integer.parseInt(getNextArgRequired());
334 } else if (opt.equals("--activityType")) {
335 mActivityType = Integer.parseInt(getNextArgRequired());
Winson Chung6954fc92017-03-24 16:22:12 -0700336 } else if (opt.equals("--task")) {
337 mTaskId = Integer.parseInt(getNextArgRequired());
338 } else if (opt.equals("--task-overlay")) {
339 mIsTaskOverlay = true;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000340 } else if (opt.equals("--lock-task")) {
341 mIsLockTask = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700342 } else {
343 return false;
344 }
345 return true;
346 }
347 });
348 }
349
Dianne Hackborn354736e2016-08-22 17:00:05 -0700350 int runStartActivity(PrintWriter pw) throws RemoteException {
351 Intent intent;
352 try {
353 intent = makeIntent(UserHandle.USER_CURRENT);
354 } catch (URISyntaxException e) {
355 throw new RuntimeException(e.getMessage(), e);
356 }
357
358 if (mUserId == UserHandle.USER_ALL) {
359 getErrPrintWriter().println("Error: Can't start service with user 'all'");
360 return 1;
361 }
362
363 String mimeType = intent.getType();
364 if (mimeType == null && intent.getData() != null
365 && "content".equals(intent.getData().getScheme())) {
366 mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId);
367 }
368
369 do {
370 if (mStopOption) {
371 String packageName;
372 if (intent.getComponent() != null) {
373 packageName = intent.getComponent().getPackageName();
374 } else {
375 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0,
376 mUserId).getList();
377 if (activities == null || activities.size() <= 0) {
378 getErrPrintWriter().println("Error: Intent does not match any activities: "
379 + intent);
380 return 1;
381 } else if (activities.size() > 1) {
382 getErrPrintWriter().println(
383 "Error: Intent matches multiple activities; can't stop: "
384 + intent);
385 return 1;
386 }
387 packageName = activities.get(0).activityInfo.packageName;
388 }
389 pw.println("Stopping: " + packageName);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700390 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700391 mInterface.forceStopPackage(packageName, mUserId);
392 try {
393 Thread.sleep(250);
394 } catch (InterruptedException e) {
395 }
396 }
397
398 ProfilerInfo profilerInfo = null;
399
Andreas Gampe83085bb2017-06-26 17:54:11 -0700400 if (mProfileFile != null || mAgent != null) {
401 ParcelFileDescriptor fd = null;
402 if (mProfileFile != null) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700403 fd = openFileForSystem(mProfileFile, "w");
Andreas Gampe83085bb2017-06-26 17:54:11 -0700404 if (fd == null) {
405 return 1;
406 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700407 }
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800408 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800409 mStreaming, mAgent, mAttachAgentDuringBind);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700410 }
411
412 pw.println("Starting: " + intent);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700413 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700414 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
415
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700416 WaitResult result = null;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700417 int res;
418 final long startTime = SystemClock.uptimeMillis();
419 ActivityOptions options = null;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700420 if (mDisplayId != INVALID_DISPLAY) {
421 options = ActivityOptions.makeBasic();
422 options.setLaunchDisplayId(mDisplayId);
423 }
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700424 if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
425 if (options == null) {
426 options = ActivityOptions.makeBasic();
427 }
428 options.setLaunchWindowingMode(mWindowingMode);
429 }
430 if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
431 if (options == null) {
432 options = ActivityOptions.makeBasic();
433 }
434 options.setLaunchActivityType(mActivityType);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700435 }
Winson Chung6954fc92017-03-24 16:22:12 -0700436 if (mTaskId != INVALID_TASK_ID) {
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000437 if (options == null) {
438 options = ActivityOptions.makeBasic();
439 }
Winson Chung6954fc92017-03-24 16:22:12 -0700440 options.setLaunchTaskId(mTaskId);
441
442 if (mIsTaskOverlay) {
443 options.setTaskOverlay(true, true /* canResume */);
444 }
445 }
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000446 if (mIsLockTask) {
447 if (options == null) {
448 options = ActivityOptions.makeBasic();
449 }
Benjamin Franzcaffa772018-02-05 16:36:10 +0000450 options.setLockTaskEnabled(true);
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000451 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700452 if (mWaitOption) {
453 result = mInterface.startActivityAndWait(null, null, intent, mimeType,
454 null, null, 0, mStartFlags, profilerInfo,
455 options != null ? options.toBundle() : null, mUserId);
456 res = result.result;
457 } else {
458 res = mInterface.startActivityAsUser(null, null, intent, mimeType,
459 null, null, 0, mStartFlags, profilerInfo,
460 options != null ? options.toBundle() : null, mUserId);
461 }
462 final long endTime = SystemClock.uptimeMillis();
463 PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
464 boolean launched = false;
465 switch (res) {
466 case ActivityManager.START_SUCCESS:
467 launched = true;
468 break;
469 case ActivityManager.START_SWITCHES_CANCELED:
470 launched = true;
471 out.println(
472 "Warning: Activity not started because the "
473 + " current activity is being kept for the user.");
474 break;
475 case ActivityManager.START_DELIVERED_TO_TOP:
476 launched = true;
477 out.println(
478 "Warning: Activity not started, intent has "
479 + "been delivered to currently running "
480 + "top-most instance.");
481 break;
482 case ActivityManager.START_RETURN_INTENT_TO_CALLER:
483 launched = true;
484 out.println(
485 "Warning: Activity not started because intent "
486 + "should be handled by the caller");
487 break;
488 case ActivityManager.START_TASK_TO_FRONT:
489 launched = true;
490 out.println(
491 "Warning: Activity not started, its current "
492 + "task has been brought to the front");
493 break;
494 case ActivityManager.START_INTENT_NOT_RESOLVED:
495 out.println(
496 "Error: Activity not started, unable to "
497 + "resolve " + intent.toString());
498 break;
499 case ActivityManager.START_CLASS_NOT_FOUND:
500 out.println(NO_CLASS_ERROR_CODE);
501 out.println("Error: Activity class " +
502 intent.getComponent().toShortString()
503 + " does not exist.");
504 break;
505 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
506 out.println(
507 "Error: Activity not started, you requested to "
508 + "both forward and receive its result");
509 break;
510 case ActivityManager.START_PERMISSION_DENIED:
511 out.println(
512 "Error: Activity not started, you do not "
513 + "have permission to access it.");
514 break;
515 case ActivityManager.START_NOT_VOICE_COMPATIBLE:
516 out.println(
517 "Error: Activity not started, voice control not allowed for: "
518 + intent);
519 break;
520 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
521 out.println(
522 "Error: Not allowed to start background user activity"
523 + " that shouldn't be displayed for all users.");
524 break;
525 default:
526 out.println(
527 "Error: Activity not started, unknown error code " + res);
528 break;
529 }
Dianne Hackborn331084d2016-10-07 17:57:00 -0700530 out.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700531 if (mWaitOption && launched) {
532 if (result == null) {
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700533 result = new WaitResult();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700534 result.who = intent.getComponent();
535 }
536 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
537 if (result.who != null) {
538 pw.println("Activity: " + result.who.flattenToShortString());
539 }
540 if (result.thisTime >= 0) {
541 pw.println("ThisTime: " + result.thisTime);
542 }
543 if (result.totalTime >= 0) {
544 pw.println("TotalTime: " + result.totalTime);
545 }
546 pw.println("WaitTime: " + (endTime-startTime));
547 pw.println("Complete");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700548 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700549 }
550 mRepeat--;
551 if (mRepeat > 0) {
552 mInterface.unhandledBack();
553 }
554 } while (mRepeat > 0);
555 return 0;
556 }
557
Christopher Tate7e1368d2017-03-30 17:20:12 -0700558 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700559 final PrintWriter err = getErrPrintWriter();
560 Intent intent;
561 try {
562 intent = makeIntent(UserHandle.USER_CURRENT);
563 } catch (URISyntaxException e) {
564 throw new RuntimeException(e.getMessage(), e);
565 }
566 if (mUserId == UserHandle.USER_ALL) {
567 err.println("Error: Can't start activity with user 'all'");
568 return -1;
569 }
570 pw.println("Starting service: " + intent);
571 pw.flush();
572 ComponentName cn = mInterface.startService(null, intent, intent.getType(),
Christopher Tate242ba3e92017-04-14 15:07:06 -0700573 asForeground, SHELL_PACKAGE_NAME, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700574 if (cn == null) {
575 err.println("Error: Not found; no service started.");
576 return -1;
577 } else if (cn.getPackageName().equals("!")) {
578 err.println("Error: Requires permission " + cn.getClassName());
579 return -1;
580 } else if (cn.getPackageName().equals("!!")) {
581 err.println("Error: " + cn.getClassName());
582 return -1;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800583 } else if (cn.getPackageName().equals("?")) {
584 err.println("Error: " + cn.getClassName());
585 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700586 }
587 return 0;
588 }
589
590 int runStopService(PrintWriter pw) throws RemoteException {
591 final PrintWriter err = getErrPrintWriter();
592 Intent intent;
593 try {
594 intent = makeIntent(UserHandle.USER_CURRENT);
595 } catch (URISyntaxException e) {
596 throw new RuntimeException(e.getMessage(), e);
597 }
598 if (mUserId == UserHandle.USER_ALL) {
599 err.println("Error: Can't stop activity with user 'all'");
600 return -1;
601 }
602 pw.println("Stopping service: " + intent);
603 pw.flush();
604 int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
605 if (result == 0) {
606 err.println("Service not stopped: was not running.");
607 return -1;
608 } else if (result == 1) {
609 err.println("Service stopped");
610 return -1;
611 } else if (result == -1) {
612 err.println("Error stopping service");
613 return -1;
614 }
615 return 0;
616 }
617
618 final static class IntentReceiver extends IIntentReceiver.Stub {
619 private final PrintWriter mPw;
620 private boolean mFinished = false;
621
622 IntentReceiver(PrintWriter pw) {
623 mPw = pw;
624 }
625
626 @Override
627 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
628 boolean ordered, boolean sticky, int sendingUser) {
629 String line = "Broadcast completed: result=" + resultCode;
630 if (data != null) line = line + ", data=\"" + data + "\"";
631 if (extras != null) line = line + ", extras: " + extras;
632 mPw.println(line);
633 mPw.flush();
634 synchronized (this) {
635 mFinished = true;
636 notifyAll();
637 }
638 }
639
640 public synchronized void waitForFinish() {
641 try {
642 while (!mFinished) wait();
643 } catch (InterruptedException e) {
644 throw new IllegalStateException(e);
645 }
646 }
647 }
648
649 int runSendBroadcast(PrintWriter pw) throws RemoteException {
650 Intent intent;
651 try {
652 intent = makeIntent(UserHandle.USER_CURRENT);
653 } catch (URISyntaxException e) {
654 throw new RuntimeException(e.getMessage(), e);
655 }
Jeff Sharkey6a34e562016-12-21 09:56:00 -0700656 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700657 IntentReceiver receiver = new IntentReceiver(pw);
658 String[] requiredPermissions = mReceiverPermission == null ? null
659 : new String[] {mReceiverPermission};
660 pw.println("Broadcasting: " + intent);
661 pw.flush();
662 mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
663 android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
664 receiver.waitForFinish();
665 return 0;
666 }
667
Dianne Hackborn331084d2016-10-07 17:57:00 -0700668 int runTraceIpc(PrintWriter pw) throws RemoteException {
669 String op = getNextArgRequired();
670 if (op.equals("start")) {
671 return runTraceIpcStart(pw);
672 } else if (op.equals("stop")) {
673 return runTraceIpcStop(pw);
674 } else {
675 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'");
676 return -1;
677 }
678 }
679
680 int runTraceIpcStart(PrintWriter pw) throws RemoteException {
681 pw.println("Starting IPC tracing.");
682 pw.flush();
683 mInterface.startBinderTracking();
684 return 0;
685 }
686
687 int runTraceIpcStop(PrintWriter pw) throws RemoteException {
688 final PrintWriter err = getErrPrintWriter();
689 String opt;
690 String filename = null;
691 while ((opt=getNextOption()) != null) {
692 if (opt.equals("--dump-file")) {
693 filename = getNextArgRequired();
694 } else {
695 err.println("Error: Unknown option: " + opt);
696 return -1;
697 }
698 }
699 if (filename == null) {
700 err.println("Error: Specify filename to dump logs to.");
701 return -1;
702 }
703
704 File file = new File(filename);
705 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700706 ParcelFileDescriptor fd = openFileForSystem(filename, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700707 if (fd == null) {
708 return -1;
709 }
710
711 ;
712 if (!mInterface.stopBinderTrackingAndDump(fd)) {
713 err.println("STOP TRACE FAILED.");
714 return -1;
715 }
716
717 pw.println("Stopped IPC tracing. Dumping logs to: " + filename);
718 return 0;
719 }
720
721 static void removeWallOption() {
722 String props = SystemProperties.get("dalvik.vm.extra-opts");
723 if (props != null && props.contains("-Xprofile:wallclock")) {
724 props = props.replace("-Xprofile:wallclock", "");
725 props = props.trim();
726 SystemProperties.set("dalvik.vm.extra-opts", props);
727 }
728 }
729
730 private int runProfile(PrintWriter pw) throws RemoteException {
731 final PrintWriter err = getErrPrintWriter();
732 String profileFile = null;
733 boolean start = false;
734 boolean wall = false;
735 int userId = UserHandle.USER_CURRENT;
736 int profileType = 0;
737 mSamplingInterval = 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800738 mStreaming = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700739
740 String process = null;
741
742 String cmd = getNextArgRequired();
743
744 if ("start".equals(cmd)) {
745 start = true;
746 String opt;
747 while ((opt=getNextOption()) != null) {
748 if (opt.equals("--user")) {
749 userId = UserHandle.parseUserArg(getNextArgRequired());
750 } else if (opt.equals("--wall")) {
751 wall = true;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800752 } else if (opt.equals("--streaming")) {
753 mStreaming = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700754 } else if (opt.equals("--sampling")) {
755 mSamplingInterval = Integer.parseInt(getNextArgRequired());
756 } else {
757 err.println("Error: Unknown option: " + opt);
758 return -1;
759 }
760 }
761 process = getNextArgRequired();
762 } else if ("stop".equals(cmd)) {
763 String opt;
764 while ((opt=getNextOption()) != null) {
765 if (opt.equals("--user")) {
766 userId = UserHandle.parseUserArg(getNextArgRequired());
767 } else {
768 err.println("Error: Unknown option: " + opt);
769 return -1;
770 }
771 }
772 process = getNextArg();
773 } else {
774 // Compatibility with old syntax: process is specified first.
775 process = cmd;
776 cmd = getNextArgRequired();
777 if ("start".equals(cmd)) {
778 start = true;
779 } else if (!"stop".equals(cmd)) {
780 throw new IllegalArgumentException("Profile command " + process + " not valid");
781 }
782 }
783
784 if (userId == UserHandle.USER_ALL) {
785 err.println("Error: Can't profile with user 'all'");
786 return -1;
787 }
788
789 ParcelFileDescriptor fd = null;
790 ProfilerInfo profilerInfo = null;
791
792 if (start) {
793 profileFile = getNextArgRequired();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700794 fd = openFileForSystem(profileFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700795 if (fd == null) {
796 return -1;
797 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700798 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800799 null, false);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700800 }
801
802 try {
803 if (wall) {
804 // XXX doesn't work -- this needs to be set before booting.
805 String props = SystemProperties.get("dalvik.vm.extra-opts");
806 if (props == null || !props.contains("-Xprofile:wallclock")) {
807 props = props + " -Xprofile:wallclock";
808 //SystemProperties.set("dalvik.vm.extra-opts", props);
809 }
810 } else if (start) {
811 //removeWallOption();
812 }
813 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
814 wall = false;
815 err.println("PROFILE FAILED on process " + process);
816 return -1;
817 }
818 } finally {
819 if (!wall) {
820 //removeWallOption();
821 }
822 }
823 return 0;
824 }
825
826 int runDumpHeap(PrintWriter pw) throws RemoteException {
827 final PrintWriter err = getErrPrintWriter();
828 boolean managed = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700829 boolean mallocInfo = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700830 int userId = UserHandle.USER_CURRENT;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700831 boolean runGc = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700832
833 String opt;
834 while ((opt=getNextOption()) != null) {
835 if (opt.equals("--user")) {
836 userId = UserHandle.parseUserArg(getNextArgRequired());
837 if (userId == UserHandle.USER_ALL) {
838 err.println("Error: Can't dump heap with user 'all'");
839 return -1;
840 }
841 } else if (opt.equals("-n")) {
842 managed = false;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700843 } else if (opt.equals("-g")) {
844 runGc = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700845 } else if (opt.equals("-m")) {
846 managed = false;
847 mallocInfo = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700848 } else {
849 err.println("Error: Unknown option: " + opt);
850 return -1;
851 }
852 }
853 String process = getNextArgRequired();
854 String heapFile = getNextArgRequired();
855
856 File file = new File(heapFile);
857 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700858 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700859 if (fd == null) {
860 return -1;
861 }
862
Christopher Ferris8d652f82017-04-11 16:29:18 -0700863 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700864 err.println("HEAP DUMP FAILED on process " + process);
865 return -1;
866 }
867 return 0;
868 }
869
870 int runSetDebugApp(PrintWriter pw) throws RemoteException {
871 boolean wait = false;
872 boolean persistent = false;
873
874 String opt;
875 while ((opt=getNextOption()) != null) {
876 if (opt.equals("-w")) {
877 wait = true;
878 } else if (opt.equals("--persistent")) {
879 persistent = true;
880 } else {
881 getErrPrintWriter().println("Error: Unknown option: " + opt);
882 return -1;
883 }
884 }
885
886 String pkg = getNextArgRequired();
887 mInterface.setDebugApp(pkg, wait, persistent);
888 return 0;
889 }
890
Andreas Gampe5b495d52018-01-22 15:15:54 -0800891 int runSetAgentApp(PrintWriter pw) throws RemoteException {
892 String pkg = getNextArgRequired();
893 String agent = getNextArg();
894 mInterface.setAgentApp(pkg, agent);
895 return 0;
896 }
897
Dianne Hackborn331084d2016-10-07 17:57:00 -0700898 int runClearDebugApp(PrintWriter pw) throws RemoteException {
899 mInterface.setDebugApp(null, false, true);
900 return 0;
901 }
902
903 int runSetWatchHeap(PrintWriter pw) throws RemoteException {
904 String proc = getNextArgRequired();
905 String limit = getNextArgRequired();
906 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
907 return 0;
908 }
909
910 int runClearWatchHeap(PrintWriter pw) throws RemoteException {
911 String proc = getNextArgRequired();
912 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null);
913 return 0;
914 }
915
916 int runBugReport(PrintWriter pw) throws RemoteException {
917 String opt;
918 int bugreportType = ActivityManager.BUGREPORT_OPTION_FULL;
919 while ((opt=getNextOption()) != null) {
920 if (opt.equals("--progress")) {
921 bugreportType = ActivityManager.BUGREPORT_OPTION_INTERACTIVE;
Felipe Leme9606c3b2017-01-05 14:57:12 -0800922 } else if (opt.equals("--telephony")) {
923 bugreportType = ActivityManager.BUGREPORT_OPTION_TELEPHONY;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700924 } else {
925 getErrPrintWriter().println("Error: Unknown option: " + opt);
926 return -1;
927 }
928 }
929 mInterface.requestBugReport(bugreportType);
930 pw.println("Your lovely bug report is being created; please be patient.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800931 return 0;
932 }
933
Dianne Hackborn2e441072015-10-28 18:00:57 -0700934 int runForceStop(PrintWriter pw) throws RemoteException {
935 int userId = UserHandle.USER_ALL;
936
937 String opt;
938 while ((opt = getNextOption()) != null) {
939 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800940 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -0700941 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700942 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700943 return -1;
944 }
945 }
946 mInterface.forceStopPackage(getNextArgRequired(), userId);
947 return 0;
948 }
949
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800950 int runCrash(PrintWriter pw) throws RemoteException {
951 int userId = UserHandle.USER_ALL;
952
953 String opt;
954 while ((opt=getNextOption()) != null) {
955 if (opt.equals("--user")) {
956 userId = UserHandle.parseUserArg(getNextArgRequired());
957 } else {
958 getErrPrintWriter().println("Error: Unknown option: " + opt);
959 return -1;
960 }
961 }
962
963 int pid = -1;
964 String packageName = null;
965 final String arg = getNextArgRequired();
966 // The argument is either a pid or a package name
967 try {
968 pid = Integer.parseInt(arg);
969 } catch (NumberFormatException e) {
970 packageName = arg;
971 }
972 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
973 return 0;
974 }
975
Dianne Hackborn2e441072015-10-28 18:00:57 -0700976 int runKill(PrintWriter pw) throws RemoteException {
977 int userId = UserHandle.USER_ALL;
978
979 String opt;
980 while ((opt=getNextOption()) != null) {
981 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800982 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -0700983 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700984 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700985 return -1;
986 }
987 }
988 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
989 return 0;
990 }
991
992 int runKillAll(PrintWriter pw) throws RemoteException {
993 mInterface.killAllBackgroundProcesses();
994 return 0;
995 }
996
Dianne Hackborne07641d2016-11-09 15:07:23 -0800997 int runMakeIdle(PrintWriter pw) throws RemoteException {
998 int userId = UserHandle.USER_ALL;
999
1000 String opt;
1001 while ((opt = getNextOption()) != null) {
1002 if (opt.equals("--user")) {
1003 userId = UserHandle.parseUserArg(getNextArgRequired());
1004 } else {
1005 getErrPrintWriter().println("Error: Unknown option: " + opt);
1006 return -1;
1007 }
1008 }
1009 mInterface.makePackageIdle(getNextArgRequired(), userId);
1010 return 0;
1011 }
1012
Dianne Hackborn331084d2016-10-07 17:57:00 -07001013 static final class MyActivityController extends IActivityController.Stub {
1014 final IActivityManager mInterface;
1015 final PrintWriter mPw;
1016 final InputStream mInput;
1017 final String mGdbPort;
1018 final boolean mMonkey;
1019
1020 static final int STATE_NORMAL = 0;
1021 static final int STATE_CRASHED = 1;
1022 static final int STATE_EARLY_ANR = 2;
1023 static final int STATE_ANR = 3;
1024
1025 int mState;
1026
1027 static final int RESULT_DEFAULT = 0;
1028
1029 static final int RESULT_CRASH_DIALOG = 0;
1030 static final int RESULT_CRASH_KILL = 1;
1031
1032 static final int RESULT_EARLY_ANR_CONTINUE = 0;
1033 static final int RESULT_EARLY_ANR_KILL = 1;
1034
1035 static final int RESULT_ANR_DIALOG = 0;
1036 static final int RESULT_ANR_KILL = 1;
1037 static final int RESULT_ANR_WAIT = 1;
1038
1039 int mResult;
1040
1041 Process mGdbProcess;
1042 Thread mGdbThread;
1043 boolean mGotGdbPrint;
1044
1045 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
1046 String gdbPort, boolean monkey) {
1047 mInterface = iam;
1048 mPw = pw;
1049 mInput = input;
1050 mGdbPort = gdbPort;
1051 mMonkey = monkey;
1052 }
1053
1054 @Override
1055 public boolean activityResuming(String pkg) {
1056 synchronized (this) {
1057 mPw.println("** Activity resuming: " + pkg);
1058 mPw.flush();
1059 }
1060 return true;
1061 }
1062
1063 @Override
1064 public boolean activityStarting(Intent intent, String pkg) {
1065 synchronized (this) {
1066 mPw.println("** Activity starting: " + pkg);
1067 mPw.flush();
1068 }
1069 return true;
1070 }
1071
1072 @Override
1073 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
1074 long timeMillis, String stackTrace) {
1075 synchronized (this) {
1076 mPw.println("** ERROR: PROCESS CRASHED");
1077 mPw.println("processName: " + processName);
1078 mPw.println("processPid: " + pid);
1079 mPw.println("shortMsg: " + shortMsg);
1080 mPw.println("longMsg: " + longMsg);
1081 mPw.println("timeMillis: " + timeMillis);
1082 mPw.println("stack:");
1083 mPw.print(stackTrace);
1084 mPw.println("#");
1085 mPw.flush();
1086 int result = waitControllerLocked(pid, STATE_CRASHED);
1087 return result == RESULT_CRASH_KILL ? false : true;
1088 }
1089 }
1090
1091 @Override
1092 public int appEarlyNotResponding(String processName, int pid, String annotation) {
1093 synchronized (this) {
1094 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING");
1095 mPw.println("processName: " + processName);
1096 mPw.println("processPid: " + pid);
1097 mPw.println("annotation: " + annotation);
1098 mPw.flush();
1099 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
1100 if (result == RESULT_EARLY_ANR_KILL) return -1;
1101 return 0;
1102 }
1103 }
1104
1105 @Override
1106 public int appNotResponding(String processName, int pid, String processStats) {
1107 synchronized (this) {
1108 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1109 mPw.println("processName: " + processName);
1110 mPw.println("processPid: " + pid);
1111 mPw.println("processStats:");
1112 mPw.print(processStats);
1113 mPw.println("#");
1114 mPw.flush();
1115 int result = waitControllerLocked(pid, STATE_ANR);
1116 if (result == RESULT_ANR_KILL) return -1;
1117 if (result == RESULT_ANR_WAIT) return 1;
1118 return 0;
1119 }
1120 }
1121
1122 @Override
1123 public int systemNotResponding(String message) {
1124 synchronized (this) {
1125 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1126 mPw.println("message: " + message);
1127 mPw.println("#");
1128 mPw.println("Allowing system to die.");
1129 mPw.flush();
1130 return -1;
1131 }
1132 }
1133
1134 void killGdbLocked() {
1135 mGotGdbPrint = false;
1136 if (mGdbProcess != null) {
1137 mPw.println("Stopping gdbserver");
1138 mPw.flush();
1139 mGdbProcess.destroy();
1140 mGdbProcess = null;
1141 }
1142 if (mGdbThread != null) {
1143 mGdbThread.interrupt();
1144 mGdbThread = null;
1145 }
1146 }
1147
1148 int waitControllerLocked(int pid, int state) {
1149 if (mGdbPort != null) {
1150 killGdbLocked();
1151
1152 try {
1153 mPw.println("Starting gdbserver on port " + mGdbPort);
1154 mPw.println("Do the following:");
1155 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
1156 mPw.println(" gdbclient app_process :" + mGdbPort);
1157 mPw.flush();
1158
1159 mGdbProcess = Runtime.getRuntime().exec(new String[] {
1160 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
1161 });
1162 final InputStreamReader converter = new InputStreamReader(
1163 mGdbProcess.getInputStream());
1164 mGdbThread = new Thread() {
1165 @Override
1166 public void run() {
1167 BufferedReader in = new BufferedReader(converter);
1168 String line;
1169 int count = 0;
1170 while (true) {
1171 synchronized (MyActivityController.this) {
1172 if (mGdbThread == null) {
1173 return;
1174 }
1175 if (count == 2) {
1176 mGotGdbPrint = true;
1177 MyActivityController.this.notifyAll();
1178 }
1179 }
1180 try {
1181 line = in.readLine();
1182 if (line == null) {
1183 return;
1184 }
1185 mPw.println("GDB: " + line);
1186 mPw.flush();
1187 count++;
1188 } catch (IOException e) {
1189 return;
1190 }
1191 }
1192 }
1193 };
1194 mGdbThread.start();
1195
1196 // Stupid waiting for .5s. Doesn't matter if we end early.
1197 try {
1198 this.wait(500);
1199 } catch (InterruptedException e) {
1200 }
1201
1202 } catch (IOException e) {
1203 mPw.println("Failure starting gdbserver: " + e);
1204 mPw.flush();
1205 killGdbLocked();
1206 }
1207 }
1208 mState = state;
1209 mPw.println("");
1210 printMessageForState();
1211 mPw.flush();
1212
1213 while (mState != STATE_NORMAL) {
1214 try {
1215 wait();
1216 } catch (InterruptedException e) {
1217 }
1218 }
1219
1220 killGdbLocked();
1221
1222 return mResult;
1223 }
1224
1225 void resumeController(int result) {
1226 synchronized (this) {
1227 mState = STATE_NORMAL;
1228 mResult = result;
1229 notifyAll();
1230 }
1231 }
1232
1233 void printMessageForState() {
1234 switch (mState) {
1235 case STATE_NORMAL:
1236 mPw.println("Monitoring activity manager... available commands:");
1237 break;
1238 case STATE_CRASHED:
1239 mPw.println("Waiting after crash... available commands:");
1240 mPw.println("(c)ontinue: show crash dialog");
1241 mPw.println("(k)ill: immediately kill app");
1242 break;
1243 case STATE_EARLY_ANR:
1244 mPw.println("Waiting after early ANR... available commands:");
1245 mPw.println("(c)ontinue: standard ANR processing");
1246 mPw.println("(k)ill: immediately kill app");
1247 break;
1248 case STATE_ANR:
1249 mPw.println("Waiting after ANR... available commands:");
1250 mPw.println("(c)ontinue: show ANR dialog");
1251 mPw.println("(k)ill: immediately kill app");
1252 mPw.println("(w)ait: wait some more");
1253 break;
1254 }
1255 mPw.println("(q)uit: finish monitoring");
1256 }
1257
1258 void run() throws RemoteException {
1259 try {
1260 printMessageForState();
1261 mPw.flush();
1262
1263 mInterface.setActivityController(this, mMonkey);
1264 mState = STATE_NORMAL;
1265
1266 InputStreamReader converter = new InputStreamReader(mInput);
1267 BufferedReader in = new BufferedReader(converter);
1268 String line;
1269
1270 while ((line = in.readLine()) != null) {
1271 boolean addNewline = true;
1272 if (line.length() <= 0) {
1273 addNewline = false;
1274 } else if ("q".equals(line) || "quit".equals(line)) {
1275 resumeController(RESULT_DEFAULT);
1276 break;
1277 } else if (mState == STATE_CRASHED) {
1278 if ("c".equals(line) || "continue".equals(line)) {
1279 resumeController(RESULT_CRASH_DIALOG);
1280 } else if ("k".equals(line) || "kill".equals(line)) {
1281 resumeController(RESULT_CRASH_KILL);
1282 } else {
1283 mPw.println("Invalid command: " + line);
1284 }
1285 } else if (mState == STATE_ANR) {
1286 if ("c".equals(line) || "continue".equals(line)) {
1287 resumeController(RESULT_ANR_DIALOG);
1288 } else if ("k".equals(line) || "kill".equals(line)) {
1289 resumeController(RESULT_ANR_KILL);
1290 } else if ("w".equals(line) || "wait".equals(line)) {
1291 resumeController(RESULT_ANR_WAIT);
1292 } else {
1293 mPw.println("Invalid command: " + line);
1294 }
1295 } else if (mState == STATE_EARLY_ANR) {
1296 if ("c".equals(line) || "continue".equals(line)) {
1297 resumeController(RESULT_EARLY_ANR_CONTINUE);
1298 } else if ("k".equals(line) || "kill".equals(line)) {
1299 resumeController(RESULT_EARLY_ANR_KILL);
1300 } else {
1301 mPw.println("Invalid command: " + line);
1302 }
1303 } else {
1304 mPw.println("Invalid command: " + line);
1305 }
1306
1307 synchronized (this) {
1308 if (addNewline) {
1309 mPw.println("");
1310 }
1311 printMessageForState();
1312 mPw.flush();
1313 }
1314 }
1315
1316 } catch (IOException e) {
1317 e.printStackTrace(mPw);
1318 mPw.flush();
1319 } finally {
1320 mInterface.setActivityController(null, mMonkey);
1321 }
1322 }
1323 }
1324
1325 int runMonitor(PrintWriter pw) throws RemoteException {
1326 String opt;
1327 String gdbPort = null;
1328 boolean monkey = false;
1329 while ((opt=getNextOption()) != null) {
1330 if (opt.equals("--gdb")) {
1331 gdbPort = getNextArgRequired();
1332 } else if (opt.equals("-m")) {
1333 monkey = true;
1334 } else {
1335 getErrPrintWriter().println("Error: Unknown option: " + opt);
1336 return -1;
1337 }
1338 }
1339
1340 MyActivityController controller = new MyActivityController(mInterface, pw,
1341 getRawInputStream(), gdbPort, monkey);
1342 controller.run();
1343 return 0;
1344 }
1345
Dianne Hackborne51505a2017-08-07 17:13:52 -07001346 static final class MyUidObserver extends IUidObserver.Stub
1347 implements ActivityManagerService.OomAdjObserver {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001348 final IActivityManager mInterface;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001349 final ActivityManagerService mInternal;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001350 final PrintWriter mPw;
1351 final InputStream mInput;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001352 final int mUid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001353
1354 static final int STATE_NORMAL = 0;
1355
1356 int mState;
1357
Dianne Hackborne51505a2017-08-07 17:13:52 -07001358 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
1359 mInterface = service;
1360 mInternal = service;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001361 mPw = pw;
1362 mInput = input;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001363 mUid = uid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001364 }
1365
1366 @Override
1367 public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException {
1368 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001369 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1370 try {
1371 mPw.print(uid);
1372 mPw.print(" procstate ");
1373 mPw.print(ProcessList.makeProcStateString(procState));
1374 mPw.print(" seq ");
1375 mPw.println(procStateSeq);
1376 mPw.flush();
1377 } finally {
1378 StrictMode.setThreadPolicy(oldPolicy);
1379 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001380 }
1381 }
1382
1383 @Override
1384 public void onUidGone(int uid, boolean disabled) throws RemoteException {
1385 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001386 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1387 try {
1388 mPw.print(uid);
1389 mPw.print(" gone");
1390 if (disabled) {
1391 mPw.print(" disabled");
1392 }
1393 mPw.println();
1394 mPw.flush();
1395 } finally {
1396 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001397 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001398 }
1399 }
1400
1401 @Override
1402 public void onUidActive(int uid) throws RemoteException {
1403 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001404 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1405 try {
1406 mPw.print(uid);
1407 mPw.println(" active");
1408 mPw.flush();
1409 } finally {
1410 StrictMode.setThreadPolicy(oldPolicy);
1411 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001412 }
1413 }
1414
1415 @Override
1416 public void onUidIdle(int uid, boolean disabled) throws RemoteException {
1417 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001418 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1419 try {
1420 mPw.print(uid);
1421 mPw.print(" idle");
1422 if (disabled) {
1423 mPw.print(" disabled");
1424 }
1425 mPw.println();
1426 mPw.flush();
1427 } finally {
1428 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001429 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001430 }
1431 }
1432
1433 @Override
1434 public void onUidCachedChanged(int uid, boolean cached) throws RemoteException {
1435 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001436 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1437 try {
1438 mPw.print(uid);
1439 mPw.println(cached ? " cached" : " uncached");
1440 mPw.flush();
1441 } finally {
1442 StrictMode.setThreadPolicy(oldPolicy);
1443 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001444 }
1445 }
1446
Dianne Hackborne51505a2017-08-07 17:13:52 -07001447 @Override
1448 public void onOomAdjMessage(String msg) {
1449 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001450 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1451 try {
1452 mPw.print("# ");
1453 mPw.println(msg);
1454 mPw.flush();
1455 } finally {
1456 StrictMode.setThreadPolicy(oldPolicy);
1457 }
Dianne Hackborne51505a2017-08-07 17:13:52 -07001458 }
1459 }
1460
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001461 void printMessageForState() {
1462 switch (mState) {
1463 case STATE_NORMAL:
1464 mPw.println("Watching uid states... available commands:");
1465 break;
1466 }
1467 mPw.println("(q)uit: finish watching");
1468 }
1469
1470 void run() throws RemoteException {
1471 try {
1472 printMessageForState();
1473 mPw.flush();
1474
1475 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE
1476 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
1477 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
1478 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackborne51505a2017-08-07 17:13:52 -07001479 if (mUid >= 0) {
1480 mInternal.setOomAdjObserver(mUid, this);
1481 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001482 mState = STATE_NORMAL;
1483
1484 InputStreamReader converter = new InputStreamReader(mInput);
1485 BufferedReader in = new BufferedReader(converter);
1486 String line;
1487
1488 while ((line = in.readLine()) != null) {
1489 boolean addNewline = true;
1490 if (line.length() <= 0) {
1491 addNewline = false;
1492 } else if ("q".equals(line) || "quit".equals(line)) {
1493 break;
1494 } else {
1495 mPw.println("Invalid command: " + line);
1496 }
1497
1498 synchronized (this) {
1499 if (addNewline) {
1500 mPw.println("");
1501 }
1502 printMessageForState();
1503 mPw.flush();
1504 }
1505 }
1506
1507 } catch (IOException e) {
1508 e.printStackTrace(mPw);
1509 mPw.flush();
1510 } finally {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001511 if (mUid >= 0) {
1512 mInternal.clearOomAdjObserver();
1513 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001514 mInterface.unregisterUidObserver(this);
1515 }
1516 }
1517 }
1518
1519 int runWatchUids(PrintWriter pw) throws RemoteException {
1520 String opt;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001521 int uid = -1;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001522 while ((opt=getNextOption()) != null) {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001523 if (opt.equals("--oom")) {
1524 uid = Integer.parseInt(getNextArgRequired());
1525 } else {
1526 getErrPrintWriter().println("Error: Unknown option: " + opt);
1527 return -1;
1528
1529 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001530 }
1531
Dianne Hackborne51505a2017-08-07 17:13:52 -07001532 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001533 controller.run();
1534 return 0;
1535 }
1536
Dianne Hackborn331084d2016-10-07 17:57:00 -07001537 int runHang(PrintWriter pw) throws RemoteException {
1538 String opt;
1539 boolean allowRestart = false;
1540 while ((opt=getNextOption()) != null) {
1541 if (opt.equals("--allow-restart")) {
1542 allowRestart = true;
1543 } else {
1544 getErrPrintWriter().println("Error: Unknown option: " + opt);
1545 return -1;
1546 }
1547 }
1548
1549 pw.println("Hanging the system...");
1550 pw.flush();
1551 mInterface.hang(new Binder(), allowRestart);
1552 return 0;
1553 }
1554
1555 int runRestart(PrintWriter pw) throws RemoteException {
1556 String opt;
1557 while ((opt=getNextOption()) != null) {
1558 getErrPrintWriter().println("Error: Unknown option: " + opt);
1559 return -1;
1560 }
1561
1562 pw.println("Restart the system...");
1563 pw.flush();
1564 mInterface.restart();
1565 return 0;
1566 }
1567
1568 int runIdleMaintenance(PrintWriter pw) throws RemoteException {
1569 String opt;
1570 while ((opt=getNextOption()) != null) {
1571 getErrPrintWriter().println("Error: Unknown option: " + opt);
1572 return -1;
1573 }
1574
1575 pw.println("Performing idle maintenance...");
1576 mInterface.sendIdleJobTrigger();
1577 return 0;
1578 }
1579
1580 int runScreenCompat(PrintWriter pw) throws RemoteException {
1581 String mode = getNextArgRequired();
1582 boolean enabled;
1583 if ("on".equals(mode)) {
1584 enabled = true;
1585 } else if ("off".equals(mode)) {
1586 enabled = false;
1587 } else {
1588 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode);
1589 return -1;
1590 }
1591
1592 String packageName = getNextArgRequired();
1593 do {
1594 try {
1595 mInterface.setPackageScreenCompatMode(packageName, enabled
1596 ? ActivityManager.COMPAT_MODE_ENABLED
1597 : ActivityManager.COMPAT_MODE_DISABLED);
1598 } catch (RemoteException e) {
1599 }
1600 packageName = getNextArg();
1601 } while (packageName != null);
1602 return 0;
1603 }
1604
1605 int runPackageImportance(PrintWriter pw) throws RemoteException {
1606 String packageName = getNextArgRequired();
1607 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell");
1608 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
1609 return 0;
1610 }
1611
1612 int runToUri(PrintWriter pw, int flags) throws RemoteException {
1613 Intent intent;
1614 try {
1615 intent = makeIntent(UserHandle.USER_CURRENT);
1616 } catch (URISyntaxException e) {
1617 throw new RuntimeException(e.getMessage(), e);
1618 }
1619 pw.println(intent.toUri(flags));
1620 return 0;
1621 }
1622
1623 int runSwitchUser(PrintWriter pw) throws RemoteException {
1624 String user = getNextArgRequired();
1625 mInterface.switchUser(Integer.parseInt(user));
1626 return 0;
1627 }
1628
1629 int runGetCurrentUser(PrintWriter pw) throws RemoteException {
1630 UserInfo currentUser = Preconditions.checkNotNull(mInterface.getCurrentUser(),
1631 "Current user not set");
1632 pw.println(currentUser.id);
1633 return 0;
1634 }
1635
1636 int runStartUser(PrintWriter pw) throws RemoteException {
1637 String user = getNextArgRequired();
1638 boolean success = mInterface.startUserInBackground(Integer.parseInt(user));
1639 if (success) {
1640 pw.println("Success: user started");
1641 } else {
1642 getErrPrintWriter().println("Error: could not start user");
1643 }
1644 return 0;
1645 }
1646
1647 private static byte[] argToBytes(String arg) {
1648 if (arg.equals("!")) {
1649 return null;
1650 } else {
1651 return HexDump.hexStringToByteArray(arg);
1652 }
1653 }
1654
1655 int runUnlockUser(PrintWriter pw) throws RemoteException {
1656 int userId = Integer.parseInt(getNextArgRequired());
1657 byte[] token = argToBytes(getNextArgRequired());
1658 byte[] secret = argToBytes(getNextArgRequired());
1659 boolean success = mInterface.unlockUser(userId, token, secret, null);
1660 if (success) {
1661 pw.println("Success: user unlocked");
1662 } else {
1663 getErrPrintWriter().println("Error: could not unlock user");
1664 }
1665 return 0;
1666 }
1667
1668 static final class StopUserCallback extends IStopUserCallback.Stub {
1669 private boolean mFinished = false;
1670
1671 public synchronized void waitForFinish() {
1672 try {
1673 while (!mFinished) wait();
1674 } catch (InterruptedException e) {
1675 throw new IllegalStateException(e);
1676 }
1677 }
1678
1679 @Override
1680 public synchronized void userStopped(int userId) {
1681 mFinished = true;
1682 notifyAll();
1683 }
1684
1685 @Override
1686 public synchronized void userStopAborted(int userId) {
1687 mFinished = true;
1688 notifyAll();
1689 }
1690 }
1691
1692 int runStopUser(PrintWriter pw) throws RemoteException {
1693 boolean wait = false;
1694 boolean force = false;
1695 String opt;
1696 while ((opt = getNextOption()) != null) {
1697 if ("-w".equals(opt)) {
1698 wait = true;
1699 } else if ("-f".equals(opt)) {
1700 force = true;
1701 } else {
1702 getErrPrintWriter().println("Error: unknown option: " + opt);
1703 return -1;
1704 }
1705 }
1706 int user = Integer.parseInt(getNextArgRequired());
1707 StopUserCallback callback = wait ? new StopUserCallback() : null;
1708
1709 int res = mInterface.stopUser(user, force, callback);
1710 if (res != ActivityManager.USER_OP_SUCCESS) {
1711 String txt = "";
1712 switch (res) {
1713 case ActivityManager.USER_OP_IS_CURRENT:
1714 txt = " (Can't stop current user)";
1715 break;
1716 case ActivityManager.USER_OP_UNKNOWN_USER:
1717 txt = " (Unknown user " + user + ")";
1718 break;
1719 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
1720 txt = " (System user cannot be stopped)";
1721 break;
1722 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP:
1723 txt = " (Can't stop user " + user
1724 + " - one of its related users can't be stopped)";
1725 break;
1726 }
1727 getErrPrintWriter().println("Switch failed: " + res + txt);
1728 return -1;
1729 } else if (callback != null) {
1730 callback.waitForFinish();
1731 }
1732 return 0;
1733 }
1734
1735 int runIsUserStopped(PrintWriter pw) {
1736 int userId = UserHandle.parseUserArg(getNextArgRequired());
1737 boolean stopped = mInternal.isUserStopped(userId);
1738 pw.println(stopped);
1739 return 0;
1740 }
1741
1742 int runGetStartedUserState(PrintWriter pw) throws RemoteException {
1743 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1744 "runGetStartedUserState()");
1745 final int userId = Integer.parseInt(getNextArgRequired());
1746 try {
1747 pw.println(mInternal.getStartedUserState(userId));
1748 } catch (NullPointerException e) {
1749 pw.println("User is not started: " + userId);
1750 }
Dianne Hackborn2e441072015-10-28 18:00:57 -07001751 return 0;
1752 }
1753
1754 int runTrackAssociations(PrintWriter pw) {
1755 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1756 "registerUidObserver()");
1757 synchronized (mInternal) {
1758 if (!mInternal.mTrackingAssociations) {
1759 mInternal.mTrackingAssociations = true;
1760 pw.println("Association tracking started.");
1761 } else {
1762 pw.println("Association tracking already enabled.");
1763 }
1764 }
1765 return 0;
1766 }
1767
1768 int runUntrackAssociations(PrintWriter pw) {
1769 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1770 "registerUidObserver()");
1771 synchronized (mInternal) {
1772 if (mInternal.mTrackingAssociations) {
1773 mInternal.mTrackingAssociations = false;
1774 mInternal.mAssociations.clear();
1775 pw.println("Association tracking stopped.");
1776 } else {
1777 pw.println("Association tracking not running.");
1778 }
1779 }
1780 return 0;
1781 }
1782
Felipe Leme2f1b2272016-03-25 16:15:02 -07001783 int getUidState(PrintWriter pw) throws RemoteException {
1784 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1785 "getUidState()");
1786 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
1787 pw.print(state);
1788 pw.print(" (");
1789 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
1790 pw.println(")");
1791 return 0;
1792 }
1793
Dianne Hackborn331084d2016-10-07 17:57:00 -07001794 private List<Configuration> getRecentConfigurations(int days) {
1795 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1796 Context.USAGE_STATS_SERVICE));
1797 final long now = System.currentTimeMillis();
1798 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
Sudheer Shanka28537b62016-09-07 11:12:31 -07001799 try {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001800 @SuppressWarnings("unchecked")
1801 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
1802 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
1803 if (configStatsSlice == null) {
1804 return Collections.emptyList();
1805 }
1806
1807 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
1808 final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
1809 final int configStatsListSize = configStatsList.size();
1810 for (int i = 0; i < configStatsListSize; i++) {
1811 final ConfigurationStats stats = configStatsList.get(i);
1812 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
1813 if (indexOfKey < 0) {
1814 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
1815 } else {
1816 recentConfigs.setValueAt(indexOfKey,
1817 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
1818 }
1819 }
1820
1821 final Comparator<Configuration> comparator = new Comparator<Configuration>() {
1822 @Override
1823 public int compare(Configuration a, Configuration b) {
1824 return recentConfigs.get(b).compareTo(recentConfigs.get(a));
1825 }
1826 };
1827
1828 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
1829 configs.addAll(recentConfigs.keySet());
1830 Collections.sort(configs, comparator);
1831 return configs;
1832
1833 } catch (RemoteException e) {
1834 return Collections.emptyList();
Sudheer Shanka28537b62016-09-07 11:12:31 -07001835 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001836 }
1837
1838 int runGetConfig(PrintWriter pw) throws RemoteException {
1839 int days = 14;
1840 String option = getNextOption();
1841 if (option != null) {
1842 if (!option.equals("--days")) {
1843 throw new IllegalArgumentException("unrecognized option " + option);
1844 }
1845
1846 days = Integer.parseInt(getNextArgRequired());
1847 if (days <= 0) {
1848 throw new IllegalArgumentException("--days must be a positive integer");
1849 }
1850 }
1851
1852 Configuration config = mInterface.getConfiguration();
1853 if (config == null) {
1854 getErrPrintWriter().println("Activity manager has no configuration");
1855 return -1;
1856 }
1857
1858 pw.println("config: " + Configuration.resourceQualifierString(config));
1859 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
1860
1861 final List<Configuration> recentConfigs = getRecentConfigurations(days);
1862 final int recentConfigSize = recentConfigs.size();
1863 if (recentConfigSize > 0) {
1864 pw.println("recentConfigs:");
1865 }
1866
1867 for (int i = 0; i < recentConfigSize; i++) {
1868 pw.println(" config: " + Configuration.resourceQualifierString(
1869 recentConfigs.get(i)));
1870 }
1871 return 0;
1872 }
1873
1874 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
1875 boolean suppress = Boolean.valueOf(getNextArgRequired());
1876 mInterface.suppressResizeConfigChanges(suppress);
1877 return 0;
1878 }
1879
1880 int runSetInactive(PrintWriter pw) throws RemoteException {
1881 int userId = UserHandle.USER_CURRENT;
1882
1883 String opt;
1884 while ((opt=getNextOption()) != null) {
1885 if (opt.equals("--user")) {
1886 userId = UserHandle.parseUserArg(getNextArgRequired());
1887 } else {
1888 getErrPrintWriter().println("Error: Unknown option: " + opt);
1889 return -1;
1890 }
1891 }
1892 String packageName = getNextArgRequired();
1893 String value = getNextArgRequired();
1894
1895 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1896 Context.USAGE_STATS_SERVICE));
1897 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId);
1898 return 0;
1899 }
1900
Amith Yamasaniafbccb72017-11-27 10:44:24 -08001901 private int bucketNameToBucketValue(String name) {
1902 String lower = name.toLowerCase();
1903 if (lower.startsWith("ac")) {
1904 return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
1905 } else if (lower.startsWith("wo")) {
1906 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
1907 } else if (lower.startsWith("fr")) {
1908 return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
1909 } else if (lower.startsWith("ra")) {
1910 return UsageStatsManager.STANDBY_BUCKET_RARE;
1911 } else if (lower.startsWith("ne")) {
1912 return UsageStatsManager.STANDBY_BUCKET_NEVER;
1913 } else {
1914 try {
1915 int bucket = Integer.parseInt(lower);
1916 return bucket;
1917 } catch (NumberFormatException nfe) {
1918 getErrPrintWriter().println("Error: Unknown bucket: " + name);
1919 }
1920 }
1921 return -1;
1922 }
1923
Amith Yamasani17fffee2017-09-29 13:17:43 -07001924 int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
1925 int userId = UserHandle.USER_CURRENT;
1926
1927 String opt;
1928 while ((opt=getNextOption()) != null) {
1929 if (opt.equals("--user")) {
1930 userId = UserHandle.parseUserArg(getNextArgRequired());
1931 } else {
1932 getErrPrintWriter().println("Error: Unknown option: " + opt);
1933 return -1;
1934 }
1935 }
1936 String packageName = getNextArgRequired();
1937 String value = getNextArgRequired();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08001938 int bucket = bucketNameToBucketValue(value);
1939 if (bucket < 0) return -1;
Amith Yamasanie8789312017-12-10 14:34:26 -08001940 boolean multiple = peekNextArg() != null;
1941
Amith Yamasani17fffee2017-09-29 13:17:43 -07001942
1943 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1944 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08001945 if (!multiple) {
1946 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
1947 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08001948 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
1949 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08001950 while ((packageName = getNextArg()) != null) {
1951 value = getNextArgRequired();
1952 bucket = bucketNameToBucketValue(value);
1953 if (bucket < 0) continue;
Suprabh Shukla868bde22018-02-20 20:59:52 -08001954 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08001955 }
Suprabh Shukla868bde22018-02-20 20:59:52 -08001956 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
1957 usm.setAppStandbyBuckets(slice, userId);
Amith Yamasanie8789312017-12-10 14:34:26 -08001958 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -08001959 return 0;
1960 }
1961
1962 int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
1963 int userId = UserHandle.USER_CURRENT;
1964
1965 String opt;
1966 while ((opt=getNextOption()) != null) {
1967 if (opt.equals("--user")) {
1968 userId = UserHandle.parseUserArg(getNextArgRequired());
1969 } else {
1970 getErrPrintWriter().println("Error: Unknown option: " + opt);
1971 return -1;
1972 }
1973 }
Amith Yamasanie8789312017-12-10 14:34:26 -08001974 String packageName = getNextArg();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08001975
1976 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1977 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08001978 if (packageName != null) {
1979 int bucket = usm.getAppStandbyBucket(packageName, null, userId);
1980 pw.println(bucket);
1981 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08001982 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -08001983 SHELL_PACKAGE_NAME, userId);
Suprabh Shukla868bde22018-02-20 20:59:52 -08001984 for (AppStandbyInfo bucketInfo : buckets.getList()) {
1985 pw.print(bucketInfo.mPackageName); pw.print(": ");
1986 pw.println(bucketInfo.mStandbyBucket);
Amith Yamasanie8789312017-12-10 14:34:26 -08001987 }
1988 }
Amith Yamasani17fffee2017-09-29 13:17:43 -07001989 return 0;
1990 }
1991
Dianne Hackborn331084d2016-10-07 17:57:00 -07001992 int runGetInactive(PrintWriter pw) throws RemoteException {
1993 int userId = UserHandle.USER_CURRENT;
1994
1995 String opt;
1996 while ((opt=getNextOption()) != null) {
1997 if (opt.equals("--user")) {
1998 userId = UserHandle.parseUserArg(getNextArgRequired());
1999 } else {
2000 getErrPrintWriter().println("Error: Unknown option: " + opt);
2001 return -1;
2002 }
2003 }
2004 String packageName = getNextArgRequired();
2005
2006 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2007 Context.USAGE_STATS_SERVICE));
2008 boolean isIdle = usm.isAppInactive(packageName, userId);
2009 pw.println("Idle=" + isIdle);
2010 return 0;
2011 }
2012
2013 int runSendTrimMemory(PrintWriter pw) throws RemoteException {
2014 int userId = UserHandle.USER_CURRENT;
2015 String opt;
2016 while ((opt = getNextOption()) != null) {
2017 if (opt.equals("--user")) {
2018 userId = UserHandle.parseUserArg(getNextArgRequired());
2019 if (userId == UserHandle.USER_ALL) {
2020 getErrPrintWriter().println("Error: Can't use user 'all'");
2021 return -1;
2022 }
2023 } else {
2024 getErrPrintWriter().println("Error: Unknown option: " + opt);
2025 return -1;
2026 }
2027 }
2028
2029 String proc = getNextArgRequired();
2030 String levelArg = getNextArgRequired();
2031 int level;
2032 switch (levelArg) {
2033 case "HIDDEN":
2034 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
2035 break;
2036 case "RUNNING_MODERATE":
2037 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
2038 break;
2039 case "BACKGROUND":
2040 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
2041 break;
2042 case "RUNNING_LOW":
2043 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
2044 break;
2045 case "MODERATE":
2046 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
2047 break;
2048 case "RUNNING_CRITICAL":
2049 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
2050 break;
2051 case "COMPLETE":
2052 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
2053 break;
2054 default:
Dianne Hackborne51505a2017-08-07 17:13:52 -07002055 try {
2056 level = Integer.parseInt(levelArg);
2057 } catch (NumberFormatException e) {
2058 getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
2059 return -1;
2060 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002061 }
2062 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
2063 getErrPrintWriter().println("Unknown error: failed to set trim level");
2064 return -1;
2065 }
2066 return 0;
2067 }
2068
Andrii Kulian839def92016-11-02 10:58:58 -07002069 int runDisplay(PrintWriter pw) throws RemoteException {
2070 String op = getNextArgRequired();
2071 switch (op) {
2072 case "move-stack":
2073 return runDisplayMoveStack(pw);
2074 default:
2075 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2076 return -1;
2077 }
2078 }
2079
Dianne Hackborn331084d2016-10-07 17:57:00 -07002080 int runStack(PrintWriter pw) throws RemoteException {
2081 String op = getNextArgRequired();
2082 switch (op) {
2083 case "start":
2084 return runStackStart(pw);
Andrii Kulian839def92016-11-02 10:58:58 -07002085 case "move-task":
Dianne Hackborn331084d2016-10-07 17:57:00 -07002086 return runStackMoveTask(pw);
2087 case "resize":
2088 return runStackResize(pw);
2089 case "resize-animated":
2090 return runStackResizeAnimated(pw);
2091 case "resize-docked-stack":
2092 return runStackResizeDocked(pw);
2093 case "positiontask":
2094 return runStackPositionTask(pw);
2095 case "list":
2096 return runStackList(pw);
2097 case "info":
2098 return runStackInfo(pw);
2099 case "move-top-activity-to-pinned-stack":
2100 return runMoveTopActivityToPinnedStack(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002101 case "remove":
2102 return runStackRemove(pw);
2103 default:
2104 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2105 return -1;
2106 }
2107 }
2108
2109
2110 private Rect getBounds() {
2111 String leftStr = getNextArgRequired();
2112 int left = Integer.parseInt(leftStr);
2113 String topStr = getNextArgRequired();
2114 int top = Integer.parseInt(topStr);
2115 String rightStr = getNextArgRequired();
2116 int right = Integer.parseInt(rightStr);
2117 String bottomStr = getNextArgRequired();
2118 int bottom = Integer.parseInt(bottomStr);
2119 if (left < 0) {
2120 getErrPrintWriter().println("Error: bad left arg: " + leftStr);
2121 return null;
2122 }
2123 if (top < 0) {
2124 getErrPrintWriter().println("Error: bad top arg: " + topStr);
2125 return null;
2126 }
2127 if (right <= 0) {
2128 getErrPrintWriter().println("Error: bad right arg: " + rightStr);
2129 return null;
2130 }
2131 if (bottom <= 0) {
2132 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr);
2133 return null;
2134 }
2135 return new Rect(left, top, right, bottom);
2136 }
2137
Andrii Kulian839def92016-11-02 10:58:58 -07002138 int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
2139 String stackIdStr = getNextArgRequired();
2140 int stackId = Integer.parseInt(stackIdStr);
2141 String displayIdStr = getNextArgRequired();
2142 int displayId = Integer.parseInt(displayIdStr);
2143 mInterface.moveStackToDisplay(stackId, displayId);
2144 return 0;
2145 }
2146
Dianne Hackborn331084d2016-10-07 17:57:00 -07002147 int runStackStart(PrintWriter pw) throws RemoteException {
2148 String displayIdStr = getNextArgRequired();
2149 int displayId = Integer.parseInt(displayIdStr);
2150 Intent intent;
2151 try {
2152 intent = makeIntent(UserHandle.USER_CURRENT);
2153 } catch (URISyntaxException e) {
2154 throw new RuntimeException(e.getMessage(), e);
2155 }
2156
Andrii Kulianb1cdb102017-07-13 15:33:06 -07002157 final int stackId = mInterface.createStackOnDisplay(displayId);
2158 if (stackId != INVALID_STACK_ID) {
2159 // TODO: Need proper support if this is used by test...
2160// container.startActivity(intent);
2161// ActivityOptions options = ActivityOptions.makeBasic();
2162// options.setLaunchDisplayId(displayId);
2163// options.setLaunchStackId(stackId);
2164// mInterface.startAct
2165// mInterface.startActivityAsUser(null, null, intent, mimeType,
2166// null, null, 0, mStartFlags, profilerInfo,
2167// options != null ? options.toBundle() : null, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002168 }
2169 return 0;
2170 }
2171
2172 int runStackMoveTask(PrintWriter pw) throws RemoteException {
2173 String taskIdStr = getNextArgRequired();
2174 int taskId = Integer.parseInt(taskIdStr);
2175 String stackIdStr = getNextArgRequired();
2176 int stackId = Integer.parseInt(stackIdStr);
2177 String toTopStr = getNextArgRequired();
2178 final boolean toTop;
2179 if ("true".equals(toTopStr)) {
2180 toTop = true;
2181 } else if ("false".equals(toTopStr)) {
2182 toTop = false;
2183 } else {
2184 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr);
2185 return -1;
2186 }
2187
2188 mInterface.moveTaskToStack(taskId, stackId, toTop);
2189 return 0;
2190 }
2191
2192 int runStackResize(PrintWriter pw) throws RemoteException {
2193 String stackIdStr = getNextArgRequired();
2194 int stackId = Integer.parseInt(stackIdStr);
2195 final Rect bounds = getBounds();
2196 if (bounds == null) {
2197 getErrPrintWriter().println("Error: invalid input bounds");
2198 return -1;
2199 }
2200 return resizeStack(stackId, bounds, 0);
2201 }
2202
2203 int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
2204 String stackIdStr = getNextArgRequired();
2205 int stackId = Integer.parseInt(stackIdStr);
2206 final Rect bounds;
2207 if ("null".equals(peekNextArg())) {
2208 bounds = null;
2209 } else {
2210 bounds = getBounds();
2211 if (bounds == null) {
2212 getErrPrintWriter().println("Error: invalid input bounds");
2213 return -1;
2214 }
2215 }
2216 return resizeStackUnchecked(stackId, bounds, 0, true);
2217 }
2218
2219 int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate)
2220 throws RemoteException {
2221 try {
2222 mInterface.resizeStack(stackId, bounds, false, false, animate, -1);
2223 Thread.sleep(delayMs);
2224 } catch (InterruptedException e) {
2225 }
2226 return 0;
2227 }
2228
2229 int runStackResizeDocked(PrintWriter pw) throws RemoteException {
2230 final Rect bounds = getBounds();
2231 final Rect taskBounds = getBounds();
2232 if (bounds == null || taskBounds == null) {
2233 getErrPrintWriter().println("Error: invalid input bounds");
2234 return -1;
2235 }
2236 mInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
2237 return 0;
2238 }
2239
2240 int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException {
2241 if (bounds == null) {
2242 getErrPrintWriter().println("Error: invalid input bounds");
2243 return -1;
2244 }
2245 return resizeStackUnchecked(stackId, bounds, delayMs, false);
2246 }
2247
2248 int runStackPositionTask(PrintWriter pw) throws RemoteException {
2249 String taskIdStr = getNextArgRequired();
2250 int taskId = Integer.parseInt(taskIdStr);
2251 String stackIdStr = getNextArgRequired();
2252 int stackId = Integer.parseInt(stackIdStr);
2253 String positionStr = getNextArgRequired();
2254 int position = Integer.parseInt(positionStr);
2255
2256 mInterface.positionTaskInStack(taskId, stackId, position);
2257 return 0;
2258 }
2259
2260 int runStackList(PrintWriter pw) throws RemoteException {
2261 List<ActivityManager.StackInfo> stacks = mInterface.getAllStackInfos();
2262 for (ActivityManager.StackInfo info : stacks) {
2263 pw.println(info);
2264 }
2265 return 0;
2266 }
2267
2268 int runStackInfo(PrintWriter pw) throws RemoteException {
Wale Ogunwale68278562017-09-23 17:13:55 -07002269 int windowingMode = Integer.parseInt(getNextArgRequired());
2270 int activityType = Integer.parseInt(getNextArgRequired());
2271 ActivityManager.StackInfo info = mInterface.getStackInfo(windowingMode, activityType);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002272 pw.println(info);
2273 return 0;
2274 }
2275
2276 int runStackRemove(PrintWriter pw) throws RemoteException {
2277 String stackIdStr = getNextArgRequired();
2278 int stackId = Integer.parseInt(stackIdStr);
2279 mInterface.removeStack(stackId);
2280 return 0;
2281 }
2282
2283 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException {
2284 int stackId = Integer.parseInt(getNextArgRequired());
2285 final Rect bounds = getBounds();
2286 if (bounds == null) {
2287 getErrPrintWriter().println("Error: invalid input bounds");
2288 return -1;
2289 }
2290
2291 if (!mInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
2292 getErrPrintWriter().println("Didn't move top activity to pinned stack.");
2293 return -1;
2294 }
2295 return 0;
2296 }
2297
Dianne Hackborn331084d2016-10-07 17:57:00 -07002298 void setBoundsSide(Rect bounds, String side, int value) {
2299 switch (side) {
2300 case "l":
2301 bounds.left = value;
2302 break;
2303 case "r":
2304 bounds.right = value;
2305 break;
2306 case "t":
2307 bounds.top = value;
2308 break;
2309 case "b":
2310 bounds.bottom = value;
2311 break;
2312 default:
2313 getErrPrintWriter().println("Unknown set side: " + side);
2314 break;
2315 }
2316 }
2317
2318 int runTask(PrintWriter pw) throws RemoteException {
2319 String op = getNextArgRequired();
2320 if (op.equals("lock")) {
2321 return runTaskLock(pw);
2322 } else if (op.equals("resizeable")) {
2323 return runTaskResizeable(pw);
2324 } else if (op.equals("resize")) {
2325 return runTaskResize(pw);
David Stevensee9e2772017-02-09 16:30:27 -08002326 } else if (op.equals("focus")) {
2327 return runTaskFocus(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002328 } else {
2329 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2330 return -1;
2331 }
2332 }
2333
2334 int runTaskLock(PrintWriter pw) throws RemoteException {
2335 String taskIdStr = getNextArgRequired();
2336 if (taskIdStr.equals("stop")) {
Benjamin Franza83859f2017-07-03 16:34:14 +01002337 mInterface.stopSystemLockTaskMode();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002338 } else {
2339 int taskId = Integer.parseInt(taskIdStr);
Winson Chungbb348802017-01-30 12:01:45 -08002340 mInterface.startSystemLockTaskMode(taskId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002341 }
2342 pw.println("Activity manager is " + (mInterface.isInLockTaskMode() ? "" : "not ") +
2343 "in lockTaskMode");
2344 return 0;
2345 }
2346
2347 int runTaskResizeable(PrintWriter pw) throws RemoteException {
2348 final String taskIdStr = getNextArgRequired();
2349 final int taskId = Integer.parseInt(taskIdStr);
2350 final String resizeableStr = getNextArgRequired();
2351 final int resizeableMode = Integer.parseInt(resizeableStr);
2352 mInterface.setTaskResizeable(taskId, resizeableMode);
2353 return 0;
2354 }
2355
2356 int runTaskResize(PrintWriter pw) throws RemoteException {
2357 final String taskIdStr = getNextArgRequired();
2358 final int taskId = Integer.parseInt(taskIdStr);
2359 final Rect bounds = getBounds();
2360 if (bounds == null) {
2361 getErrPrintWriter().println("Error: invalid input bounds");
2362 return -1;
2363 }
2364 taskResize(taskId, bounds, 0, false);
2365 return 0;
2366 }
2367
2368 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
2369 throws RemoteException {
2370 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
2371 mInterface.resizeTask(taskId, bounds, resizeMode);
2372 try {
2373 Thread.sleep(delay_ms);
2374 } catch (InterruptedException e) {
2375 }
2376 }
2377
Dianne Hackborn331084d2016-10-07 17:57:00 -07002378 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
2379 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
2380 throws RemoteException {
2381 int maxMove;
2382 if (movingForward) {
2383 while (maxToTravel > 0
2384 && ((horizontal && taskRect.right < stackRect.right)
2385 ||(!horizontal && taskRect.bottom < stackRect.bottom))) {
2386 if (horizontal) {
2387 maxMove = Math.min(stepSize, stackRect.right - taskRect.right);
2388 maxToTravel -= maxMove;
2389 taskRect.right += maxMove;
2390 taskRect.left += maxMove;
2391 } else {
2392 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom);
2393 maxToTravel -= maxMove;
2394 taskRect.top += maxMove;
2395 taskRect.bottom += maxMove;
2396 }
2397 taskResize(taskId, taskRect, delay_ms, false);
2398 }
2399 } else {
2400 while (maxToTravel < 0
2401 && ((horizontal && taskRect.left > stackRect.left)
2402 ||(!horizontal && taskRect.top > stackRect.top))) {
2403 if (horizontal) {
2404 maxMove = Math.min(stepSize, taskRect.left - stackRect.left);
2405 maxToTravel -= maxMove;
2406 taskRect.right -= maxMove;
2407 taskRect.left -= maxMove;
2408 } else {
2409 maxMove = Math.min(stepSize, taskRect.top - stackRect.top);
2410 maxToTravel -= maxMove;
2411 taskRect.top -= maxMove;
2412 taskRect.bottom -= maxMove;
2413 }
2414 taskResize(taskId, taskRect, delay_ms, false);
2415 }
2416 }
2417 // Return the remaining distance we didn't travel because we reached the target location.
2418 return maxToTravel;
2419 }
2420
2421 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) {
2422 int stepSize = 0;
2423 if (greaterThanTarget && target < current) {
2424 current -= inStepSize;
2425 stepSize = inStepSize;
2426 if (target > current) {
2427 stepSize -= (target - current);
2428 }
2429 }
2430 if (!greaterThanTarget && target > current) {
2431 current += inStepSize;
2432 stepSize = inStepSize;
2433 if (target < current) {
2434 stepSize += (current - target);
2435 }
2436 }
2437 return stepSize;
2438 }
2439
David Stevensee9e2772017-02-09 16:30:27 -08002440 int runTaskFocus(PrintWriter pw) throws RemoteException {
2441 final int taskId = Integer.parseInt(getNextArgRequired());
2442 pw.println("Setting focus to task " + taskId);
2443 mInterface.setFocusedTask(taskId);
2444 return 0;
2445 }
2446
Dianne Hackborn331084d2016-10-07 17:57:00 -07002447 int runWrite(PrintWriter pw) {
2448 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2449 "registerUidObserver()");
Winson Chung3f0e59a2017-10-25 10:19:05 -07002450 mInternal.getRecentTasks().flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002451 pw.println("All tasks persisted.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002452 return 0;
2453 }
2454
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002455 int runAttachAgent(PrintWriter pw) {
2456 // TODO: revisit the permissions required for attaching agents
2457 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2458 "attach-agent");
2459 String process = getNextArgRequired();
2460 String agent = getNextArgRequired();
2461 String opt;
2462 if ((opt = getNextArg()) != null) {
2463 pw.println("Error: Unknown option: " + opt);
2464 return -1;
2465 }
2466 mInternal.attachAgent(process, agent);
2467 return 0;
2468 }
2469
Michael Kwan94438b72016-11-03 15:30:34 -07002470 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
Matthew Ng626e0cc2016-12-07 17:25:53 -08002471 final Resources res = getResources(pw);
2472 if (res == null) {
2473 return -1;
2474 }
Erik Wolsheimer9be3a062017-05-31 14:59:57 -07002475 pw.println(ActivityManager.supportsMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002476 return 0;
2477 }
2478
2479 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException {
2480 final Resources res = getResources(pw);
2481 if (res == null) {
2482 return -1;
2483 }
Erik Wolsheimer9be3a062017-05-31 14:59:57 -07002484 pw.println(ActivityManager.supportsSplitScreenMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002485 return 0;
2486 }
2487
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002488 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
2489 int userid = UserHandle.parseUserArg(getNextArgRequired());
2490 ArrayList<String> packages = new ArrayList<>();
2491 packages.add(getNextArgRequired());
2492 String packageName;
2493 while ((packageName = getNextArg()) != null) {
2494 packages.add(packageName);
2495 }
2496 mInternal.scheduleApplicationInfoChanged(packages, userid);
2497 pw.println("Packages updated with most recent ApplicationInfos.");
2498 return 0;
2499 }
2500
Arthur Hsuf3f3a602017-02-21 14:01:53 -08002501 int runNoHomeScreen(PrintWriter pw) throws RemoteException {
2502 final Resources res = getResources(pw);
2503 if (res == null) {
2504 return -1;
2505 }
2506 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen));
2507 return 0;
2508 }
2509
Jeff Sharkeyfd658132017-05-03 11:38:01 -06002510 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
2511 mInternal.waitForBroadcastIdle(pw);
2512 return 0;
2513 }
2514
Matthew Ng626e0cc2016-12-07 17:25:53 -08002515 private Resources getResources(PrintWriter pw) throws RemoteException {
Michael Kwan94438b72016-11-03 15:30:34 -07002516 // system resources does not contain all the device configuration, construct it manually.
2517 Configuration config = mInterface.getConfiguration();
2518 if (config == null) {
2519 pw.println("Error: Activity manager has no configuration");
Matthew Ng626e0cc2016-12-07 17:25:53 -08002520 return null;
Michael Kwan94438b72016-11-03 15:30:34 -07002521 }
2522
2523 final DisplayMetrics metrics = new DisplayMetrics();
2524 metrics.setToDefaults();
2525
Matthew Ng626e0cc2016-12-07 17:25:53 -08002526 return new Resources(AssetManager.getSystem(), metrics, config);
Michael Kwan94438b72016-11-03 15:30:34 -07002527 }
2528
Dianne Hackborn2e441072015-10-28 18:00:57 -07002529 @Override
2530 public void onHelp() {
2531 PrintWriter pw = getOutPrintWriter();
2532 dumpHelp(pw, mDumping);
2533 }
2534
2535 static void dumpHelp(PrintWriter pw, boolean dumping) {
2536 if (dumping) {
2537 pw.println("Activity manager dump options:");
2538 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
2539 pw.println(" WHAT may be one of:");
2540 pw.println(" a[ctivities]: activity stack state");
2541 pw.println(" r[recents]: recent activities state");
2542 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002543 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002544 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
2545 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
2546 pw.println(" o[om]: out of memory management");
2547 pw.println(" perm[issions]: URI permission grant state");
2548 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
2549 pw.println(" provider [COMP_SPEC]: provider client-side state");
2550 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
2551 pw.println(" as[sociations]: tracked app associations");
Dianne Hackborn0ef403e2017-01-24 18:22:15 -08002552 pw.println(" settings: currently applied config settings");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002553 pw.println(" service [COMP_SPEC]: service client-side state");
2554 pw.println(" package [PACKAGE_NAME]: all state related to given package");
2555 pw.println(" all: dump all activities");
2556 pw.println(" top: dump the top activity");
2557 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
2558 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
2559 pw.println(" a partial substring in a component name, a");
2560 pw.println(" hex object identifier.");
2561 pw.println(" -a: include all available server state.");
2562 pw.println(" -c: include client state.");
2563 pw.println(" -p: limit output to given package.");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002564 pw.println(" --checkin: output checkin format, resetting data.");
2565 pw.println(" --C: output checkin format, not resetting data.");
Steven Timotius4346f0a2017-09-12 11:07:21 -07002566 pw.println(" --proto: output dump in protocol buffer format.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002567 } else {
2568 pw.println("Activity manager (activity) commands:");
2569 pw.println(" help");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002570 pw.println(" Print this help text.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002571 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002572 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002573 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002574 pw.println(" Start an Activity. Options are:");
2575 pw.println(" -D: enable debugging");
2576 pw.println(" -N: enable native debugging");
2577 pw.println(" -W: wait for launch to complete");
2578 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>");
2579 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2580 pw.println(" between samples (use with --start-profiler)");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002581 pw.println(" --streaming: stream the profiling output to the specified file");
2582 pw.println(" (use with --start-profiler)");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002583 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
Andreas Gampe83085bb2017-06-26 17:54:11 -07002584 pw.println(" --attach-agent <agent>: attach the given agent before binding");
Andreas Gampeab8a63b2018-01-05 13:55:15 -08002585 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002586 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
2587 pw.println(" the top activity will be finished.");
2588 pw.println(" -S: force stop the target app before starting the activity");
2589 pw.println(" --track-allocation: enable tracking of object allocations");
2590 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2591 pw.println(" specified then run as the current user.");
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002592 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into.");
2593 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002594 pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
2595 pw.println(" Start a Service. Options are:");
2596 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2597 pw.println(" specified then run as the current user.");
Jaewan Kim329b35f2017-04-11 11:19:49 +09002598 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
2599 pw.println(" Start a foreground Service. Options are:");
2600 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2601 pw.println(" specified then run as the current user.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002602 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
2603 pw.println(" Stop a Service. Options are:");
2604 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2605 pw.println(" specified then run as the current user.");
2606 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>");
2607 pw.println(" Send a broadcast Intent. Options are:");
2608 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not");
2609 pw.println(" specified then send to all users.");
2610 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002611 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
David Brazdild5d42172018-02-14 19:39:03 +00002612 pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
Dianne Hackborn28824062016-10-18 13:19:20 -07002613 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
2614 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
2615 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
2616 pw.println(" is only one instrumentation. Options are:");
2617 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with");
2618 pw.println(" [-e perf true] to generate raw output for performance measurements.");
2619 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a");
2620 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]].");
2621 pw.println(" -p <FILE>: write profiling data to <FILE>");
Mike Mad2239822017-10-31 12:30:42 -07002622 pw.println(" -m: Write output as protobuf to stdout (machine readable)");
2623 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine");
2624 pw.println(" readable). If path is not specified, default directory and file name will");
2625 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto");
Dianne Hackborn28824062016-10-18 13:19:20 -07002626 pw.println(" -w: wait for instrumentation to finish before returning. Required for");
2627 pw.println(" test runners.");
2628 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
2629 pw.println(" current user if not specified.");
David Brazdild5d42172018-02-14 19:39:03 +00002630 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002631 pw.println(" --no-window-animation: turn off window animations while running.");
2632 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
2633 pw.println(" This assumes that the process supports the selected ABI.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002634 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]");
2635 pw.println(" Trace IPC transactions.");
2636 pw.println(" start: start tracing IPC transactions.");
2637 pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
2638 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
2639 pw.println(" profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002640 pw.println(" [--streaming] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002641 pw.println(" Start and stop profiler on a process. The given <PROCESS> argument");
2642 pw.println(" may be either a process name or pid. Options are:");
2643 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2644 pw.println(" specify user of process to profile; uses current user if not specified.");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002645 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2646 pw.println(" between samples");
2647 pw.println(" --streaming: stream the profiling output to the specified file");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002648 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002649 pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
2650 pw.println(" be either a process name or pid. Options are:");
2651 pw.println(" -n: dump native heap instead of managed heap");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002652 pw.println(" -g: force GC before dumping the heap");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002653 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2654 pw.println(" specify user of process to dump; uses current user if not specified.");
2655 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>");
2656 pw.println(" Set application <PACKAGE> to debug. Options are:");
2657 pw.println(" -w: wait for debugger when application starts");
2658 pw.println(" --persistent: retain this value");
2659 pw.println(" clear-debug-app");
2660 pw.println(" Clear the previously set-debug-app.");
2661 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>");
2662 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or");
2663 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
2664 pw.println(" clear-watch-heap");
2665 pw.println(" Clear the previously set-watch-heap.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002666 pw.println(" bug-report [--progress | --telephony]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002667 pw.println(" Request bug report generation; will launch a notification");
2668 pw.println(" when done to select where it should be delivered. Options are:");
2669 pw.println(" --progress: will launch a notification right away to show its progress.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002670 pw.println(" --telephony: will dump only telephony sections.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002671 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002672 pw.println(" Completely stop the given application package.");
Christopher Tate8aa8fe12017-01-20 17:50:32 -08002673 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>");
2674 pw.println(" Induce a VM crash in the specified package or process");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002675 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002676 pw.println(" Kill all processes associated with the given application.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002677 pw.println(" kill-all");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002678 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn85e35642017-01-12 15:10:57 -08002679 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
2680 pw.println(" If the given application's uid is in the background and waiting to");
2681 pw.println(" become idle (not allowing background services), do that now.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002682 pw.println(" monitor [--gdb <port>]");
2683 pw.println(" Start monitoring for crashes or ANRs.");
2684 pw.println(" --gdb: start gdbserv on the given port at crash/ANR");
Dianne Hackborne51505a2017-08-07 17:13:52 -07002685 pw.println(" watch-uids [--oom <uid>");
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01002686 pw.println(" Start watching for and reporting uid state changes.");
Dianne Hackborne51505a2017-08-07 17:13:52 -07002687 pw.println(" --oom: specify a uid for which to report detailed change messages.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002688 pw.println(" hang [--allow-restart]");
2689 pw.println(" Hang the system.");
2690 pw.println(" --allow-restart: allow watchdog to perform normal system restart");
2691 pw.println(" restart");
2692 pw.println(" Restart the user-space system.");
2693 pw.println(" idle-maintenance");
2694 pw.println(" Perform idle maintenance now.");
2695 pw.println(" screen-compat [on|off] <PACKAGE>");
2696 pw.println(" Control screen compatibility mode of <PACKAGE>.");
2697 pw.println(" package-importance <PACKAGE>");
2698 pw.println(" Print current importance of <PACKAGE>.");
2699 pw.println(" to-uri [INTENT]");
2700 pw.println(" Print the given Intent specification as a URI.");
2701 pw.println(" to-intent-uri [INTENT]");
2702 pw.println(" Print the given Intent specification as an intent: URI.");
2703 pw.println(" to-app-uri [INTENT]");
2704 pw.println(" Print the given Intent specification as an android-app: URI.");
2705 pw.println(" switch-user <USER_ID>");
2706 pw.println(" Switch to put USER_ID in the foreground, starting");
2707 pw.println(" execution of that user if it is currently stopped.");
2708 pw.println(" get-current-user");
2709 pw.println(" Returns id of the current foreground user.");
2710 pw.println(" start-user <USER_ID>");
2711 pw.println(" Start USER_ID in background if it is currently stopped;");
2712 pw.println(" use switch-user if you want to start the user in foreground");
2713 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]");
2714 pw.println(" Attempt to unlock the given user using the given authorization token.");
2715 pw.println(" stop-user [-w] [-f] <USER_ID>");
2716 pw.println(" Stop execution of USER_ID, not allowing it to run any");
2717 pw.println(" code until a later explicit start or switch to it.");
2718 pw.println(" -w: wait for stop-user to complete.");
2719 pw.println(" -f: force stop even if there are related users that cannot be stopped.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08002720 pw.println(" is-user-stopped <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002721 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002722 pw.println(" get-started-user-state <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002723 pw.println(" Gets the current state of the given started user.");
2724 pw.println(" track-associations");
2725 pw.println(" Enable association tracking.");
2726 pw.println(" untrack-associations");
2727 pw.println(" Disable and clear association tracking.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002728 pw.println(" get-uid-state <UID>");
2729 pw.println(" Gets the process state of an app given its <UID>.");
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002730 pw.println(" attach-agent <PROCESS> <FILE>");
2731 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 -07002732 pw.println(" get-config");
2733 pw.println(" Rtrieve the configuration and any recent configurations of the device.");
Michael Kwan94438b72016-11-03 15:30:34 -07002734 pw.println(" supports-multiwindow");
2735 pw.println(" Returns true if the device supports multiwindow.");
Matthew Ng626e0cc2016-12-07 17:25:53 -08002736 pw.println(" supports-split-screen-multi-window");
2737 pw.println(" Returns true if the device supports split screen multiwindow.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002738 pw.println(" suppress-resize-config-changes <true|false>");
2739 pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
2740 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
2741 pw.println(" Sets the inactive state of an app.");
2742 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
2743 pw.println(" Returns the inactive state of an app.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002744 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
Amith Yamasani17fffee2017-09-29 13:17:43 -07002745 pw.println(" Puts an app in the standby bucket.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002746 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
2747 pw.println(" Returns the standby bucket of an app.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002748 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
2749 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
Dianne Hackborne51505a2017-08-07 17:13:52 -07002750 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 -07002751 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays.");
2752 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>");
2753 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002754 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
2755 pw.println(" start <DISPLAY_ID> <INTENT>");
2756 pw.println(" Start a new activity on <DISPLAY_ID> using <INTENT>");
Andrii Kulian839def92016-11-02 10:58:58 -07002757 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002758 pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
2759 pw.println(" bottom (false) of <STACK_ID>.");
2760 pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
2761 pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.");
2762 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
2763 pw.println(" Same as resize, but allow animation.");
2764 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
2765 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
2766 pw.println(" and supplying temporary different task bounds indicated by");
2767 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002768 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
2769 pw.println(" Moves the top activity from");
2770 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
2771 pw.println(" bounds of the pinned stack.");
2772 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>");
2773 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
2774 pw.println(" list");
2775 pw.println(" List all of the activity stacks and their sizes.");
Wale Ogunwale68278562017-09-23 17:13:55 -07002776 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
2777 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002778 pw.println(" remove <STACK_ID>");
2779 pw.println(" Remove stack <STACK_ID>.");
2780 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
2781 pw.println(" lock <TASK_ID>");
2782 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run.");
2783 pw.println(" lock stop");
2784 pw.println(" End the current task lock.");
2785 pw.println(" resizeable <TASK_ID> [0|1|2|3]");
2786 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:");
2787 pw.println(" 0: unresizeable");
2788 pw.println(" 1: crop_windows");
2789 pw.println(" 2: resizeable");
2790 pw.println(" 3: resizeable_and_pipable");
2791 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
2792 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
2793 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
2794 pw.println(" has the specified bounds.");
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002795 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
2796 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
2797 pw.println(" without restarting any processes.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002798 pw.println(" write");
2799 pw.println(" Write all pending state to storage.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002800 pw.println();
2801 Intent.printIntentArgsHelp(pw, "");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002802 }
2803 }
2804}