blob: 85322d611f4182fd2f12edaba014851bb1ce8388 [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
Ng Zhi An8ab52a22018-08-29 10:20:33 -070019import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
Sudheer Shanka8f99bff2018-10-21 16:19:53 -070020import static android.app.ActivityTaskManager.INVALID_TASK_ID;
Felipe Lemeb546ca72018-08-15 08:44:12 -070021import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
22import static android.app.ActivityTaskManager.RESIZE_MODE_USER;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -080023import static android.app.WaitResult.launchStateToString;
Felipe Lemeb546ca72018-08-15 08:44:12 -070024import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
25import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
26import static android.view.Display.INVALID_DISPLAY;
27
Felipe Leme2f1b2272016-03-25 16:15:02 -070028import android.app.ActivityManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070029import android.app.ActivityOptions;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070030import android.app.ActivityTaskManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070031import android.app.AppGlobals;
Dianne Hackborn331084d2016-10-07 17:57:00 -070032import android.app.IActivityController;
Dianne Hackborn2e441072015-10-28 18:00:57 -070033import android.app.IActivityManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070034import android.app.IActivityTaskManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070035import android.app.IStopUserCallback;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +010036import android.app.IUidObserver;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080037import android.app.KeyguardManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070038import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070039import android.app.WaitResult;
Suprabh Shukla868bde22018-02-20 20:59:52 -080040import android.app.usage.AppStandbyInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070041import android.app.usage.ConfigurationStats;
42import android.app.usage.IUsageStatsManager;
43import android.app.usage.UsageStatsManager;
44import android.content.ComponentCallbacks2;
45import android.content.ComponentName;
46import android.content.Context;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080047import android.content.DeviceConfigurationProto;
48import android.content.GlobalConfigurationProto;
Dianne Hackborn331084d2016-10-07 17:57:00 -070049import android.content.IIntentReceiver;
Dianne Hackborn354736e2016-08-22 17:00:05 -070050import android.content.Intent;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080051import android.content.pm.ConfigurationInfo;
52import android.content.pm.FeatureInfo;
Dianne Hackborn354736e2016-08-22 17:00:05 -070053import android.content.pm.IPackageManager;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080054import android.content.pm.PackageManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070055import android.content.pm.ParceledListSlice;
Dianne Hackborn354736e2016-08-22 17:00:05 -070056import android.content.pm.ResolveInfo;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080057import android.content.pm.SharedLibraryInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070058import android.content.pm.UserInfo;
Michael Kwan94438b72016-11-03 15:30:34 -070059import android.content.res.AssetManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070060import android.content.res.Configuration;
Michael Kwan94438b72016-11-03 15:30:34 -070061import android.content.res.Resources;
Dianne Hackborn331084d2016-10-07 17:57:00 -070062import android.graphics.Rect;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080063import android.hardware.display.DisplayManager;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080064import android.opengl.GLES10;
Dianne Hackborn331084d2016-10-07 17:57:00 -070065import android.os.Binder;
66import android.os.Build;
67import android.os.Bundle;
Dianne Hackborn354736e2016-08-22 17:00:05 -070068import android.os.ParcelFileDescriptor;
Makoto Onuki2c6657f2018-06-06 15:24:02 -070069import android.os.RemoteCallback;
70import android.os.RemoteCallback.OnResultListener;
Dianne Hackborn2e441072015-10-28 18:00:57 -070071import android.os.RemoteException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070072import android.os.ServiceManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -070073import android.os.ShellCommand;
Dianne Hackborn5c3296a2017-12-13 17:52:26 -080074import android.os.StrictMode;
Dianne Hackborn354736e2016-08-22 17:00:05 -070075import android.os.SystemClock;
Dianne Hackborn331084d2016-10-07 17:57:00 -070076import android.os.SystemProperties;
Dianne Hackborn2e441072015-10-28 18:00:57 -070077import android.os.UserHandle;
Alex Chau5c0df232018-02-22 15:57:17 +080078import android.os.UserManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070079import android.text.TextUtils;
Makoto Onuki2c6657f2018-06-06 15:24:02 -070080import android.text.format.Time;
Dianne Hackborn331084d2016-10-07 17:57:00 -070081import android.util.ArrayMap;
Felipe Leme2f1b2272016-03-25 16:15:02 -070082import android.util.DebugUtils;
Michael Kwan94438b72016-11-03 15:30:34 -070083import android.util.DisplayMetrics;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080084import android.util.proto.ProtoOutputStream;
85import android.view.Display;
Dianne Hackborn2e441072015-10-28 18:00:57 -070086
Dianne Hackborn331084d2016-10-07 17:57:00 -070087import com.android.internal.util.HexDump;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080088import com.android.internal.util.MemInfoReader;
Dianne Hackborn331084d2016-10-07 17:57:00 -070089import com.android.internal.util.Preconditions;
90
91import java.io.BufferedReader;
92import java.io.File;
93import java.io.IOException;
94import java.io.InputStream;
95import java.io.InputStreamReader;
Dianne Hackborn2e441072015-10-28 18:00:57 -070096import java.io.PrintWriter;
Dianne Hackborn354736e2016-08-22 17:00:05 -070097import java.net.URISyntaxException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070098import java.util.ArrayList;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080099import java.util.Arrays;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700100import java.util.Collections;
101import java.util.Comparator;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800102import java.util.HashSet;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700103import java.util.List;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800104import java.util.Set;
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700105import java.util.concurrent.CountDownLatch;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700106
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800107import javax.microedition.khronos.egl.EGL10;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800108import javax.microedition.khronos.egl.EGLConfig;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800109import javax.microedition.khronos.egl.EGLContext;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800110import javax.microedition.khronos.egl.EGLDisplay;
111import javax.microedition.khronos.egl.EGLSurface;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800112
Dianne Hackborn331084d2016-10-07 17:57:00 -0700113final class ActivityManagerShellCommand extends ShellCommand {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700114 public static final String NO_CLASS_ERROR_CODE = "Error type 3";
Dianne Hackborn331084d2016-10-07 17:57:00 -0700115 private static final String SHELL_PACKAGE_NAME = "com.android.shell";
116
Dianne Hackborn2e441072015-10-28 18:00:57 -0700117 // IPC interface to activity manager -- don't need to do additional security checks.
118 final IActivityManager mInterface;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700119 final IActivityTaskManager mTaskInterface;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700120
121 // Internal service impl -- must perform security checks before touching.
122 final ActivityManagerService mInternal;
123
Dianne Hackborn354736e2016-08-22 17:00:05 -0700124 // Convenience for interacting with package manager.
125 final IPackageManager mPm;
126
127 private int mStartFlags = 0;
128 private boolean mWaitOption = false;
129 private boolean mStopOption = false;
130
131 private int mRepeat = 0;
132 private int mUserId;
133 private String mReceiverPermission;
134
135 private String mProfileFile;
136 private int mSamplingInterval;
137 private boolean mAutoStop;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800138 private boolean mStreaming; // Streaming the profiling output to a file.
Andreas Gampe83085bb2017-06-26 17:54:11 -0700139 private String mAgent; // Agent to attach on startup.
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800140 private boolean mAttachAgentDuringBind; // Whether agent should be attached late.
Andrii Kulian16802aa2016-11-02 12:21:33 -0700141 private int mDisplayId;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700142 private int mWindowingMode;
143 private int mActivityType;
Winson Chung6954fc92017-03-24 16:22:12 -0700144 private int mTaskId;
145 private boolean mIsTaskOverlay;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000146 private boolean mIsLockTask;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700147
Dianne Hackborn2e441072015-10-28 18:00:57 -0700148 final boolean mDumping;
149
150 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
151 mInterface = service;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700152 mTaskInterface = service.mActivityTaskManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700153 mInternal = service;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700154 mPm = AppGlobals.getPackageManager();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700155 mDumping = dumping;
156 }
157
158 @Override
159 public int onCommand(String cmd) {
160 if (cmd == null) {
161 return handleDefaultCommands(cmd);
162 }
Dianne Hackborn5c3296a2017-12-13 17:52:26 -0800163 final PrintWriter pw = getOutPrintWriter();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700164 try {
165 switch (cmd) {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700166 case "start":
167 case "start-activity":
168 return runStartActivity(pw);
169 case "startservice":
170 case "start-service":
Christopher Tate7e1368d2017-03-30 17:20:12 -0700171 return runStartService(pw, false);
172 case "startforegroundservice":
173 case "startfgservice":
174 case "start-foreground-service":
175 case "start-fg-service":
176 return runStartService(pw, true);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700177 case "stopservice":
178 case "stop-service":
Dianne Hackborn331084d2016-10-07 17:57:00 -0700179 return runStopService(pw);
180 case "broadcast":
181 return runSendBroadcast(pw);
182 case "instrument":
Dianne Hackborn28824062016-10-18 13:19:20 -0700183 getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");
184 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700185 case "trace-ipc":
186 return runTraceIpc(pw);
187 case "profile":
188 return runProfile(pw);
189 case "dumpheap":
190 return runDumpHeap(pw);
191 case "set-debug-app":
192 return runSetDebugApp(pw);
Andreas Gampe5b495d52018-01-22 15:15:54 -0800193 case "set-agent-app":
194 return runSetAgentApp(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700195 case "clear-debug-app":
196 return runClearDebugApp(pw);
197 case "set-watch-heap":
198 return runSetWatchHeap(pw);
199 case "clear-watch-heap":
200 return runClearWatchHeap(pw);
201 case "bug-report":
202 return runBugReport(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700203 case "force-stop":
204 return runForceStop(pw);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800205 case "crash":
206 return runCrash(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700207 case "kill":
208 return runKill(pw);
209 case "kill-all":
210 return runKillAll(pw);
Dianne Hackborn85e35642017-01-12 15:10:57 -0800211 case "make-uid-idle":
Dianne Hackborne07641d2016-11-09 15:07:23 -0800212 return runMakeIdle(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700213 case "monitor":
214 return runMonitor(pw);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +0100215 case "watch-uids":
216 return runWatchUids(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700217 case "hang":
218 return runHang(pw);
219 case "restart":
220 return runRestart(pw);
221 case "idle-maintenance":
222 return runIdleMaintenance(pw);
223 case "screen-compat":
224 return runScreenCompat(pw);
225 case "package-importance":
226 return runPackageImportance(pw);
227 case "to-uri":
228 return runToUri(pw, 0);
229 case "to-intent-uri":
230 return runToUri(pw, Intent.URI_INTENT_SCHEME);
231 case "to-app-uri":
232 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME);
233 case "switch-user":
234 return runSwitchUser(pw);
235 case "get-current-user":
236 return runGetCurrentUser(pw);
237 case "start-user":
238 return runStartUser(pw);
239 case "unlock-user":
240 return runUnlockUser(pw);
241 case "stop-user":
242 return runStopUser(pw);
243 case "is-user-stopped":
244 return runIsUserStopped(pw);
245 case "get-started-user-state":
246 return runGetStartedUserState(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700247 case "track-associations":
248 return runTrackAssociations(pw);
249 case "untrack-associations":
250 return runUntrackAssociations(pw);
Felipe Leme2f1b2272016-03-25 16:15:02 -0700251 case "get-uid-state":
252 return getUidState(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700253 case "get-config":
254 return runGetConfig(pw);
255 case "suppress-resize-config-changes":
256 return runSuppressResizeConfigChanges(pw);
257 case "set-inactive":
258 return runSetInactive(pw);
259 case "get-inactive":
260 return runGetInactive(pw);
Amith Yamasani17fffee2017-09-29 13:17:43 -0700261 case "set-standby-bucket":
262 return runSetStandbyBucket(pw);
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800263 case "get-standby-bucket":
264 return runGetStandbyBucket(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700265 case "send-trim-memory":
266 return runSendTrimMemory(pw);
Andrii Kulian839def92016-11-02 10:58:58 -0700267 case "display":
268 return runDisplay(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700269 case "stack":
270 return runStack(pw);
271 case "task":
272 return runTask(pw);
273 case "write":
274 return runWrite(pw);
Leonard Mosescuf3409ce2016-10-06 17:32:05 -0700275 case "attach-agent":
276 return runAttachAgent(pw);
Michael Kwan94438b72016-11-03 15:30:34 -0700277 case "supports-multiwindow":
278 return runSupportsMultiwindow(pw);
Matthew Ng626e0cc2016-12-07 17:25:53 -0800279 case "supports-split-screen-multi-window":
280 return runSupportsSplitScreenMultiwindow(pw);
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +0100281 case "update-appinfo":
282 return runUpdateApplicationInfo(pw);
Arthur Hsuf3f3a602017-02-21 14:01:53 -0800283 case "no-home-screen":
284 return runNoHomeScreen(pw);
Jeff Sharkeyfd658132017-05-03 11:38:01 -0600285 case "wait-for-broadcast-idle":
286 return runWaitForBroadcastIdle(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700287 default:
288 return handleDefaultCommands(cmd);
289 }
290 } catch (RemoteException e) {
291 pw.println("Remote exception: " + e);
292 }
293 return -1;
294 }
295
Dianne Hackborn354736e2016-08-22 17:00:05 -0700296 private Intent makeIntent(int defUser) throws URISyntaxException {
297 mStartFlags = 0;
298 mWaitOption = false;
299 mStopOption = false;
300 mRepeat = 0;
301 mProfileFile = null;
302 mSamplingInterval = 0;
303 mAutoStop = false;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800304 mStreaming = false;
Ng Zhi An8ab52a22018-08-29 10:20:33 -0700305 mUserId = mInternal.mUserController.handleIncomingUser(Binder.getCallingPid(),
306 Binder.getCallingUid(), defUser, false, ALLOW_FULL_ONLY,
307 "ActivityManagerShellCommand", null);
Andrii Kulian16802aa2016-11-02 12:21:33 -0700308 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700309 mWindowingMode = WINDOWING_MODE_UNDEFINED;
310 mActivityType = ACTIVITY_TYPE_UNDEFINED;
Winson Chung6954fc92017-03-24 16:22:12 -0700311 mTaskId = INVALID_TASK_ID;
312 mIsTaskOverlay = false;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000313 mIsLockTask = false;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700314
315 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
316 @Override
317 public boolean handleOption(String opt, ShellCommand cmd) {
318 if (opt.equals("-D")) {
319 mStartFlags |= ActivityManager.START_FLAG_DEBUG;
320 } else if (opt.equals("-N")) {
321 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING;
322 } else if (opt.equals("-W")) {
323 mWaitOption = true;
324 } else if (opt.equals("-P")) {
325 mProfileFile = getNextArgRequired();
326 mAutoStop = true;
327 } else if (opt.equals("--start-profiler")) {
328 mProfileFile = getNextArgRequired();
329 mAutoStop = false;
330 } else if (opt.equals("--sampling")) {
331 mSamplingInterval = Integer.parseInt(getNextArgRequired());
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800332 } else if (opt.equals("--streaming")) {
333 mStreaming = true;
Andreas Gampe83085bb2017-06-26 17:54:11 -0700334 } else if (opt.equals("--attach-agent")) {
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800335 if (mAgent != null) {
336 cmd.getErrPrintWriter().println(
337 "Multiple --attach-agent(-bind) not supported");
338 return false;
339 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700340 mAgent = getNextArgRequired();
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800341 mAttachAgentDuringBind = false;
342 } else if (opt.equals("--attach-agent-bind")) {
343 if (mAgent != null) {
344 cmd.getErrPrintWriter().println(
345 "Multiple --attach-agent(-bind) not supported");
346 return false;
347 }
348 mAgent = getNextArgRequired();
349 mAttachAgentDuringBind = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700350 } else if (opt.equals("-R")) {
351 mRepeat = Integer.parseInt(getNextArgRequired());
352 } else if (opt.equals("-S")) {
353 mStopOption = true;
354 } else if (opt.equals("--track-allocation")) {
355 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
356 } else if (opt.equals("--user")) {
357 mUserId = UserHandle.parseUserArg(getNextArgRequired());
358 } else if (opt.equals("--receiver-permission")) {
359 mReceiverPermission = getNextArgRequired();
Andrii Kulian16802aa2016-11-02 12:21:33 -0700360 } else if (opt.equals("--display")) {
361 mDisplayId = Integer.parseInt(getNextArgRequired());
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700362 } else if (opt.equals("--windowingMode")) {
363 mWindowingMode = Integer.parseInt(getNextArgRequired());
364 } else if (opt.equals("--activityType")) {
365 mActivityType = Integer.parseInt(getNextArgRequired());
Winson Chung6954fc92017-03-24 16:22:12 -0700366 } else if (opt.equals("--task")) {
367 mTaskId = Integer.parseInt(getNextArgRequired());
368 } else if (opt.equals("--task-overlay")) {
369 mIsTaskOverlay = true;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000370 } else if (opt.equals("--lock-task")) {
371 mIsLockTask = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700372 } else {
373 return false;
374 }
375 return true;
376 }
377 });
378 }
379
Dianne Hackborn354736e2016-08-22 17:00:05 -0700380 int runStartActivity(PrintWriter pw) throws RemoteException {
381 Intent intent;
382 try {
383 intent = makeIntent(UserHandle.USER_CURRENT);
384 } catch (URISyntaxException e) {
385 throw new RuntimeException(e.getMessage(), e);
386 }
387
388 if (mUserId == UserHandle.USER_ALL) {
389 getErrPrintWriter().println("Error: Can't start service with user 'all'");
390 return 1;
391 }
392
393 String mimeType = intent.getType();
394 if (mimeType == null && intent.getData() != null
395 && "content".equals(intent.getData().getScheme())) {
396 mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId);
397 }
398
399 do {
400 if (mStopOption) {
401 String packageName;
402 if (intent.getComponent() != null) {
403 packageName = intent.getComponent().getPackageName();
404 } else {
405 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0,
406 mUserId).getList();
407 if (activities == null || activities.size() <= 0) {
408 getErrPrintWriter().println("Error: Intent does not match any activities: "
409 + intent);
410 return 1;
411 } else if (activities.size() > 1) {
412 getErrPrintWriter().println(
413 "Error: Intent matches multiple activities; can't stop: "
414 + intent);
415 return 1;
416 }
417 packageName = activities.get(0).activityInfo.packageName;
418 }
419 pw.println("Stopping: " + packageName);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700420 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700421 mInterface.forceStopPackage(packageName, mUserId);
422 try {
423 Thread.sleep(250);
424 } catch (InterruptedException e) {
425 }
426 }
427
428 ProfilerInfo profilerInfo = null;
429
Andreas Gampe83085bb2017-06-26 17:54:11 -0700430 if (mProfileFile != null || mAgent != null) {
431 ParcelFileDescriptor fd = null;
432 if (mProfileFile != null) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700433 fd = openFileForSystem(mProfileFile, "w");
Andreas Gampe83085bb2017-06-26 17:54:11 -0700434 if (fd == null) {
435 return 1;
436 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700437 }
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800438 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800439 mStreaming, mAgent, mAttachAgentDuringBind);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700440 }
441
442 pw.println("Starting: " + intent);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700443 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700444 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
445
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700446 WaitResult result = null;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700447 int res;
448 final long startTime = SystemClock.uptimeMillis();
449 ActivityOptions options = null;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700450 if (mDisplayId != INVALID_DISPLAY) {
451 options = ActivityOptions.makeBasic();
452 options.setLaunchDisplayId(mDisplayId);
453 }
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700454 if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
455 if (options == null) {
456 options = ActivityOptions.makeBasic();
457 }
458 options.setLaunchWindowingMode(mWindowingMode);
459 }
460 if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
461 if (options == null) {
462 options = ActivityOptions.makeBasic();
463 }
464 options.setLaunchActivityType(mActivityType);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700465 }
Winson Chung6954fc92017-03-24 16:22:12 -0700466 if (mTaskId != INVALID_TASK_ID) {
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000467 if (options == null) {
468 options = ActivityOptions.makeBasic();
469 }
Winson Chung6954fc92017-03-24 16:22:12 -0700470 options.setLaunchTaskId(mTaskId);
471
472 if (mIsTaskOverlay) {
473 options.setTaskOverlay(true, true /* canResume */);
474 }
475 }
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000476 if (mIsLockTask) {
477 if (options == null) {
478 options = ActivityOptions.makeBasic();
479 }
Benjamin Franzcaffa772018-02-05 16:36:10 +0000480 options.setLockTaskEnabled(true);
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000481 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700482 if (mWaitOption) {
Wale Ogunwale7056a062018-10-18 15:02:50 -0700483 result = mInternal.startActivityAndWait(null, null, intent, mimeType,
Dianne Hackborn354736e2016-08-22 17:00:05 -0700484 null, null, 0, mStartFlags, profilerInfo,
485 options != null ? options.toBundle() : null, mUserId);
486 res = result.result;
487 } else {
Wale Ogunwale7056a062018-10-18 15:02:50 -0700488 res = mInternal.startActivityAsUser(null, null, intent, mimeType,
Dianne Hackborn354736e2016-08-22 17:00:05 -0700489 null, null, 0, mStartFlags, profilerInfo,
490 options != null ? options.toBundle() : null, mUserId);
491 }
492 final long endTime = SystemClock.uptimeMillis();
493 PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
494 boolean launched = false;
495 switch (res) {
496 case ActivityManager.START_SUCCESS:
497 launched = true;
498 break;
499 case ActivityManager.START_SWITCHES_CANCELED:
500 launched = true;
501 out.println(
502 "Warning: Activity not started because the "
503 + " current activity is being kept for the user.");
504 break;
505 case ActivityManager.START_DELIVERED_TO_TOP:
506 launched = true;
507 out.println(
508 "Warning: Activity not started, intent has "
509 + "been delivered to currently running "
510 + "top-most instance.");
511 break;
512 case ActivityManager.START_RETURN_INTENT_TO_CALLER:
513 launched = true;
514 out.println(
515 "Warning: Activity not started because intent "
516 + "should be handled by the caller");
517 break;
518 case ActivityManager.START_TASK_TO_FRONT:
519 launched = true;
520 out.println(
521 "Warning: Activity not started, its current "
522 + "task has been brought to the front");
523 break;
524 case ActivityManager.START_INTENT_NOT_RESOLVED:
525 out.println(
526 "Error: Activity not started, unable to "
527 + "resolve " + intent.toString());
528 break;
529 case ActivityManager.START_CLASS_NOT_FOUND:
530 out.println(NO_CLASS_ERROR_CODE);
531 out.println("Error: Activity class " +
532 intent.getComponent().toShortString()
533 + " does not exist.");
534 break;
535 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
536 out.println(
537 "Error: Activity not started, you requested to "
538 + "both forward and receive its result");
539 break;
540 case ActivityManager.START_PERMISSION_DENIED:
541 out.println(
542 "Error: Activity not started, you do not "
543 + "have permission to access it.");
544 break;
545 case ActivityManager.START_NOT_VOICE_COMPATIBLE:
546 out.println(
547 "Error: Activity not started, voice control not allowed for: "
548 + intent);
549 break;
550 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
551 out.println(
552 "Error: Not allowed to start background user activity"
553 + " that shouldn't be displayed for all users.");
554 break;
555 default:
556 out.println(
557 "Error: Activity not started, unknown error code " + res);
558 break;
559 }
Dianne Hackborn331084d2016-10-07 17:57:00 -0700560 out.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700561 if (mWaitOption && launched) {
562 if (result == null) {
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700563 result = new WaitResult();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700564 result.who = intent.getComponent();
565 }
566 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
Louis Chang0513a942019-03-06 12:38:13 +0800567 pw.println("LaunchState: " + launchStateToString(result.launchState));
Dianne Hackborn354736e2016-08-22 17:00:05 -0700568 if (result.who != null) {
569 pw.println("Activity: " + result.who.flattenToShortString());
570 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700571 if (result.totalTime >= 0) {
572 pw.println("TotalTime: " + result.totalTime);
573 }
574 pw.println("WaitTime: " + (endTime-startTime));
575 pw.println("Complete");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700576 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700577 }
578 mRepeat--;
579 if (mRepeat > 0) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700580 mTaskInterface.unhandledBack();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700581 }
582 } while (mRepeat > 0);
583 return 0;
584 }
585
Christopher Tate7e1368d2017-03-30 17:20:12 -0700586 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700587 final PrintWriter err = getErrPrintWriter();
588 Intent intent;
589 try {
590 intent = makeIntent(UserHandle.USER_CURRENT);
591 } catch (URISyntaxException e) {
592 throw new RuntimeException(e.getMessage(), e);
593 }
594 if (mUserId == UserHandle.USER_ALL) {
595 err.println("Error: Can't start activity with user 'all'");
596 return -1;
597 }
598 pw.println("Starting service: " + intent);
599 pw.flush();
600 ComponentName cn = mInterface.startService(null, intent, intent.getType(),
Christopher Tate242ba3e92017-04-14 15:07:06 -0700601 asForeground, SHELL_PACKAGE_NAME, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700602 if (cn == null) {
603 err.println("Error: Not found; no service started.");
604 return -1;
605 } else if (cn.getPackageName().equals("!")) {
606 err.println("Error: Requires permission " + cn.getClassName());
607 return -1;
608 } else if (cn.getPackageName().equals("!!")) {
609 err.println("Error: " + cn.getClassName());
610 return -1;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800611 } else if (cn.getPackageName().equals("?")) {
612 err.println("Error: " + cn.getClassName());
613 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700614 }
615 return 0;
616 }
617
618 int runStopService(PrintWriter pw) throws RemoteException {
619 final PrintWriter err = getErrPrintWriter();
620 Intent intent;
621 try {
622 intent = makeIntent(UserHandle.USER_CURRENT);
623 } catch (URISyntaxException e) {
624 throw new RuntimeException(e.getMessage(), e);
625 }
626 if (mUserId == UserHandle.USER_ALL) {
627 err.println("Error: Can't stop activity with user 'all'");
628 return -1;
629 }
630 pw.println("Stopping service: " + intent);
631 pw.flush();
632 int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
633 if (result == 0) {
634 err.println("Service not stopped: was not running.");
635 return -1;
636 } else if (result == 1) {
637 err.println("Service stopped");
638 return -1;
639 } else if (result == -1) {
640 err.println("Error stopping service");
641 return -1;
642 }
643 return 0;
644 }
645
646 final static class IntentReceiver extends IIntentReceiver.Stub {
647 private final PrintWriter mPw;
648 private boolean mFinished = false;
649
650 IntentReceiver(PrintWriter pw) {
651 mPw = pw;
652 }
653
654 @Override
655 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
656 boolean ordered, boolean sticky, int sendingUser) {
657 String line = "Broadcast completed: result=" + resultCode;
658 if (data != null) line = line + ", data=\"" + data + "\"";
659 if (extras != null) line = line + ", extras: " + extras;
660 mPw.println(line);
661 mPw.flush();
662 synchronized (this) {
663 mFinished = true;
664 notifyAll();
665 }
666 }
667
668 public synchronized void waitForFinish() {
669 try {
670 while (!mFinished) wait();
671 } catch (InterruptedException e) {
672 throw new IllegalStateException(e);
673 }
674 }
675 }
676
677 int runSendBroadcast(PrintWriter pw) throws RemoteException {
678 Intent intent;
679 try {
680 intent = makeIntent(UserHandle.USER_CURRENT);
681 } catch (URISyntaxException e) {
682 throw new RuntimeException(e.getMessage(), e);
683 }
Jeff Sharkey6a34e562016-12-21 09:56:00 -0700684 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700685 IntentReceiver receiver = new IntentReceiver(pw);
686 String[] requiredPermissions = mReceiverPermission == null ? null
687 : new String[] {mReceiverPermission};
688 pw.println("Broadcasting: " + intent);
689 pw.flush();
690 mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
691 android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
692 receiver.waitForFinish();
693 return 0;
694 }
695
Dianne Hackborn331084d2016-10-07 17:57:00 -0700696 int runTraceIpc(PrintWriter pw) throws RemoteException {
697 String op = getNextArgRequired();
698 if (op.equals("start")) {
699 return runTraceIpcStart(pw);
700 } else if (op.equals("stop")) {
701 return runTraceIpcStop(pw);
702 } else {
703 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'");
704 return -1;
705 }
706 }
707
708 int runTraceIpcStart(PrintWriter pw) throws RemoteException {
709 pw.println("Starting IPC tracing.");
710 pw.flush();
711 mInterface.startBinderTracking();
712 return 0;
713 }
714
715 int runTraceIpcStop(PrintWriter pw) throws RemoteException {
716 final PrintWriter err = getErrPrintWriter();
717 String opt;
718 String filename = null;
719 while ((opt=getNextOption()) != null) {
720 if (opt.equals("--dump-file")) {
721 filename = getNextArgRequired();
722 } else {
723 err.println("Error: Unknown option: " + opt);
724 return -1;
725 }
726 }
727 if (filename == null) {
728 err.println("Error: Specify filename to dump logs to.");
729 return -1;
730 }
731
732 File file = new File(filename);
733 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700734 ParcelFileDescriptor fd = openFileForSystem(filename, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700735 if (fd == null) {
736 return -1;
737 }
738
Dianne Hackborn331084d2016-10-07 17:57:00 -0700739 if (!mInterface.stopBinderTrackingAndDump(fd)) {
740 err.println("STOP TRACE FAILED.");
741 return -1;
742 }
743
744 pw.println("Stopped IPC tracing. Dumping logs to: " + filename);
745 return 0;
746 }
747
748 static void removeWallOption() {
749 String props = SystemProperties.get("dalvik.vm.extra-opts");
750 if (props != null && props.contains("-Xprofile:wallclock")) {
751 props = props.replace("-Xprofile:wallclock", "");
752 props = props.trim();
753 SystemProperties.set("dalvik.vm.extra-opts", props);
754 }
755 }
756
757 private int runProfile(PrintWriter pw) throws RemoteException {
758 final PrintWriter err = getErrPrintWriter();
759 String profileFile = null;
760 boolean start = false;
761 boolean wall = false;
762 int userId = UserHandle.USER_CURRENT;
763 int profileType = 0;
764 mSamplingInterval = 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800765 mStreaming = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700766
767 String process = null;
768
769 String cmd = getNextArgRequired();
770
771 if ("start".equals(cmd)) {
772 start = true;
773 String opt;
774 while ((opt=getNextOption()) != null) {
775 if (opt.equals("--user")) {
776 userId = UserHandle.parseUserArg(getNextArgRequired());
777 } else if (opt.equals("--wall")) {
778 wall = true;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800779 } else if (opt.equals("--streaming")) {
780 mStreaming = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700781 } else if (opt.equals("--sampling")) {
782 mSamplingInterval = Integer.parseInt(getNextArgRequired());
783 } else {
784 err.println("Error: Unknown option: " + opt);
785 return -1;
786 }
787 }
788 process = getNextArgRequired();
789 } else if ("stop".equals(cmd)) {
790 String opt;
791 while ((opt=getNextOption()) != null) {
792 if (opt.equals("--user")) {
793 userId = UserHandle.parseUserArg(getNextArgRequired());
794 } else {
795 err.println("Error: Unknown option: " + opt);
796 return -1;
797 }
798 }
799 process = getNextArg();
800 } else {
801 // Compatibility with old syntax: process is specified first.
802 process = cmd;
803 cmd = getNextArgRequired();
804 if ("start".equals(cmd)) {
805 start = true;
806 } else if (!"stop".equals(cmd)) {
807 throw new IllegalArgumentException("Profile command " + process + " not valid");
808 }
809 }
810
811 if (userId == UserHandle.USER_ALL) {
812 err.println("Error: Can't profile with user 'all'");
813 return -1;
814 }
815
816 ParcelFileDescriptor fd = null;
817 ProfilerInfo profilerInfo = null;
818
819 if (start) {
820 profileFile = getNextArgRequired();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700821 fd = openFileForSystem(profileFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700822 if (fd == null) {
823 return -1;
824 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700825 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800826 null, false);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700827 }
828
829 try {
830 if (wall) {
831 // XXX doesn't work -- this needs to be set before booting.
832 String props = SystemProperties.get("dalvik.vm.extra-opts");
833 if (props == null || !props.contains("-Xprofile:wallclock")) {
834 props = props + " -Xprofile:wallclock";
835 //SystemProperties.set("dalvik.vm.extra-opts", props);
836 }
837 } else if (start) {
838 //removeWallOption();
839 }
840 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
841 wall = false;
842 err.println("PROFILE FAILED on process " + process);
843 return -1;
844 }
845 } finally {
846 if (!wall) {
847 //removeWallOption();
848 }
849 }
850 return 0;
851 }
852
853 int runDumpHeap(PrintWriter pw) throws RemoteException {
854 final PrintWriter err = getErrPrintWriter();
855 boolean managed = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700856 boolean mallocInfo = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700857 int userId = UserHandle.USER_CURRENT;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700858 boolean runGc = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700859
860 String opt;
861 while ((opt=getNextOption()) != null) {
862 if (opt.equals("--user")) {
863 userId = UserHandle.parseUserArg(getNextArgRequired());
864 if (userId == UserHandle.USER_ALL) {
865 err.println("Error: Can't dump heap with user 'all'");
866 return -1;
867 }
868 } else if (opt.equals("-n")) {
869 managed = false;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700870 } else if (opt.equals("-g")) {
871 runGc = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700872 } else if (opt.equals("-m")) {
873 managed = false;
874 mallocInfo = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700875 } else {
876 err.println("Error: Unknown option: " + opt);
877 return -1;
878 }
879 }
880 String process = getNextArgRequired();
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700881 String heapFile = getNextArg();
882 if (heapFile == null) {
883 final Time t = new Time();
884 t.set(System.currentTimeMillis());
885 heapFile = "/data/local/tmp/heapdump-" + t.format("%Y%m%d-%H%M%S") + ".prof";
886 }
887 pw.println("File: " + heapFile);
888 pw.flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -0700889
890 File file = new File(heapFile);
891 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700892 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700893 if (fd == null) {
894 return -1;
895 }
896
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700897 final CountDownLatch latch = new CountDownLatch(1);
898
899 final RemoteCallback finishCallback = new RemoteCallback(new OnResultListener() {
900 @Override
901 public void onResult(Bundle result) {
902 latch.countDown();
903 }
904 }, null);
905
906 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd,
907 finishCallback)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700908 err.println("HEAP DUMP FAILED on process " + process);
909 return -1;
910 }
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700911 pw.println("Waiting for dump to finish...");
912 pw.flush();
913 try {
914 latch.await();
915 } catch (InterruptedException e) {
916 err.println("Caught InterruptedException");
917 }
918
Dianne Hackborn331084d2016-10-07 17:57:00 -0700919 return 0;
920 }
921
922 int runSetDebugApp(PrintWriter pw) throws RemoteException {
923 boolean wait = false;
924 boolean persistent = false;
925
926 String opt;
927 while ((opt=getNextOption()) != null) {
928 if (opt.equals("-w")) {
929 wait = true;
930 } else if (opt.equals("--persistent")) {
931 persistent = true;
932 } else {
933 getErrPrintWriter().println("Error: Unknown option: " + opt);
934 return -1;
935 }
936 }
937
938 String pkg = getNextArgRequired();
939 mInterface.setDebugApp(pkg, wait, persistent);
940 return 0;
941 }
942
Andreas Gampe5b495d52018-01-22 15:15:54 -0800943 int runSetAgentApp(PrintWriter pw) throws RemoteException {
944 String pkg = getNextArgRequired();
945 String agent = getNextArg();
946 mInterface.setAgentApp(pkg, agent);
947 return 0;
948 }
949
Dianne Hackborn331084d2016-10-07 17:57:00 -0700950 int runClearDebugApp(PrintWriter pw) throws RemoteException {
951 mInterface.setDebugApp(null, false, true);
952 return 0;
953 }
954
955 int runSetWatchHeap(PrintWriter pw) throws RemoteException {
956 String proc = getNextArgRequired();
957 String limit = getNextArgRequired();
958 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
959 return 0;
960 }
961
962 int runClearWatchHeap(PrintWriter pw) throws RemoteException {
963 String proc = getNextArgRequired();
964 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null);
965 return 0;
966 }
967
968 int runBugReport(PrintWriter pw) throws RemoteException {
969 String opt;
970 int bugreportType = ActivityManager.BUGREPORT_OPTION_FULL;
971 while ((opt=getNextOption()) != null) {
972 if (opt.equals("--progress")) {
973 bugreportType = ActivityManager.BUGREPORT_OPTION_INTERACTIVE;
Felipe Leme9606c3b2017-01-05 14:57:12 -0800974 } else if (opt.equals("--telephony")) {
975 bugreportType = ActivityManager.BUGREPORT_OPTION_TELEPHONY;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700976 } else {
977 getErrPrintWriter().println("Error: Unknown option: " + opt);
978 return -1;
979 }
980 }
981 mInterface.requestBugReport(bugreportType);
982 pw.println("Your lovely bug report is being created; please be patient.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800983 return 0;
984 }
985
Dianne Hackborn2e441072015-10-28 18:00:57 -0700986 int runForceStop(PrintWriter pw) throws RemoteException {
987 int userId = UserHandle.USER_ALL;
988
989 String opt;
990 while ((opt = getNextOption()) != null) {
991 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800992 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -0700993 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700994 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700995 return -1;
996 }
997 }
998 mInterface.forceStopPackage(getNextArgRequired(), userId);
999 return 0;
1000 }
1001
Christopher Tate8aa8fe12017-01-20 17:50:32 -08001002 int runCrash(PrintWriter pw) throws RemoteException {
1003 int userId = UserHandle.USER_ALL;
1004
1005 String opt;
1006 while ((opt=getNextOption()) != null) {
1007 if (opt.equals("--user")) {
1008 userId = UserHandle.parseUserArg(getNextArgRequired());
1009 } else {
1010 getErrPrintWriter().println("Error: Unknown option: " + opt);
1011 return -1;
1012 }
1013 }
1014
1015 int pid = -1;
1016 String packageName = null;
1017 final String arg = getNextArgRequired();
1018 // The argument is either a pid or a package name
1019 try {
1020 pid = Integer.parseInt(arg);
1021 } catch (NumberFormatException e) {
1022 packageName = arg;
1023 }
1024 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
1025 return 0;
1026 }
1027
Dianne Hackborn2e441072015-10-28 18:00:57 -07001028 int runKill(PrintWriter pw) throws RemoteException {
1029 int userId = UserHandle.USER_ALL;
1030
1031 String opt;
1032 while ((opt=getNextOption()) != null) {
1033 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001034 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001035 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001036 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001037 return -1;
1038 }
1039 }
1040 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
1041 return 0;
1042 }
1043
1044 int runKillAll(PrintWriter pw) throws RemoteException {
1045 mInterface.killAllBackgroundProcesses();
1046 return 0;
1047 }
1048
Dianne Hackborne07641d2016-11-09 15:07:23 -08001049 int runMakeIdle(PrintWriter pw) throws RemoteException {
1050 int userId = UserHandle.USER_ALL;
1051
1052 String opt;
1053 while ((opt = getNextOption()) != null) {
1054 if (opt.equals("--user")) {
1055 userId = UserHandle.parseUserArg(getNextArgRequired());
1056 } else {
1057 getErrPrintWriter().println("Error: Unknown option: " + opt);
1058 return -1;
1059 }
1060 }
1061 mInterface.makePackageIdle(getNextArgRequired(), userId);
1062 return 0;
1063 }
1064
Dianne Hackborn331084d2016-10-07 17:57:00 -07001065 static final class MyActivityController extends IActivityController.Stub {
1066 final IActivityManager mInterface;
1067 final PrintWriter mPw;
1068 final InputStream mInput;
1069 final String mGdbPort;
1070 final boolean mMonkey;
1071
1072 static final int STATE_NORMAL = 0;
1073 static final int STATE_CRASHED = 1;
1074 static final int STATE_EARLY_ANR = 2;
1075 static final int STATE_ANR = 3;
1076
1077 int mState;
1078
1079 static final int RESULT_DEFAULT = 0;
1080
1081 static final int RESULT_CRASH_DIALOG = 0;
1082 static final int RESULT_CRASH_KILL = 1;
1083
1084 static final int RESULT_EARLY_ANR_CONTINUE = 0;
1085 static final int RESULT_EARLY_ANR_KILL = 1;
1086
1087 static final int RESULT_ANR_DIALOG = 0;
1088 static final int RESULT_ANR_KILL = 1;
1089 static final int RESULT_ANR_WAIT = 1;
1090
1091 int mResult;
1092
1093 Process mGdbProcess;
1094 Thread mGdbThread;
1095 boolean mGotGdbPrint;
1096
1097 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
1098 String gdbPort, boolean monkey) {
1099 mInterface = iam;
1100 mPw = pw;
1101 mInput = input;
1102 mGdbPort = gdbPort;
1103 mMonkey = monkey;
1104 }
1105
1106 @Override
1107 public boolean activityResuming(String pkg) {
1108 synchronized (this) {
1109 mPw.println("** Activity resuming: " + pkg);
1110 mPw.flush();
1111 }
1112 return true;
1113 }
1114
1115 @Override
1116 public boolean activityStarting(Intent intent, String pkg) {
1117 synchronized (this) {
1118 mPw.println("** Activity starting: " + pkg);
1119 mPw.flush();
1120 }
1121 return true;
1122 }
1123
1124 @Override
1125 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
1126 long timeMillis, String stackTrace) {
1127 synchronized (this) {
1128 mPw.println("** ERROR: PROCESS CRASHED");
1129 mPw.println("processName: " + processName);
1130 mPw.println("processPid: " + pid);
1131 mPw.println("shortMsg: " + shortMsg);
1132 mPw.println("longMsg: " + longMsg);
1133 mPw.println("timeMillis: " + timeMillis);
1134 mPw.println("stack:");
1135 mPw.print(stackTrace);
1136 mPw.println("#");
1137 mPw.flush();
1138 int result = waitControllerLocked(pid, STATE_CRASHED);
1139 return result == RESULT_CRASH_KILL ? false : true;
1140 }
1141 }
1142
1143 @Override
1144 public int appEarlyNotResponding(String processName, int pid, String annotation) {
1145 synchronized (this) {
1146 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING");
1147 mPw.println("processName: " + processName);
1148 mPw.println("processPid: " + pid);
1149 mPw.println("annotation: " + annotation);
1150 mPw.flush();
1151 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
1152 if (result == RESULT_EARLY_ANR_KILL) return -1;
1153 return 0;
1154 }
1155 }
1156
1157 @Override
1158 public int appNotResponding(String processName, int pid, String processStats) {
1159 synchronized (this) {
1160 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1161 mPw.println("processName: " + processName);
1162 mPw.println("processPid: " + pid);
1163 mPw.println("processStats:");
1164 mPw.print(processStats);
1165 mPw.println("#");
1166 mPw.flush();
1167 int result = waitControllerLocked(pid, STATE_ANR);
1168 if (result == RESULT_ANR_KILL) return -1;
1169 if (result == RESULT_ANR_WAIT) return 1;
1170 return 0;
1171 }
1172 }
1173
1174 @Override
1175 public int systemNotResponding(String message) {
1176 synchronized (this) {
1177 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1178 mPw.println("message: " + message);
1179 mPw.println("#");
1180 mPw.println("Allowing system to die.");
1181 mPw.flush();
1182 return -1;
1183 }
1184 }
1185
1186 void killGdbLocked() {
1187 mGotGdbPrint = false;
1188 if (mGdbProcess != null) {
1189 mPw.println("Stopping gdbserver");
1190 mPw.flush();
1191 mGdbProcess.destroy();
1192 mGdbProcess = null;
1193 }
1194 if (mGdbThread != null) {
1195 mGdbThread.interrupt();
1196 mGdbThread = null;
1197 }
1198 }
1199
1200 int waitControllerLocked(int pid, int state) {
1201 if (mGdbPort != null) {
1202 killGdbLocked();
1203
1204 try {
1205 mPw.println("Starting gdbserver on port " + mGdbPort);
1206 mPw.println("Do the following:");
1207 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
1208 mPw.println(" gdbclient app_process :" + mGdbPort);
1209 mPw.flush();
1210
1211 mGdbProcess = Runtime.getRuntime().exec(new String[] {
1212 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
1213 });
1214 final InputStreamReader converter = new InputStreamReader(
1215 mGdbProcess.getInputStream());
1216 mGdbThread = new Thread() {
1217 @Override
1218 public void run() {
1219 BufferedReader in = new BufferedReader(converter);
1220 String line;
1221 int count = 0;
1222 while (true) {
1223 synchronized (MyActivityController.this) {
1224 if (mGdbThread == null) {
1225 return;
1226 }
1227 if (count == 2) {
1228 mGotGdbPrint = true;
1229 MyActivityController.this.notifyAll();
1230 }
1231 }
1232 try {
1233 line = in.readLine();
1234 if (line == null) {
1235 return;
1236 }
1237 mPw.println("GDB: " + line);
1238 mPw.flush();
1239 count++;
1240 } catch (IOException e) {
1241 return;
1242 }
1243 }
1244 }
1245 };
1246 mGdbThread.start();
1247
1248 // Stupid waiting for .5s. Doesn't matter if we end early.
1249 try {
1250 this.wait(500);
1251 } catch (InterruptedException e) {
1252 }
1253
1254 } catch (IOException e) {
1255 mPw.println("Failure starting gdbserver: " + e);
1256 mPw.flush();
1257 killGdbLocked();
1258 }
1259 }
1260 mState = state;
1261 mPw.println("");
1262 printMessageForState();
1263 mPw.flush();
1264
1265 while (mState != STATE_NORMAL) {
1266 try {
1267 wait();
1268 } catch (InterruptedException e) {
1269 }
1270 }
1271
1272 killGdbLocked();
1273
1274 return mResult;
1275 }
1276
1277 void resumeController(int result) {
1278 synchronized (this) {
1279 mState = STATE_NORMAL;
1280 mResult = result;
1281 notifyAll();
1282 }
1283 }
1284
1285 void printMessageForState() {
1286 switch (mState) {
1287 case STATE_NORMAL:
1288 mPw.println("Monitoring activity manager... available commands:");
1289 break;
1290 case STATE_CRASHED:
1291 mPw.println("Waiting after crash... available commands:");
1292 mPw.println("(c)ontinue: show crash dialog");
1293 mPw.println("(k)ill: immediately kill app");
1294 break;
1295 case STATE_EARLY_ANR:
1296 mPw.println("Waiting after early ANR... available commands:");
1297 mPw.println("(c)ontinue: standard ANR processing");
1298 mPw.println("(k)ill: immediately kill app");
1299 break;
1300 case STATE_ANR:
1301 mPw.println("Waiting after ANR... available commands:");
1302 mPw.println("(c)ontinue: show ANR dialog");
1303 mPw.println("(k)ill: immediately kill app");
1304 mPw.println("(w)ait: wait some more");
1305 break;
1306 }
1307 mPw.println("(q)uit: finish monitoring");
1308 }
1309
1310 void run() throws RemoteException {
1311 try {
1312 printMessageForState();
1313 mPw.flush();
1314
1315 mInterface.setActivityController(this, mMonkey);
1316 mState = STATE_NORMAL;
1317
1318 InputStreamReader converter = new InputStreamReader(mInput);
1319 BufferedReader in = new BufferedReader(converter);
1320 String line;
1321
1322 while ((line = in.readLine()) != null) {
1323 boolean addNewline = true;
1324 if (line.length() <= 0) {
1325 addNewline = false;
1326 } else if ("q".equals(line) || "quit".equals(line)) {
1327 resumeController(RESULT_DEFAULT);
1328 break;
1329 } else if (mState == STATE_CRASHED) {
1330 if ("c".equals(line) || "continue".equals(line)) {
1331 resumeController(RESULT_CRASH_DIALOG);
1332 } else if ("k".equals(line) || "kill".equals(line)) {
1333 resumeController(RESULT_CRASH_KILL);
1334 } else {
1335 mPw.println("Invalid command: " + line);
1336 }
1337 } else if (mState == STATE_ANR) {
1338 if ("c".equals(line) || "continue".equals(line)) {
1339 resumeController(RESULT_ANR_DIALOG);
1340 } else if ("k".equals(line) || "kill".equals(line)) {
1341 resumeController(RESULT_ANR_KILL);
1342 } else if ("w".equals(line) || "wait".equals(line)) {
1343 resumeController(RESULT_ANR_WAIT);
1344 } else {
1345 mPw.println("Invalid command: " + line);
1346 }
1347 } else if (mState == STATE_EARLY_ANR) {
1348 if ("c".equals(line) || "continue".equals(line)) {
1349 resumeController(RESULT_EARLY_ANR_CONTINUE);
1350 } else if ("k".equals(line) || "kill".equals(line)) {
1351 resumeController(RESULT_EARLY_ANR_KILL);
1352 } else {
1353 mPw.println("Invalid command: " + line);
1354 }
1355 } else {
1356 mPw.println("Invalid command: " + line);
1357 }
1358
1359 synchronized (this) {
1360 if (addNewline) {
1361 mPw.println("");
1362 }
1363 printMessageForState();
1364 mPw.flush();
1365 }
1366 }
1367
1368 } catch (IOException e) {
1369 e.printStackTrace(mPw);
1370 mPw.flush();
1371 } finally {
1372 mInterface.setActivityController(null, mMonkey);
1373 }
1374 }
1375 }
1376
1377 int runMonitor(PrintWriter pw) throws RemoteException {
1378 String opt;
1379 String gdbPort = null;
1380 boolean monkey = false;
1381 while ((opt=getNextOption()) != null) {
1382 if (opt.equals("--gdb")) {
1383 gdbPort = getNextArgRequired();
1384 } else if (opt.equals("-m")) {
1385 monkey = true;
1386 } else {
1387 getErrPrintWriter().println("Error: Unknown option: " + opt);
1388 return -1;
1389 }
1390 }
1391
1392 MyActivityController controller = new MyActivityController(mInterface, pw,
1393 getRawInputStream(), gdbPort, monkey);
1394 controller.run();
1395 return 0;
1396 }
1397
Dianne Hackborne51505a2017-08-07 17:13:52 -07001398 static final class MyUidObserver extends IUidObserver.Stub
1399 implements ActivityManagerService.OomAdjObserver {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001400 final IActivityManager mInterface;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001401 final ActivityManagerService mInternal;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001402 final PrintWriter mPw;
1403 final InputStream mInput;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001404 final int mUid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001405
1406 static final int STATE_NORMAL = 0;
1407
1408 int mState;
1409
Dianne Hackborne51505a2017-08-07 17:13:52 -07001410 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
1411 mInterface = service;
1412 mInternal = service;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001413 mPw = pw;
1414 mInput = input;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001415 mUid = uid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001416 }
1417
1418 @Override
1419 public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException {
1420 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001421 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1422 try {
1423 mPw.print(uid);
1424 mPw.print(" procstate ");
1425 mPw.print(ProcessList.makeProcStateString(procState));
1426 mPw.print(" seq ");
1427 mPw.println(procStateSeq);
1428 mPw.flush();
1429 } finally {
1430 StrictMode.setThreadPolicy(oldPolicy);
1431 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001432 }
1433 }
1434
1435 @Override
1436 public void onUidGone(int uid, boolean disabled) throws RemoteException {
1437 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001438 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1439 try {
1440 mPw.print(uid);
1441 mPw.print(" gone");
1442 if (disabled) {
1443 mPw.print(" disabled");
1444 }
1445 mPw.println();
1446 mPw.flush();
1447 } finally {
1448 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001449 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001450 }
1451 }
1452
1453 @Override
1454 public void onUidActive(int uid) throws RemoteException {
1455 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001456 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1457 try {
1458 mPw.print(uid);
1459 mPw.println(" active");
1460 mPw.flush();
1461 } finally {
1462 StrictMode.setThreadPolicy(oldPolicy);
1463 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001464 }
1465 }
1466
1467 @Override
1468 public void onUidIdle(int uid, boolean disabled) throws RemoteException {
1469 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001470 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1471 try {
1472 mPw.print(uid);
1473 mPw.print(" idle");
1474 if (disabled) {
1475 mPw.print(" disabled");
1476 }
1477 mPw.println();
1478 mPw.flush();
1479 } finally {
1480 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001481 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001482 }
1483 }
1484
1485 @Override
1486 public void onUidCachedChanged(int uid, boolean cached) throws RemoteException {
1487 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001488 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1489 try {
1490 mPw.print(uid);
1491 mPw.println(cached ? " cached" : " uncached");
1492 mPw.flush();
1493 } finally {
1494 StrictMode.setThreadPolicy(oldPolicy);
1495 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001496 }
1497 }
1498
Dianne Hackborne51505a2017-08-07 17:13:52 -07001499 @Override
1500 public void onOomAdjMessage(String msg) {
1501 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001502 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1503 try {
1504 mPw.print("# ");
1505 mPw.println(msg);
1506 mPw.flush();
1507 } finally {
1508 StrictMode.setThreadPolicy(oldPolicy);
1509 }
Dianne Hackborne51505a2017-08-07 17:13:52 -07001510 }
1511 }
1512
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001513 void printMessageForState() {
1514 switch (mState) {
1515 case STATE_NORMAL:
1516 mPw.println("Watching uid states... available commands:");
1517 break;
1518 }
1519 mPw.println("(q)uit: finish watching");
1520 }
1521
1522 void run() throws RemoteException {
1523 try {
1524 printMessageForState();
1525 mPw.flush();
1526
1527 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE
1528 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
1529 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
1530 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackborne51505a2017-08-07 17:13:52 -07001531 if (mUid >= 0) {
1532 mInternal.setOomAdjObserver(mUid, this);
1533 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001534 mState = STATE_NORMAL;
1535
1536 InputStreamReader converter = new InputStreamReader(mInput);
1537 BufferedReader in = new BufferedReader(converter);
1538 String line;
1539
1540 while ((line = in.readLine()) != null) {
1541 boolean addNewline = true;
1542 if (line.length() <= 0) {
1543 addNewline = false;
1544 } else if ("q".equals(line) || "quit".equals(line)) {
1545 break;
1546 } else {
1547 mPw.println("Invalid command: " + line);
1548 }
1549
1550 synchronized (this) {
1551 if (addNewline) {
1552 mPw.println("");
1553 }
1554 printMessageForState();
1555 mPw.flush();
1556 }
1557 }
1558
1559 } catch (IOException e) {
1560 e.printStackTrace(mPw);
1561 mPw.flush();
1562 } finally {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001563 if (mUid >= 0) {
1564 mInternal.clearOomAdjObserver();
1565 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001566 mInterface.unregisterUidObserver(this);
1567 }
1568 }
1569 }
1570
1571 int runWatchUids(PrintWriter pw) throws RemoteException {
1572 String opt;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001573 int uid = -1;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001574 while ((opt=getNextOption()) != null) {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001575 if (opt.equals("--oom")) {
1576 uid = Integer.parseInt(getNextArgRequired());
1577 } else {
1578 getErrPrintWriter().println("Error: Unknown option: " + opt);
1579 return -1;
1580
1581 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001582 }
1583
Dianne Hackborne51505a2017-08-07 17:13:52 -07001584 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001585 controller.run();
1586 return 0;
1587 }
1588
Dianne Hackborn331084d2016-10-07 17:57:00 -07001589 int runHang(PrintWriter pw) throws RemoteException {
1590 String opt;
1591 boolean allowRestart = false;
1592 while ((opt=getNextOption()) != null) {
1593 if (opt.equals("--allow-restart")) {
1594 allowRestart = true;
1595 } else {
1596 getErrPrintWriter().println("Error: Unknown option: " + opt);
1597 return -1;
1598 }
1599 }
1600
1601 pw.println("Hanging the system...");
1602 pw.flush();
1603 mInterface.hang(new Binder(), allowRestart);
1604 return 0;
1605 }
1606
1607 int runRestart(PrintWriter pw) throws RemoteException {
1608 String opt;
1609 while ((opt=getNextOption()) != null) {
1610 getErrPrintWriter().println("Error: Unknown option: " + opt);
1611 return -1;
1612 }
1613
1614 pw.println("Restart the system...");
1615 pw.flush();
1616 mInterface.restart();
1617 return 0;
1618 }
1619
1620 int runIdleMaintenance(PrintWriter pw) throws RemoteException {
1621 String opt;
1622 while ((opt=getNextOption()) != null) {
1623 getErrPrintWriter().println("Error: Unknown option: " + opt);
1624 return -1;
1625 }
1626
1627 pw.println("Performing idle maintenance...");
1628 mInterface.sendIdleJobTrigger();
1629 return 0;
1630 }
1631
1632 int runScreenCompat(PrintWriter pw) throws RemoteException {
1633 String mode = getNextArgRequired();
1634 boolean enabled;
1635 if ("on".equals(mode)) {
1636 enabled = true;
1637 } else if ("off".equals(mode)) {
1638 enabled = false;
1639 } else {
1640 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode);
1641 return -1;
1642 }
1643
1644 String packageName = getNextArgRequired();
1645 do {
1646 try {
1647 mInterface.setPackageScreenCompatMode(packageName, enabled
1648 ? ActivityManager.COMPAT_MODE_ENABLED
1649 : ActivityManager.COMPAT_MODE_DISABLED);
1650 } catch (RemoteException e) {
1651 }
1652 packageName = getNextArg();
1653 } while (packageName != null);
1654 return 0;
1655 }
1656
1657 int runPackageImportance(PrintWriter pw) throws RemoteException {
1658 String packageName = getNextArgRequired();
1659 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell");
1660 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
1661 return 0;
1662 }
1663
1664 int runToUri(PrintWriter pw, int flags) throws RemoteException {
1665 Intent intent;
1666 try {
1667 intent = makeIntent(UserHandle.USER_CURRENT);
1668 } catch (URISyntaxException e) {
1669 throw new RuntimeException(e.getMessage(), e);
1670 }
1671 pw.println(intent.toUri(flags));
1672 return 0;
1673 }
1674
1675 int runSwitchUser(PrintWriter pw) throws RemoteException {
Alex Chau5c0df232018-02-22 15:57:17 +08001676 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
1677 if (!userManager.canSwitchUsers()) {
1678 getErrPrintWriter().println("Error: disallowed switching user");
1679 return -1;
1680 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001681 String user = getNextArgRequired();
1682 mInterface.switchUser(Integer.parseInt(user));
1683 return 0;
1684 }
1685
1686 int runGetCurrentUser(PrintWriter pw) throws RemoteException {
1687 UserInfo currentUser = Preconditions.checkNotNull(mInterface.getCurrentUser(),
1688 "Current user not set");
1689 pw.println(currentUser.id);
1690 return 0;
1691 }
1692
1693 int runStartUser(PrintWriter pw) throws RemoteException {
1694 String user = getNextArgRequired();
1695 boolean success = mInterface.startUserInBackground(Integer.parseInt(user));
1696 if (success) {
1697 pw.println("Success: user started");
1698 } else {
1699 getErrPrintWriter().println("Error: could not start user");
1700 }
1701 return 0;
1702 }
1703
1704 private static byte[] argToBytes(String arg) {
1705 if (arg.equals("!")) {
1706 return null;
1707 } else {
1708 return HexDump.hexStringToByteArray(arg);
1709 }
1710 }
1711
1712 int runUnlockUser(PrintWriter pw) throws RemoteException {
1713 int userId = Integer.parseInt(getNextArgRequired());
1714 byte[] token = argToBytes(getNextArgRequired());
1715 byte[] secret = argToBytes(getNextArgRequired());
1716 boolean success = mInterface.unlockUser(userId, token, secret, null);
1717 if (success) {
1718 pw.println("Success: user unlocked");
1719 } else {
1720 getErrPrintWriter().println("Error: could not unlock user");
1721 }
1722 return 0;
1723 }
1724
1725 static final class StopUserCallback extends IStopUserCallback.Stub {
1726 private boolean mFinished = false;
1727
1728 public synchronized void waitForFinish() {
1729 try {
1730 while (!mFinished) wait();
1731 } catch (InterruptedException e) {
1732 throw new IllegalStateException(e);
1733 }
1734 }
1735
1736 @Override
1737 public synchronized void userStopped(int userId) {
1738 mFinished = true;
1739 notifyAll();
1740 }
1741
1742 @Override
1743 public synchronized void userStopAborted(int userId) {
1744 mFinished = true;
1745 notifyAll();
1746 }
1747 }
1748
1749 int runStopUser(PrintWriter pw) throws RemoteException {
1750 boolean wait = false;
1751 boolean force = false;
1752 String opt;
1753 while ((opt = getNextOption()) != null) {
1754 if ("-w".equals(opt)) {
1755 wait = true;
1756 } else if ("-f".equals(opt)) {
1757 force = true;
1758 } else {
1759 getErrPrintWriter().println("Error: unknown option: " + opt);
1760 return -1;
1761 }
1762 }
1763 int user = Integer.parseInt(getNextArgRequired());
1764 StopUserCallback callback = wait ? new StopUserCallback() : null;
1765
1766 int res = mInterface.stopUser(user, force, callback);
1767 if (res != ActivityManager.USER_OP_SUCCESS) {
1768 String txt = "";
1769 switch (res) {
1770 case ActivityManager.USER_OP_IS_CURRENT:
1771 txt = " (Can't stop current user)";
1772 break;
1773 case ActivityManager.USER_OP_UNKNOWN_USER:
1774 txt = " (Unknown user " + user + ")";
1775 break;
1776 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
1777 txt = " (System user cannot be stopped)";
1778 break;
1779 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP:
1780 txt = " (Can't stop user " + user
1781 + " - one of its related users can't be stopped)";
1782 break;
1783 }
1784 getErrPrintWriter().println("Switch failed: " + res + txt);
1785 return -1;
1786 } else if (callback != null) {
1787 callback.waitForFinish();
1788 }
1789 return 0;
1790 }
1791
1792 int runIsUserStopped(PrintWriter pw) {
1793 int userId = UserHandle.parseUserArg(getNextArgRequired());
1794 boolean stopped = mInternal.isUserStopped(userId);
1795 pw.println(stopped);
1796 return 0;
1797 }
1798
1799 int runGetStartedUserState(PrintWriter pw) throws RemoteException {
1800 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1801 "runGetStartedUserState()");
1802 final int userId = Integer.parseInt(getNextArgRequired());
1803 try {
1804 pw.println(mInternal.getStartedUserState(userId));
1805 } catch (NullPointerException e) {
1806 pw.println("User is not started: " + userId);
1807 }
Dianne Hackborn2e441072015-10-28 18:00:57 -07001808 return 0;
1809 }
1810
1811 int runTrackAssociations(PrintWriter pw) {
1812 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Makoto Onukid5e74ed2019-01-31 15:50:18 -08001813 "runTrackAssociations()");
Dianne Hackborn2e441072015-10-28 18:00:57 -07001814 synchronized (mInternal) {
1815 if (!mInternal.mTrackingAssociations) {
1816 mInternal.mTrackingAssociations = true;
1817 pw.println("Association tracking started.");
1818 } else {
1819 pw.println("Association tracking already enabled.");
1820 }
1821 }
1822 return 0;
1823 }
1824
1825 int runUntrackAssociations(PrintWriter pw) {
1826 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Makoto Onukid5e74ed2019-01-31 15:50:18 -08001827 "runUntrackAssociations()");
Dianne Hackborn2e441072015-10-28 18:00:57 -07001828 synchronized (mInternal) {
1829 if (mInternal.mTrackingAssociations) {
1830 mInternal.mTrackingAssociations = false;
1831 mInternal.mAssociations.clear();
1832 pw.println("Association tracking stopped.");
1833 } else {
1834 pw.println("Association tracking not running.");
1835 }
1836 }
1837 return 0;
1838 }
1839
Felipe Leme2f1b2272016-03-25 16:15:02 -07001840 int getUidState(PrintWriter pw) throws RemoteException {
1841 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1842 "getUidState()");
1843 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
1844 pw.print(state);
1845 pw.print(" (");
1846 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
1847 pw.println(")");
1848 return 0;
1849 }
1850
Dianne Hackborn331084d2016-10-07 17:57:00 -07001851 private List<Configuration> getRecentConfigurations(int days) {
1852 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1853 Context.USAGE_STATS_SERVICE));
1854 final long now = System.currentTimeMillis();
1855 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
Sudheer Shanka28537b62016-09-07 11:12:31 -07001856 try {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001857 @SuppressWarnings("unchecked")
1858 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
1859 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
1860 if (configStatsSlice == null) {
1861 return Collections.emptyList();
1862 }
1863
1864 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
1865 final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
1866 final int configStatsListSize = configStatsList.size();
1867 for (int i = 0; i < configStatsListSize; i++) {
1868 final ConfigurationStats stats = configStatsList.get(i);
1869 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
1870 if (indexOfKey < 0) {
1871 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
1872 } else {
1873 recentConfigs.setValueAt(indexOfKey,
1874 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
1875 }
1876 }
1877
1878 final Comparator<Configuration> comparator = new Comparator<Configuration>() {
1879 @Override
1880 public int compare(Configuration a, Configuration b) {
1881 return recentConfigs.get(b).compareTo(recentConfigs.get(a));
1882 }
1883 };
1884
1885 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
1886 configs.addAll(recentConfigs.keySet());
1887 Collections.sort(configs, comparator);
1888 return configs;
1889
1890 } catch (RemoteException e) {
1891 return Collections.emptyList();
Sudheer Shanka28537b62016-09-07 11:12:31 -07001892 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001893 }
1894
Dianne Hackborn337e01a2018-02-27 17:16:37 -08001895 /**
1896 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
1897 * and EGLSurface and querying extensions.
1898 *
1899 * @param egl An EGL API object
1900 * @param display An EGLDisplay to create a context and surface with
1901 * @param config The EGLConfig to get the extensions for
1902 * @param surfaceSize eglCreatePbufferSurface generic parameters
1903 * @param contextAttribs eglCreateContext generic parameters
1904 * @param glExtensions A Set<String> to add GL extensions to
1905 */
1906 private static void addExtensionsForConfig(
1907 EGL10 egl,
1908 EGLDisplay display,
1909 EGLConfig config,
1910 int[] surfaceSize,
1911 int[] contextAttribs,
1912 Set<String> glExtensions) {
1913 // Create a context.
1914 EGLContext context =
1915 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
1916 // No-op if we can't create a context.
1917 if (context == EGL10.EGL_NO_CONTEXT) {
1918 return;
1919 }
1920
1921 // Create a surface.
1922 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
1923 if (surface == EGL10.EGL_NO_SURFACE) {
1924 egl.eglDestroyContext(display, context);
1925 return;
1926 }
1927
1928 // Update the current surface and context.
1929 egl.eglMakeCurrent(display, surface, surface, context);
1930
1931 // Get the list of extensions.
1932 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
1933 if (!TextUtils.isEmpty(extensionList)) {
1934 // The list of extensions comes from the driver separated by spaces.
1935 // Split them apart and add them into a Set for deduping purposes.
1936 for (String extension : extensionList.split(" ")) {
1937 glExtensions.add(extension);
1938 }
1939 }
1940
1941 // Tear down the context and surface for this config.
1942 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
1943 egl.eglDestroySurface(display, surface);
1944 egl.eglDestroyContext(display, context);
1945 }
1946
1947
1948 Set<String> getGlExtensionsFromDriver() {
1949 Set<String> glExtensions = new HashSet<>();
1950
1951 // Get the EGL implementation.
1952 EGL10 egl = (EGL10) EGLContext.getEGL();
1953 if (egl == null) {
1954 getErrPrintWriter().println("Warning: couldn't get EGL");
1955 return glExtensions;
1956 }
1957
1958 // Get the default display and initialize it.
1959 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
1960 int[] version = new int[2];
1961 egl.eglInitialize(display, version);
1962
1963 // Call getConfigs() in order to find out how many there are.
1964 int[] numConfigs = new int[1];
1965 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
1966 getErrPrintWriter().println("Warning: couldn't get EGL config count");
1967 return glExtensions;
1968 }
1969
1970 // Allocate space for all configs and ask again.
1971 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
1972 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
1973 getErrPrintWriter().println("Warning: couldn't get EGL configs");
1974 return glExtensions;
1975 }
1976
1977 // Allocate surface size parameters outside of the main loop to cut down
1978 // on GC thrashing. 1x1 is enough since we are only using it to get at
1979 // the list of extensions.
1980 int[] surfaceSize =
1981 new int[] {
1982 EGL10.EGL_WIDTH, 1,
1983 EGL10.EGL_HEIGHT, 1,
1984 EGL10.EGL_NONE
1985 };
1986
1987 // For when we need to create a GLES2.0 context.
1988 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
1989 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
1990
1991 // For getting return values from eglGetConfigAttrib
1992 int[] attrib = new int[1];
1993
1994 for (int i = 0; i < numConfigs[0]; i++) {
1995 // Get caveat for this config in order to skip slow (i.e. software) configs.
1996 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
1997 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
1998 continue;
1999 }
2000
2001 // If the config does not support pbuffers we cannot do an eglMakeCurrent
2002 // on it in addExtensionsForConfig(), so skip it here. Attempting to make
2003 // it current with a pbuffer will result in an EGL_BAD_MATCH error
2004 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
2005 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
2006 continue;
2007 }
2008
2009 final int EGL_OPENGL_ES_BIT = 0x0001;
2010 final int EGL_OPENGL_ES2_BIT = 0x0004;
2011 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
2012 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
2013 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
2014 }
2015 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
2016 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
2017 }
2018 }
2019
2020 // Release all EGL resources.
2021 egl.eglTerminate(display);
2022
2023 return glExtensions;
2024 }
2025
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002026 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
Jeff Change9467b22018-09-28 11:40:38 +08002027 PrintWriter pw, Configuration config, DisplayMetrics displayMetrics) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002028 long token = -1;
2029 if (protoOutputStream != null) {
2030 token = protoOutputStream.start(fieldId);
Jeff Change9467b22018-09-28 11:40:38 +08002031 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX,
2032 displayMetrics.widthPixels);
2033 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX,
2034 displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002035 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI,
2036 DisplayMetrics.DENSITY_DEVICE_STABLE);
2037 }
2038 if (pw != null) {
Jeff Change9467b22018-09-28 11:40:38 +08002039 pw.print("stable-width-px: "); pw.println(displayMetrics.widthPixels);
2040 pw.print("stable-height-px: "); pw.println(displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002041 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE);
2042 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002043
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002044 MemInfoReader memreader = new MemInfoReader();
2045 memreader.readMemInfo();
2046 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class);
2047 if (protoOutputStream != null) {
2048 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize());
2049 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM,
2050 ActivityManager.isLowRamDeviceStatic());
2051 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES,
2052 Runtime.getRuntime().availableProcessors());
2053 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK,
2054 kgm.isDeviceSecure());
2055 }
2056 if (pw != null) {
2057 pw.print("total-ram: "); pw.println(memreader.getTotalSize());
2058 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic());
2059 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors());
2060 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
2061 }
2062
Yunfan Chen75157d72018-07-27 14:47:21 +09002063 ConfigurationInfo configInfo = null;
2064 try {
2065 configInfo = mTaskInterface.getDeviceConfigurationInfo();
2066 } catch (RemoteException e) {
2067 throw e.rethrowFromSystemServer();
2068 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002069 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
2070 if (protoOutputStream != null) {
2071 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
2072 configInfo.reqGlEsVersion);
2073 }
2074 if (pw != null) {
2075 pw.print("opengl-version: 0x");
2076 pw.println(Integer.toHexString(configInfo.reqGlEsVersion));
2077 }
2078 }
2079
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002080 Set<String> glExtensionsSet = getGlExtensionsFromDriver();
2081 String[] glExtensions = new String[glExtensionsSet.size()];
2082 glExtensions = glExtensionsSet.toArray(glExtensions);
2083 Arrays.sort(glExtensions);
2084 for (int i = 0; i < glExtensions.length; i++) {
2085 if (protoOutputStream != null) {
2086 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
2087 glExtensions[i]);
2088 }
2089 if (pw != null) {
2090 pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
2091 }
2092
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002093 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002094
2095 PackageManager pm = mInternal.mContext.getPackageManager();
2096 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002097 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002098 for (int i = 0; i < slibs.size(); i++) {
2099 if (protoOutputStream != null) {
2100 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
2101 slibs.get(i).getName());
2102 }
2103 if (pw != null) {
2104 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName());
2105 }
2106 }
2107
2108 FeatureInfo[] features = pm.getSystemAvailableFeatures();
weijuncheng12030002018-10-30 14:07:53 +08002109 Arrays.sort(features, (o1, o2) -> {
2110 if (o1.name == o2.name) return 0;
2111 if (o1.name == null) return -1;
2112 if (o2.name == null) return 1;
2113 return o1.name.compareTo(o2.name);
2114 });
2115
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002116 for (int i = 0; i < features.length; i++) {
2117 if (features[i].name != null) {
2118 if (protoOutputStream != null) {
2119 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name);
2120 }
2121 if (pw != null) {
2122 pw.print("features: "); pw.println(features[i].name);
2123 }
2124 }
2125 }
2126
2127 if (protoOutputStream != null) {
2128 protoOutputStream.end(token);
2129 }
2130 }
2131
2132 int runGetConfig(PrintWriter pw) throws RemoteException {
2133 int days = -1;
Jeff Change9467b22018-09-28 11:40:38 +08002134 int displayId = Display.DEFAULT_DISPLAY;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002135 boolean asProto = false;
2136 boolean inclDevice = false;
2137
2138 String opt;
Jeff Change9467b22018-09-28 11:40:38 +08002139 while ((opt = getNextOption()) != null) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002140 if (opt.equals("--days")) {
2141 days = Integer.parseInt(getNextArgRequired());
2142 if (days <= 0) {
2143 throw new IllegalArgumentException("--days must be a positive integer");
2144 }
2145 } else if (opt.equals("--proto")) {
2146 asProto = true;
2147 } else if (opt.equals("--device")) {
2148 inclDevice = true;
Jeff Change9467b22018-09-28 11:40:38 +08002149 } else if (opt.equals("--display")) {
2150 displayId = Integer.parseInt(getNextArgRequired());
2151 if (displayId < 0) {
2152 throw new IllegalArgumentException("--display must be a non-negative integer");
2153 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002154 } else {
2155 getErrPrintWriter().println("Error: Unknown option: " + opt);
2156 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -07002157 }
2158 }
2159
2160 Configuration config = mInterface.getConfiguration();
2161 if (config == null) {
2162 getErrPrintWriter().println("Activity manager has no configuration");
2163 return -1;
2164 }
2165
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002166 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class);
Jeff Change9467b22018-09-28 11:40:38 +08002167 Display display = dm.getDisplay(displayId);
2168
2169 if (display == null) {
2170 getErrPrintWriter().println("Error: Display does not exist: " + displayId);
2171 return -1;
2172 }
2173
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002174 DisplayMetrics metrics = new DisplayMetrics();
2175 display.getMetrics(metrics);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002176
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002177 if (asProto) {
2178 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor());
2179 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics);
2180 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002181 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002182 }
2183 proto.flush();
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002184 } else {
2185 pw.println("config: " + Configuration.resourceQualifierString(config, metrics));
2186 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
2187 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002188 writeDeviceConfig(null, -1, pw, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002189 }
2190
2191 if (days >= 0) {
2192 final List<Configuration> recentConfigs = getRecentConfigurations(days);
2193 final int recentConfigSize = recentConfigs.size();
2194 if (recentConfigSize > 0) {
2195 pw.println("recentConfigs:");
2196 for (int i = 0; i < recentConfigSize; i++) {
2197 pw.println(" config: " + Configuration.resourceQualifierString(
2198 recentConfigs.get(i)));
2199 }
2200 }
2201 }
2202
Dianne Hackborn331084d2016-10-07 17:57:00 -07002203 }
2204 return 0;
2205 }
2206
2207 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
2208 boolean suppress = Boolean.valueOf(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002209 mTaskInterface.suppressResizeConfigChanges(suppress);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002210 return 0;
2211 }
2212
2213 int runSetInactive(PrintWriter pw) throws RemoteException {
2214 int userId = UserHandle.USER_CURRENT;
2215
2216 String opt;
2217 while ((opt=getNextOption()) != null) {
2218 if (opt.equals("--user")) {
2219 userId = UserHandle.parseUserArg(getNextArgRequired());
2220 } else {
2221 getErrPrintWriter().println("Error: Unknown option: " + opt);
2222 return -1;
2223 }
2224 }
2225 String packageName = getNextArgRequired();
2226 String value = getNextArgRequired();
2227
2228 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2229 Context.USAGE_STATS_SERVICE));
2230 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId);
2231 return 0;
2232 }
2233
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002234 private int bucketNameToBucketValue(String name) {
2235 String lower = name.toLowerCase();
2236 if (lower.startsWith("ac")) {
2237 return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
2238 } else if (lower.startsWith("wo")) {
2239 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
2240 } else if (lower.startsWith("fr")) {
2241 return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
2242 } else if (lower.startsWith("ra")) {
2243 return UsageStatsManager.STANDBY_BUCKET_RARE;
2244 } else if (lower.startsWith("ne")) {
2245 return UsageStatsManager.STANDBY_BUCKET_NEVER;
2246 } else {
2247 try {
2248 int bucket = Integer.parseInt(lower);
2249 return bucket;
2250 } catch (NumberFormatException nfe) {
2251 getErrPrintWriter().println("Error: Unknown bucket: " + name);
2252 }
2253 }
2254 return -1;
2255 }
2256
Amith Yamasani17fffee2017-09-29 13:17:43 -07002257 int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
2258 int userId = UserHandle.USER_CURRENT;
2259
2260 String opt;
2261 while ((opt=getNextOption()) != null) {
2262 if (opt.equals("--user")) {
2263 userId = UserHandle.parseUserArg(getNextArgRequired());
2264 } else {
2265 getErrPrintWriter().println("Error: Unknown option: " + opt);
2266 return -1;
2267 }
2268 }
2269 String packageName = getNextArgRequired();
2270 String value = getNextArgRequired();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002271 int bucket = bucketNameToBucketValue(value);
2272 if (bucket < 0) return -1;
Amith Yamasanie8789312017-12-10 14:34:26 -08002273 boolean multiple = peekNextArg() != null;
2274
Amith Yamasani17fffee2017-09-29 13:17:43 -07002275
2276 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2277 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002278 if (!multiple) {
2279 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
2280 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002281 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
2282 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002283 while ((packageName = getNextArg()) != null) {
2284 value = getNextArgRequired();
2285 bucket = bucketNameToBucketValue(value);
2286 if (bucket < 0) continue;
Suprabh Shukla868bde22018-02-20 20:59:52 -08002287 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002288 }
Suprabh Shukla868bde22018-02-20 20:59:52 -08002289 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
2290 usm.setAppStandbyBuckets(slice, userId);
Amith Yamasanie8789312017-12-10 14:34:26 -08002291 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002292 return 0;
2293 }
2294
2295 int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
2296 int userId = UserHandle.USER_CURRENT;
2297
2298 String opt;
2299 while ((opt=getNextOption()) != null) {
2300 if (opt.equals("--user")) {
2301 userId = UserHandle.parseUserArg(getNextArgRequired());
2302 } else {
2303 getErrPrintWriter().println("Error: Unknown option: " + opt);
2304 return -1;
2305 }
2306 }
Amith Yamasanie8789312017-12-10 14:34:26 -08002307 String packageName = getNextArg();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002308
2309 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2310 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002311 if (packageName != null) {
2312 int bucket = usm.getAppStandbyBucket(packageName, null, userId);
2313 pw.println(bucket);
2314 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002315 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -08002316 SHELL_PACKAGE_NAME, userId);
Suprabh Shukla868bde22018-02-20 20:59:52 -08002317 for (AppStandbyInfo bucketInfo : buckets.getList()) {
2318 pw.print(bucketInfo.mPackageName); pw.print(": ");
2319 pw.println(bucketInfo.mStandbyBucket);
Amith Yamasanie8789312017-12-10 14:34:26 -08002320 }
2321 }
Amith Yamasani17fffee2017-09-29 13:17:43 -07002322 return 0;
2323 }
2324
Dianne Hackborn331084d2016-10-07 17:57:00 -07002325 int runGetInactive(PrintWriter pw) throws RemoteException {
2326 int userId = UserHandle.USER_CURRENT;
2327
2328 String opt;
2329 while ((opt=getNextOption()) != null) {
2330 if (opt.equals("--user")) {
2331 userId = UserHandle.parseUserArg(getNextArgRequired());
2332 } else {
2333 getErrPrintWriter().println("Error: Unknown option: " + opt);
2334 return -1;
2335 }
2336 }
2337 String packageName = getNextArgRequired();
2338
2339 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2340 Context.USAGE_STATS_SERVICE));
2341 boolean isIdle = usm.isAppInactive(packageName, userId);
2342 pw.println("Idle=" + isIdle);
2343 return 0;
2344 }
2345
2346 int runSendTrimMemory(PrintWriter pw) throws RemoteException {
2347 int userId = UserHandle.USER_CURRENT;
2348 String opt;
2349 while ((opt = getNextOption()) != null) {
2350 if (opt.equals("--user")) {
2351 userId = UserHandle.parseUserArg(getNextArgRequired());
2352 if (userId == UserHandle.USER_ALL) {
2353 getErrPrintWriter().println("Error: Can't use user 'all'");
2354 return -1;
2355 }
2356 } else {
2357 getErrPrintWriter().println("Error: Unknown option: " + opt);
2358 return -1;
2359 }
2360 }
2361
2362 String proc = getNextArgRequired();
2363 String levelArg = getNextArgRequired();
2364 int level;
2365 switch (levelArg) {
2366 case "HIDDEN":
2367 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
2368 break;
2369 case "RUNNING_MODERATE":
2370 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
2371 break;
2372 case "BACKGROUND":
2373 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
2374 break;
2375 case "RUNNING_LOW":
2376 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
2377 break;
2378 case "MODERATE":
2379 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
2380 break;
2381 case "RUNNING_CRITICAL":
2382 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
2383 break;
2384 case "COMPLETE":
2385 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
2386 break;
2387 default:
Dianne Hackborne51505a2017-08-07 17:13:52 -07002388 try {
2389 level = Integer.parseInt(levelArg);
2390 } catch (NumberFormatException e) {
2391 getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
2392 return -1;
2393 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002394 }
2395 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
2396 getErrPrintWriter().println("Unknown error: failed to set trim level");
2397 return -1;
2398 }
2399 return 0;
2400 }
2401
Andrii Kulian839def92016-11-02 10:58:58 -07002402 int runDisplay(PrintWriter pw) throws RemoteException {
2403 String op = getNextArgRequired();
2404 switch (op) {
2405 case "move-stack":
2406 return runDisplayMoveStack(pw);
2407 default:
2408 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2409 return -1;
2410 }
2411 }
2412
Dianne Hackborn331084d2016-10-07 17:57:00 -07002413 int runStack(PrintWriter pw) throws RemoteException {
2414 String op = getNextArgRequired();
2415 switch (op) {
Andrii Kulian839def92016-11-02 10:58:58 -07002416 case "move-task":
Dianne Hackborn331084d2016-10-07 17:57:00 -07002417 return runStackMoveTask(pw);
2418 case "resize":
2419 return runStackResize(pw);
2420 case "resize-animated":
2421 return runStackResizeAnimated(pw);
2422 case "resize-docked-stack":
2423 return runStackResizeDocked(pw);
2424 case "positiontask":
2425 return runStackPositionTask(pw);
2426 case "list":
2427 return runStackList(pw);
2428 case "info":
2429 return runStackInfo(pw);
2430 case "move-top-activity-to-pinned-stack":
2431 return runMoveTopActivityToPinnedStack(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002432 case "remove":
2433 return runStackRemove(pw);
2434 default:
2435 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2436 return -1;
2437 }
2438 }
2439
2440
2441 private Rect getBounds() {
2442 String leftStr = getNextArgRequired();
2443 int left = Integer.parseInt(leftStr);
2444 String topStr = getNextArgRequired();
2445 int top = Integer.parseInt(topStr);
2446 String rightStr = getNextArgRequired();
2447 int right = Integer.parseInt(rightStr);
2448 String bottomStr = getNextArgRequired();
2449 int bottom = Integer.parseInt(bottomStr);
2450 if (left < 0) {
2451 getErrPrintWriter().println("Error: bad left arg: " + leftStr);
2452 return null;
2453 }
2454 if (top < 0) {
2455 getErrPrintWriter().println("Error: bad top arg: " + topStr);
2456 return null;
2457 }
2458 if (right <= 0) {
2459 getErrPrintWriter().println("Error: bad right arg: " + rightStr);
2460 return null;
2461 }
2462 if (bottom <= 0) {
2463 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr);
2464 return null;
2465 }
2466 return new Rect(left, top, right, bottom);
2467 }
2468
Andrii Kulian839def92016-11-02 10:58:58 -07002469 int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
2470 String stackIdStr = getNextArgRequired();
2471 int stackId = Integer.parseInt(stackIdStr);
2472 String displayIdStr = getNextArgRequired();
2473 int displayId = Integer.parseInt(displayIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002474 mTaskInterface.moveStackToDisplay(stackId, displayId);
Andrii Kulian839def92016-11-02 10:58:58 -07002475 return 0;
2476 }
2477
Dianne Hackborn331084d2016-10-07 17:57:00 -07002478 int runStackMoveTask(PrintWriter pw) throws RemoteException {
2479 String taskIdStr = getNextArgRequired();
2480 int taskId = Integer.parseInt(taskIdStr);
2481 String stackIdStr = getNextArgRequired();
2482 int stackId = Integer.parseInt(stackIdStr);
2483 String toTopStr = getNextArgRequired();
2484 final boolean toTop;
2485 if ("true".equals(toTopStr)) {
2486 toTop = true;
2487 } else if ("false".equals(toTopStr)) {
2488 toTop = false;
2489 } else {
2490 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr);
2491 return -1;
2492 }
2493
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002494 mTaskInterface.moveTaskToStack(taskId, stackId, toTop);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002495 return 0;
2496 }
2497
2498 int runStackResize(PrintWriter pw) throws RemoteException {
2499 String stackIdStr = getNextArgRequired();
2500 int stackId = Integer.parseInt(stackIdStr);
2501 final Rect bounds = getBounds();
2502 if (bounds == null) {
2503 getErrPrintWriter().println("Error: invalid input bounds");
2504 return -1;
2505 }
2506 return resizeStack(stackId, bounds, 0);
2507 }
2508
2509 int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
2510 String stackIdStr = getNextArgRequired();
2511 int stackId = Integer.parseInt(stackIdStr);
2512 final Rect bounds;
2513 if ("null".equals(peekNextArg())) {
2514 bounds = null;
2515 } else {
2516 bounds = getBounds();
2517 if (bounds == null) {
2518 getErrPrintWriter().println("Error: invalid input bounds");
2519 return -1;
2520 }
2521 }
2522 return resizeStackUnchecked(stackId, bounds, 0, true);
2523 }
2524
2525 int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate)
2526 throws RemoteException {
2527 try {
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002528 mTaskInterface.resizeStack(stackId, bounds, false, false, animate, -1);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002529 Thread.sleep(delayMs);
2530 } catch (InterruptedException e) {
2531 }
2532 return 0;
2533 }
2534
2535 int runStackResizeDocked(PrintWriter pw) throws RemoteException {
2536 final Rect bounds = getBounds();
2537 final Rect taskBounds = getBounds();
2538 if (bounds == null || taskBounds == null) {
2539 getErrPrintWriter().println("Error: invalid input bounds");
2540 return -1;
2541 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002542 mTaskInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002543 return 0;
2544 }
2545
2546 int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException {
2547 if (bounds == null) {
2548 getErrPrintWriter().println("Error: invalid input bounds");
2549 return -1;
2550 }
2551 return resizeStackUnchecked(stackId, bounds, delayMs, false);
2552 }
2553
2554 int runStackPositionTask(PrintWriter pw) throws RemoteException {
2555 String taskIdStr = getNextArgRequired();
2556 int taskId = Integer.parseInt(taskIdStr);
2557 String stackIdStr = getNextArgRequired();
2558 int stackId = Integer.parseInt(stackIdStr);
2559 String positionStr = getNextArgRequired();
2560 int position = Integer.parseInt(positionStr);
2561
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002562 mTaskInterface.positionTaskInStack(taskId, stackId, position);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002563 return 0;
2564 }
2565
2566 int runStackList(PrintWriter pw) throws RemoteException {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002567 List<ActivityManager.StackInfo> stacks = mTaskInterface.getAllStackInfos();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002568 for (ActivityManager.StackInfo info : stacks) {
2569 pw.println(info);
2570 }
2571 return 0;
2572 }
2573
2574 int runStackInfo(PrintWriter pw) throws RemoteException {
Wale Ogunwale68278562017-09-23 17:13:55 -07002575 int windowingMode = Integer.parseInt(getNextArgRequired());
2576 int activityType = Integer.parseInt(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002577 ActivityManager.StackInfo info = mTaskInterface.getStackInfo(windowingMode, activityType);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002578 pw.println(info);
2579 return 0;
2580 }
2581
2582 int runStackRemove(PrintWriter pw) throws RemoteException {
2583 String stackIdStr = getNextArgRequired();
2584 int stackId = Integer.parseInt(stackIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002585 mTaskInterface.removeStack(stackId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002586 return 0;
2587 }
2588
2589 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException {
2590 int stackId = Integer.parseInt(getNextArgRequired());
2591 final Rect bounds = getBounds();
2592 if (bounds == null) {
2593 getErrPrintWriter().println("Error: invalid input bounds");
2594 return -1;
2595 }
2596
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002597 if (!mTaskInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -07002598 getErrPrintWriter().println("Didn't move top activity to pinned stack.");
2599 return -1;
2600 }
2601 return 0;
2602 }
2603
Dianne Hackborn331084d2016-10-07 17:57:00 -07002604 void setBoundsSide(Rect bounds, String side, int value) {
2605 switch (side) {
2606 case "l":
2607 bounds.left = value;
2608 break;
2609 case "r":
2610 bounds.right = value;
2611 break;
2612 case "t":
2613 bounds.top = value;
2614 break;
2615 case "b":
2616 bounds.bottom = value;
2617 break;
2618 default:
2619 getErrPrintWriter().println("Unknown set side: " + side);
2620 break;
2621 }
2622 }
2623
2624 int runTask(PrintWriter pw) throws RemoteException {
2625 String op = getNextArgRequired();
2626 if (op.equals("lock")) {
2627 return runTaskLock(pw);
2628 } else if (op.equals("resizeable")) {
2629 return runTaskResizeable(pw);
2630 } else if (op.equals("resize")) {
2631 return runTaskResize(pw);
David Stevensee9e2772017-02-09 16:30:27 -08002632 } else if (op.equals("focus")) {
2633 return runTaskFocus(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002634 } else {
2635 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2636 return -1;
2637 }
2638 }
2639
2640 int runTaskLock(PrintWriter pw) throws RemoteException {
2641 String taskIdStr = getNextArgRequired();
2642 if (taskIdStr.equals("stop")) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002643 mTaskInterface.stopSystemLockTaskMode();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002644 } else {
2645 int taskId = Integer.parseInt(taskIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002646 mTaskInterface.startSystemLockTaskMode(taskId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002647 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002648 pw.println("Activity manager is " + (mTaskInterface.isInLockTaskMode() ? "" : "not ") +
Dianne Hackborn331084d2016-10-07 17:57:00 -07002649 "in lockTaskMode");
2650 return 0;
2651 }
2652
2653 int runTaskResizeable(PrintWriter pw) throws RemoteException {
2654 final String taskIdStr = getNextArgRequired();
2655 final int taskId = Integer.parseInt(taskIdStr);
2656 final String resizeableStr = getNextArgRequired();
2657 final int resizeableMode = Integer.parseInt(resizeableStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002658 mTaskInterface.setTaskResizeable(taskId, resizeableMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002659 return 0;
2660 }
2661
2662 int runTaskResize(PrintWriter pw) throws RemoteException {
2663 final String taskIdStr = getNextArgRequired();
2664 final int taskId = Integer.parseInt(taskIdStr);
2665 final Rect bounds = getBounds();
2666 if (bounds == null) {
2667 getErrPrintWriter().println("Error: invalid input bounds");
2668 return -1;
2669 }
2670 taskResize(taskId, bounds, 0, false);
2671 return 0;
2672 }
2673
2674 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
2675 throws RemoteException {
2676 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002677 mTaskInterface.resizeTask(taskId, bounds, resizeMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002678 try {
2679 Thread.sleep(delay_ms);
2680 } catch (InterruptedException e) {
2681 }
2682 }
2683
Dianne Hackborn331084d2016-10-07 17:57:00 -07002684 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
2685 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
2686 throws RemoteException {
2687 int maxMove;
2688 if (movingForward) {
2689 while (maxToTravel > 0
2690 && ((horizontal && taskRect.right < stackRect.right)
2691 ||(!horizontal && taskRect.bottom < stackRect.bottom))) {
2692 if (horizontal) {
2693 maxMove = Math.min(stepSize, stackRect.right - taskRect.right);
2694 maxToTravel -= maxMove;
2695 taskRect.right += maxMove;
2696 taskRect.left += maxMove;
2697 } else {
2698 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom);
2699 maxToTravel -= maxMove;
2700 taskRect.top += maxMove;
2701 taskRect.bottom += maxMove;
2702 }
2703 taskResize(taskId, taskRect, delay_ms, false);
2704 }
2705 } else {
2706 while (maxToTravel < 0
2707 && ((horizontal && taskRect.left > stackRect.left)
2708 ||(!horizontal && taskRect.top > stackRect.top))) {
2709 if (horizontal) {
2710 maxMove = Math.min(stepSize, taskRect.left - stackRect.left);
2711 maxToTravel -= maxMove;
2712 taskRect.right -= maxMove;
2713 taskRect.left -= maxMove;
2714 } else {
2715 maxMove = Math.min(stepSize, taskRect.top - stackRect.top);
2716 maxToTravel -= maxMove;
2717 taskRect.top -= maxMove;
2718 taskRect.bottom -= maxMove;
2719 }
2720 taskResize(taskId, taskRect, delay_ms, false);
2721 }
2722 }
2723 // Return the remaining distance we didn't travel because we reached the target location.
2724 return maxToTravel;
2725 }
2726
2727 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) {
2728 int stepSize = 0;
2729 if (greaterThanTarget && target < current) {
2730 current -= inStepSize;
2731 stepSize = inStepSize;
2732 if (target > current) {
2733 stepSize -= (target - current);
2734 }
2735 }
2736 if (!greaterThanTarget && target > current) {
2737 current += inStepSize;
2738 stepSize = inStepSize;
2739 if (target < current) {
2740 stepSize += (current - target);
2741 }
2742 }
2743 return stepSize;
2744 }
2745
David Stevensee9e2772017-02-09 16:30:27 -08002746 int runTaskFocus(PrintWriter pw) throws RemoteException {
2747 final int taskId = Integer.parseInt(getNextArgRequired());
2748 pw.println("Setting focus to task " + taskId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002749 mTaskInterface.setFocusedTask(taskId);
David Stevensee9e2772017-02-09 16:30:27 -08002750 return 0;
2751 }
2752
Dianne Hackborn331084d2016-10-07 17:57:00 -07002753 int runWrite(PrintWriter pw) {
2754 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2755 "registerUidObserver()");
Wale Ogunwaled7889f52018-10-25 11:03:20 -07002756 mInternal.mAtmInternal.flushRecentTasks();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002757 pw.println("All tasks persisted.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002758 return 0;
2759 }
2760
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002761 int runAttachAgent(PrintWriter pw) {
2762 // TODO: revisit the permissions required for attaching agents
2763 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2764 "attach-agent");
2765 String process = getNextArgRequired();
2766 String agent = getNextArgRequired();
2767 String opt;
2768 if ((opt = getNextArg()) != null) {
2769 pw.println("Error: Unknown option: " + opt);
2770 return -1;
2771 }
2772 mInternal.attachAgent(process, agent);
2773 return 0;
2774 }
2775
Michael Kwan94438b72016-11-03 15:30:34 -07002776 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
Matthew Ng626e0cc2016-12-07 17:25:53 -08002777 final Resources res = getResources(pw);
2778 if (res == null) {
2779 return -1;
2780 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002781 pw.println(ActivityTaskManager.supportsMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002782 return 0;
2783 }
2784
2785 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException {
2786 final Resources res = getResources(pw);
2787 if (res == null) {
2788 return -1;
2789 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002790 pw.println(ActivityTaskManager.supportsSplitScreenMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002791 return 0;
2792 }
2793
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002794 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
2795 int userid = UserHandle.parseUserArg(getNextArgRequired());
2796 ArrayList<String> packages = new ArrayList<>();
2797 packages.add(getNextArgRequired());
2798 String packageName;
2799 while ((packageName = getNextArg()) != null) {
2800 packages.add(packageName);
2801 }
2802 mInternal.scheduleApplicationInfoChanged(packages, userid);
2803 pw.println("Packages updated with most recent ApplicationInfos.");
2804 return 0;
2805 }
2806
Arthur Hsuf3f3a602017-02-21 14:01:53 -08002807 int runNoHomeScreen(PrintWriter pw) throws RemoteException {
2808 final Resources res = getResources(pw);
2809 if (res == null) {
2810 return -1;
2811 }
2812 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen));
2813 return 0;
2814 }
2815
Jeff Sharkeyfd658132017-05-03 11:38:01 -06002816 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
2817 mInternal.waitForBroadcastIdle(pw);
2818 return 0;
2819 }
2820
Matthew Ng626e0cc2016-12-07 17:25:53 -08002821 private Resources getResources(PrintWriter pw) throws RemoteException {
Michael Kwan94438b72016-11-03 15:30:34 -07002822 // system resources does not contain all the device configuration, construct it manually.
2823 Configuration config = mInterface.getConfiguration();
2824 if (config == null) {
2825 pw.println("Error: Activity manager has no configuration");
Matthew Ng626e0cc2016-12-07 17:25:53 -08002826 return null;
Michael Kwan94438b72016-11-03 15:30:34 -07002827 }
2828
2829 final DisplayMetrics metrics = new DisplayMetrics();
2830 metrics.setToDefaults();
2831
Matthew Ng626e0cc2016-12-07 17:25:53 -08002832 return new Resources(AssetManager.getSystem(), metrics, config);
Michael Kwan94438b72016-11-03 15:30:34 -07002833 }
2834
Dianne Hackborn2e441072015-10-28 18:00:57 -07002835 @Override
2836 public void onHelp() {
2837 PrintWriter pw = getOutPrintWriter();
2838 dumpHelp(pw, mDumping);
2839 }
2840
2841 static void dumpHelp(PrintWriter pw, boolean dumping) {
2842 if (dumping) {
2843 pw.println("Activity manager dump options:");
2844 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
2845 pw.println(" WHAT may be one of:");
2846 pw.println(" a[ctivities]: activity stack state");
2847 pw.println(" r[recents]: recent activities state");
2848 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002849 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002850 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
2851 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
2852 pw.println(" o[om]: out of memory management");
2853 pw.println(" perm[issions]: URI permission grant state");
2854 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
2855 pw.println(" provider [COMP_SPEC]: provider client-side state");
2856 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborn769b2e72018-12-05 08:51:20 -08002857 pw.println(" allowed-associations: current package association restrictions");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002858 pw.println(" as[sociations]: tracked app associations");
Dianne Hackborna631d562018-11-20 15:58:15 -08002859 pw.println(" lmk: stats on low memory killer");
2860 pw.println(" lru: raw LRU process list");
2861 pw.println(" binder-proxies: stats on binder objects and IPCs");
Dianne Hackborn0ef403e2017-01-24 18:22:15 -08002862 pw.println(" settings: currently applied config settings");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002863 pw.println(" service [COMP_SPEC]: service client-side state");
2864 pw.println(" package [PACKAGE_NAME]: all state related to given package");
2865 pw.println(" all: dump all activities");
2866 pw.println(" top: dump the top activity");
2867 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
2868 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
2869 pw.println(" a partial substring in a component name, a");
2870 pw.println(" hex object identifier.");
2871 pw.println(" -a: include all available server state.");
2872 pw.println(" -c: include client state.");
2873 pw.println(" -p: limit output to given package.");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002874 pw.println(" --checkin: output checkin format, resetting data.");
2875 pw.println(" --C: output checkin format, not resetting data.");
Steven Timotius4346f0a2017-09-12 11:07:21 -07002876 pw.println(" --proto: output dump in protocol buffer format.");
Felipe Lemeb546ca72018-08-15 08:44:12 -07002877 pw.println(" --autofill: dump just the autofill-related state of an activity");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002878 } else {
2879 pw.println("Activity manager (activity) commands:");
2880 pw.println(" help");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002881 pw.println(" Print this help text.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002882 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002883 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002884 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002885 pw.println(" Start an Activity. Options are:");
2886 pw.println(" -D: enable debugging");
2887 pw.println(" -N: enable native debugging");
2888 pw.println(" -W: wait for launch to complete");
2889 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>");
2890 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2891 pw.println(" between samples (use with --start-profiler)");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002892 pw.println(" --streaming: stream the profiling output to the specified file");
2893 pw.println(" (use with --start-profiler)");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002894 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
Andreas Gampe83085bb2017-06-26 17:54:11 -07002895 pw.println(" --attach-agent <agent>: attach the given agent before binding");
Andreas Gampeab8a63b2018-01-05 13:55:15 -08002896 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002897 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
2898 pw.println(" the top activity will be finished.");
2899 pw.println(" -S: force stop the target app before starting the activity");
2900 pw.println(" --track-allocation: enable tracking of object allocations");
2901 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2902 pw.println(" specified then run as the current user.");
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002903 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into.");
2904 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
Louis Changf379f802018-07-13 09:41:28 +08002905 pw.println(" --display <DISPLAY_ID>: The display to launch the activity into.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002906 pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
2907 pw.println(" Start a Service. Options are:");
2908 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2909 pw.println(" specified then run as the current user.");
Jaewan Kim329b35f2017-04-11 11:19:49 +09002910 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
2911 pw.println(" Start a foreground Service. Options are:");
2912 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2913 pw.println(" specified then run as the current user.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002914 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
2915 pw.println(" Stop a Service. Options are:");
2916 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2917 pw.println(" specified then run as the current user.");
2918 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>");
2919 pw.println(" Send a broadcast Intent. Options are:");
2920 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not");
2921 pw.println(" specified then send to all users.");
2922 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002923 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
David Brazdild5d42172018-02-14 19:39:03 +00002924 pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07002925 pw.println(" [--no-isolated-storage]");
Dianne Hackborn28824062016-10-18 13:19:20 -07002926 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
2927 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
2928 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
2929 pw.println(" is only one instrumentation. Options are:");
2930 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with");
2931 pw.println(" [-e perf true] to generate raw output for performance measurements.");
2932 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a");
2933 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]].");
2934 pw.println(" -p <FILE>: write profiling data to <FILE>");
Mike Mad2239822017-10-31 12:30:42 -07002935 pw.println(" -m: Write output as protobuf to stdout (machine readable)");
2936 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine");
2937 pw.println(" readable). If path is not specified, default directory and file name will");
2938 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto");
Dianne Hackborn28824062016-10-18 13:19:20 -07002939 pw.println(" -w: wait for instrumentation to finish before returning. Required for");
2940 pw.println(" test runners.");
2941 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
2942 pw.println(" current user if not specified.");
David Brazdild5d42172018-02-14 19:39:03 +00002943 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07002944 pw.println(" --no-isolated-storage: don't use isolated storage sandbox and ");
2945 pw.println(" mount full external storage");
Dianne Hackborn28824062016-10-18 13:19:20 -07002946 pw.println(" --no-window-animation: turn off window animations while running.");
2947 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
2948 pw.println(" This assumes that the process supports the selected ABI.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002949 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]");
2950 pw.println(" Trace IPC transactions.");
2951 pw.println(" start: start tracing IPC transactions.");
2952 pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
2953 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
2954 pw.println(" profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002955 pw.println(" [--streaming] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002956 pw.println(" Start and stop profiler on a process. The given <PROCESS> argument");
2957 pw.println(" may be either a process name or pid. Options are:");
2958 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2959 pw.println(" specify user of process to profile; uses current user if not specified.");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002960 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2961 pw.println(" between samples");
2962 pw.println(" --streaming: stream the profiling output to the specified file");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002963 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002964 pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
2965 pw.println(" be either a process name or pid. Options are:");
2966 pw.println(" -n: dump native heap instead of managed heap");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002967 pw.println(" -g: force GC before dumping the heap");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002968 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2969 pw.println(" specify user of process to dump; uses current user if not specified.");
2970 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>");
2971 pw.println(" Set application <PACKAGE> to debug. Options are:");
2972 pw.println(" -w: wait for debugger when application starts");
2973 pw.println(" --persistent: retain this value");
2974 pw.println(" clear-debug-app");
2975 pw.println(" Clear the previously set-debug-app.");
2976 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>");
2977 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or");
2978 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
2979 pw.println(" clear-watch-heap");
2980 pw.println(" Clear the previously set-watch-heap.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002981 pw.println(" bug-report [--progress | --telephony]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002982 pw.println(" Request bug report generation; will launch a notification");
2983 pw.println(" when done to select where it should be delivered. Options are:");
2984 pw.println(" --progress: will launch a notification right away to show its progress.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002985 pw.println(" --telephony: will dump only telephony sections.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002986 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002987 pw.println(" Completely stop the given application package.");
Christopher Tate8aa8fe12017-01-20 17:50:32 -08002988 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>");
2989 pw.println(" Induce a VM crash in the specified package or process");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002990 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
Makoto Onuki6569c362018-02-27 15:52:01 -08002991 pw.println(" Kill all background processes associated with the given application.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002992 pw.println(" kill-all");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002993 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn85e35642017-01-12 15:10:57 -08002994 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
2995 pw.println(" If the given application's uid is in the background and waiting to");
2996 pw.println(" become idle (not allowing background services), do that now.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002997 pw.println(" monitor [--gdb <port>]");
2998 pw.println(" Start monitoring for crashes or ANRs.");
2999 pw.println(" --gdb: start gdbserv on the given port at crash/ANR");
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07003000 pw.println(" watch-uids [--oom <uid>]");
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01003001 pw.println(" Start watching for and reporting uid state changes.");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003002 pw.println(" --oom: specify a uid for which to report detailed change messages.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003003 pw.println(" hang [--allow-restart]");
3004 pw.println(" Hang the system.");
3005 pw.println(" --allow-restart: allow watchdog to perform normal system restart");
3006 pw.println(" restart");
3007 pw.println(" Restart the user-space system.");
3008 pw.println(" idle-maintenance");
3009 pw.println(" Perform idle maintenance now.");
3010 pw.println(" screen-compat [on|off] <PACKAGE>");
3011 pw.println(" Control screen compatibility mode of <PACKAGE>.");
3012 pw.println(" package-importance <PACKAGE>");
3013 pw.println(" Print current importance of <PACKAGE>.");
3014 pw.println(" to-uri [INTENT]");
3015 pw.println(" Print the given Intent specification as a URI.");
3016 pw.println(" to-intent-uri [INTENT]");
3017 pw.println(" Print the given Intent specification as an intent: URI.");
3018 pw.println(" to-app-uri [INTENT]");
3019 pw.println(" Print the given Intent specification as an android-app: URI.");
3020 pw.println(" switch-user <USER_ID>");
3021 pw.println(" Switch to put USER_ID in the foreground, starting");
3022 pw.println(" execution of that user if it is currently stopped.");
3023 pw.println(" get-current-user");
3024 pw.println(" Returns id of the current foreground user.");
3025 pw.println(" start-user <USER_ID>");
3026 pw.println(" Start USER_ID in background if it is currently stopped;");
3027 pw.println(" use switch-user if you want to start the user in foreground");
3028 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]");
3029 pw.println(" Attempt to unlock the given user using the given authorization token.");
3030 pw.println(" stop-user [-w] [-f] <USER_ID>");
3031 pw.println(" Stop execution of USER_ID, not allowing it to run any");
3032 pw.println(" code until a later explicit start or switch to it.");
3033 pw.println(" -w: wait for stop-user to complete.");
3034 pw.println(" -f: force stop even if there are related users that cannot be stopped.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003035 pw.println(" is-user-stopped <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003036 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07003037 pw.println(" get-started-user-state <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003038 pw.println(" Gets the current state of the given started user.");
3039 pw.println(" track-associations");
3040 pw.println(" Enable association tracking.");
3041 pw.println(" untrack-associations");
3042 pw.println(" Disable and clear association tracking.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003043 pw.println(" get-uid-state <UID>");
3044 pw.println(" Gets the process state of an app given its <UID>.");
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07003045 pw.println(" attach-agent <PROCESS> <FILE>");
3046 pw.println(" Attach an agent to the specified <PROCESS>, which may be either a process name or a PID.");
Jeff Change9467b22018-09-28 11:40:38 +08003047 pw.println(" get-config [--days N] [--device] [--proto] [--display <DISPLAY_ID>]");
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08003048 pw.println(" Retrieve the configuration and any recent configurations of the device.");
3049 pw.println(" --days: also return last N days of configurations that have been seen.");
3050 pw.println(" --device: also output global device configuration info.");
3051 pw.println(" --proto: return result as a proto; does not include --days info.");
Jeff Change9467b22018-09-28 11:40:38 +08003052 pw.println(" --display: Specify for which display to run the command; if not ");
3053 pw.println(" specified then run for the default display.");
Michael Kwan94438b72016-11-03 15:30:34 -07003054 pw.println(" supports-multiwindow");
3055 pw.println(" Returns true if the device supports multiwindow.");
Matthew Ng626e0cc2016-12-07 17:25:53 -08003056 pw.println(" supports-split-screen-multi-window");
3057 pw.println(" Returns true if the device supports split screen multiwindow.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003058 pw.println(" suppress-resize-config-changes <true|false>");
3059 pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
3060 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
3061 pw.println(" Sets the inactive state of an app.");
3062 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
3063 pw.println(" Returns the inactive state of an app.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003064 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
Amith Yamasani17fffee2017-09-29 13:17:43 -07003065 pw.println(" Puts an app in the standby bucket.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003066 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
3067 pw.println(" Returns the standby bucket of an app.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003068 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
3069 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003070 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 -07003071 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays.");
3072 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>");
3073 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003074 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
Andrii Kulian839def92016-11-02 10:58:58 -07003075 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003076 pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
3077 pw.println(" bottom (false) of <STACK_ID>.");
3078 pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3079 pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.");
3080 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3081 pw.println(" Same as resize, but allow animation.");
3082 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
3083 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
3084 pw.println(" and supplying temporary different task bounds indicated by");
3085 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003086 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3087 pw.println(" Moves the top activity from");
3088 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
3089 pw.println(" bounds of the pinned stack.");
3090 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>");
3091 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
3092 pw.println(" list");
3093 pw.println(" List all of the activity stacks and their sizes.");
Wale Ogunwale68278562017-09-23 17:13:55 -07003094 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
3095 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003096 pw.println(" remove <STACK_ID>");
3097 pw.println(" Remove stack <STACK_ID>.");
3098 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
3099 pw.println(" lock <TASK_ID>");
3100 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run.");
3101 pw.println(" lock stop");
3102 pw.println(" End the current task lock.");
3103 pw.println(" resizeable <TASK_ID> [0|1|2|3]");
3104 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:");
3105 pw.println(" 0: unresizeable");
3106 pw.println(" 1: crop_windows");
3107 pw.println(" 2: resizeable");
3108 pw.println(" 3: resizeable_and_pipable");
3109 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3110 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
3111 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
3112 pw.println(" has the specified bounds.");
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01003113 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
3114 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
3115 pw.println(" without restarting any processes.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003116 pw.println(" write");
3117 pw.println(" Write all pending state to storage.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003118 pw.println();
3119 Intent.printIntentArgsHelp(pw, "");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003120 }
3121 }
3122}