blob: 740c0da72fc861583548db9652bc7b56b6ebe14c [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;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -0800495 boolean hotLaunch = false;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700496 switch (res) {
497 case ActivityManager.START_SUCCESS:
498 launched = true;
499 break;
500 case ActivityManager.START_SWITCHES_CANCELED:
501 launched = true;
502 out.println(
503 "Warning: Activity not started because the "
504 + " current activity is being kept for the user.");
505 break;
506 case ActivityManager.START_DELIVERED_TO_TOP:
507 launched = true;
508 out.println(
509 "Warning: Activity not started, intent has "
510 + "been delivered to currently running "
511 + "top-most instance.");
512 break;
513 case ActivityManager.START_RETURN_INTENT_TO_CALLER:
514 launched = true;
515 out.println(
516 "Warning: Activity not started because intent "
517 + "should be handled by the caller");
518 break;
519 case ActivityManager.START_TASK_TO_FRONT:
520 launched = true;
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -0800521 //TODO(b/120981435) remove special case
522 hotLaunch = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700523 out.println(
524 "Warning: Activity not started, its current "
525 + "task has been brought to the front");
526 break;
527 case ActivityManager.START_INTENT_NOT_RESOLVED:
528 out.println(
529 "Error: Activity not started, unable to "
530 + "resolve " + intent.toString());
531 break;
532 case ActivityManager.START_CLASS_NOT_FOUND:
533 out.println(NO_CLASS_ERROR_CODE);
534 out.println("Error: Activity class " +
535 intent.getComponent().toShortString()
536 + " does not exist.");
537 break;
538 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
539 out.println(
540 "Error: Activity not started, you requested to "
541 + "both forward and receive its result");
542 break;
543 case ActivityManager.START_PERMISSION_DENIED:
544 out.println(
545 "Error: Activity not started, you do not "
546 + "have permission to access it.");
547 break;
548 case ActivityManager.START_NOT_VOICE_COMPATIBLE:
549 out.println(
550 "Error: Activity not started, voice control not allowed for: "
551 + intent);
552 break;
553 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
554 out.println(
555 "Error: Not allowed to start background user activity"
556 + " that shouldn't be displayed for all users.");
557 break;
558 default:
559 out.println(
560 "Error: Activity not started, unknown error code " + res);
561 break;
562 }
Dianne Hackborn331084d2016-10-07 17:57:00 -0700563 out.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700564 if (mWaitOption && launched) {
565 if (result == null) {
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700566 result = new WaitResult();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700567 result.who = intent.getComponent();
568 }
569 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
Vishnu Nairbb9ab4b2018-12-13 10:29:46 -0800570 final @WaitResult.LaunchState int launchState =
571 hotLaunch ? WaitResult.LAUNCH_STATE_HOT : result.launchState;
572 pw.println("LaunchState: " + launchStateToString(launchState));
Dianne Hackborn354736e2016-08-22 17:00:05 -0700573 if (result.who != null) {
574 pw.println("Activity: " + result.who.flattenToShortString());
575 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700576 if (result.totalTime >= 0) {
577 pw.println("TotalTime: " + result.totalTime);
578 }
579 pw.println("WaitTime: " + (endTime-startTime));
580 pw.println("Complete");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700581 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700582 }
583 mRepeat--;
584 if (mRepeat > 0) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700585 mTaskInterface.unhandledBack();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700586 }
587 } while (mRepeat > 0);
588 return 0;
589 }
590
Christopher Tate7e1368d2017-03-30 17:20:12 -0700591 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700592 final PrintWriter err = getErrPrintWriter();
593 Intent intent;
594 try {
595 intent = makeIntent(UserHandle.USER_CURRENT);
596 } catch (URISyntaxException e) {
597 throw new RuntimeException(e.getMessage(), e);
598 }
599 if (mUserId == UserHandle.USER_ALL) {
600 err.println("Error: Can't start activity with user 'all'");
601 return -1;
602 }
603 pw.println("Starting service: " + intent);
604 pw.flush();
605 ComponentName cn = mInterface.startService(null, intent, intent.getType(),
Christopher Tate242ba3e92017-04-14 15:07:06 -0700606 asForeground, SHELL_PACKAGE_NAME, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700607 if (cn == null) {
608 err.println("Error: Not found; no service started.");
609 return -1;
610 } else if (cn.getPackageName().equals("!")) {
611 err.println("Error: Requires permission " + cn.getClassName());
612 return -1;
613 } else if (cn.getPackageName().equals("!!")) {
614 err.println("Error: " + cn.getClassName());
615 return -1;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800616 } else if (cn.getPackageName().equals("?")) {
617 err.println("Error: " + cn.getClassName());
618 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700619 }
620 return 0;
621 }
622
623 int runStopService(PrintWriter pw) throws RemoteException {
624 final PrintWriter err = getErrPrintWriter();
625 Intent intent;
626 try {
627 intent = makeIntent(UserHandle.USER_CURRENT);
628 } catch (URISyntaxException e) {
629 throw new RuntimeException(e.getMessage(), e);
630 }
631 if (mUserId == UserHandle.USER_ALL) {
632 err.println("Error: Can't stop activity with user 'all'");
633 return -1;
634 }
635 pw.println("Stopping service: " + intent);
636 pw.flush();
637 int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
638 if (result == 0) {
639 err.println("Service not stopped: was not running.");
640 return -1;
641 } else if (result == 1) {
642 err.println("Service stopped");
643 return -1;
644 } else if (result == -1) {
645 err.println("Error stopping service");
646 return -1;
647 }
648 return 0;
649 }
650
651 final static class IntentReceiver extends IIntentReceiver.Stub {
652 private final PrintWriter mPw;
653 private boolean mFinished = false;
654
655 IntentReceiver(PrintWriter pw) {
656 mPw = pw;
657 }
658
659 @Override
660 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
661 boolean ordered, boolean sticky, int sendingUser) {
662 String line = "Broadcast completed: result=" + resultCode;
663 if (data != null) line = line + ", data=\"" + data + "\"";
664 if (extras != null) line = line + ", extras: " + extras;
665 mPw.println(line);
666 mPw.flush();
667 synchronized (this) {
668 mFinished = true;
669 notifyAll();
670 }
671 }
672
673 public synchronized void waitForFinish() {
674 try {
675 while (!mFinished) wait();
676 } catch (InterruptedException e) {
677 throw new IllegalStateException(e);
678 }
679 }
680 }
681
682 int runSendBroadcast(PrintWriter pw) throws RemoteException {
683 Intent intent;
684 try {
685 intent = makeIntent(UserHandle.USER_CURRENT);
686 } catch (URISyntaxException e) {
687 throw new RuntimeException(e.getMessage(), e);
688 }
Jeff Sharkey6a34e562016-12-21 09:56:00 -0700689 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700690 IntentReceiver receiver = new IntentReceiver(pw);
691 String[] requiredPermissions = mReceiverPermission == null ? null
692 : new String[] {mReceiverPermission};
693 pw.println("Broadcasting: " + intent);
694 pw.flush();
695 mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
696 android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
697 receiver.waitForFinish();
698 return 0;
699 }
700
Dianne Hackborn331084d2016-10-07 17:57:00 -0700701 int runTraceIpc(PrintWriter pw) throws RemoteException {
702 String op = getNextArgRequired();
703 if (op.equals("start")) {
704 return runTraceIpcStart(pw);
705 } else if (op.equals("stop")) {
706 return runTraceIpcStop(pw);
707 } else {
708 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'");
709 return -1;
710 }
711 }
712
713 int runTraceIpcStart(PrintWriter pw) throws RemoteException {
714 pw.println("Starting IPC tracing.");
715 pw.flush();
716 mInterface.startBinderTracking();
717 return 0;
718 }
719
720 int runTraceIpcStop(PrintWriter pw) throws RemoteException {
721 final PrintWriter err = getErrPrintWriter();
722 String opt;
723 String filename = null;
724 while ((opt=getNextOption()) != null) {
725 if (opt.equals("--dump-file")) {
726 filename = getNextArgRequired();
727 } else {
728 err.println("Error: Unknown option: " + opt);
729 return -1;
730 }
731 }
732 if (filename == null) {
733 err.println("Error: Specify filename to dump logs to.");
734 return -1;
735 }
736
737 File file = new File(filename);
738 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700739 ParcelFileDescriptor fd = openFileForSystem(filename, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700740 if (fd == null) {
741 return -1;
742 }
743
Dianne Hackborn331084d2016-10-07 17:57:00 -0700744 if (!mInterface.stopBinderTrackingAndDump(fd)) {
745 err.println("STOP TRACE FAILED.");
746 return -1;
747 }
748
749 pw.println("Stopped IPC tracing. Dumping logs to: " + filename);
750 return 0;
751 }
752
753 static void removeWallOption() {
754 String props = SystemProperties.get("dalvik.vm.extra-opts");
755 if (props != null && props.contains("-Xprofile:wallclock")) {
756 props = props.replace("-Xprofile:wallclock", "");
757 props = props.trim();
758 SystemProperties.set("dalvik.vm.extra-opts", props);
759 }
760 }
761
762 private int runProfile(PrintWriter pw) throws RemoteException {
763 final PrintWriter err = getErrPrintWriter();
764 String profileFile = null;
765 boolean start = false;
766 boolean wall = false;
767 int userId = UserHandle.USER_CURRENT;
768 int profileType = 0;
769 mSamplingInterval = 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800770 mStreaming = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700771
772 String process = null;
773
774 String cmd = getNextArgRequired();
775
776 if ("start".equals(cmd)) {
777 start = true;
778 String opt;
779 while ((opt=getNextOption()) != null) {
780 if (opt.equals("--user")) {
781 userId = UserHandle.parseUserArg(getNextArgRequired());
782 } else if (opt.equals("--wall")) {
783 wall = true;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800784 } else if (opt.equals("--streaming")) {
785 mStreaming = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700786 } else if (opt.equals("--sampling")) {
787 mSamplingInterval = Integer.parseInt(getNextArgRequired());
788 } else {
789 err.println("Error: Unknown option: " + opt);
790 return -1;
791 }
792 }
793 process = getNextArgRequired();
794 } else if ("stop".equals(cmd)) {
795 String opt;
796 while ((opt=getNextOption()) != null) {
797 if (opt.equals("--user")) {
798 userId = UserHandle.parseUserArg(getNextArgRequired());
799 } else {
800 err.println("Error: Unknown option: " + opt);
801 return -1;
802 }
803 }
804 process = getNextArg();
805 } else {
806 // Compatibility with old syntax: process is specified first.
807 process = cmd;
808 cmd = getNextArgRequired();
809 if ("start".equals(cmd)) {
810 start = true;
811 } else if (!"stop".equals(cmd)) {
812 throw new IllegalArgumentException("Profile command " + process + " not valid");
813 }
814 }
815
816 if (userId == UserHandle.USER_ALL) {
817 err.println("Error: Can't profile with user 'all'");
818 return -1;
819 }
820
821 ParcelFileDescriptor fd = null;
822 ProfilerInfo profilerInfo = null;
823
824 if (start) {
825 profileFile = getNextArgRequired();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700826 fd = openFileForSystem(profileFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700827 if (fd == null) {
828 return -1;
829 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700830 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800831 null, false);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700832 }
833
834 try {
835 if (wall) {
836 // XXX doesn't work -- this needs to be set before booting.
837 String props = SystemProperties.get("dalvik.vm.extra-opts");
838 if (props == null || !props.contains("-Xprofile:wallclock")) {
839 props = props + " -Xprofile:wallclock";
840 //SystemProperties.set("dalvik.vm.extra-opts", props);
841 }
842 } else if (start) {
843 //removeWallOption();
844 }
845 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
846 wall = false;
847 err.println("PROFILE FAILED on process " + process);
848 return -1;
849 }
850 } finally {
851 if (!wall) {
852 //removeWallOption();
853 }
854 }
855 return 0;
856 }
857
858 int runDumpHeap(PrintWriter pw) throws RemoteException {
859 final PrintWriter err = getErrPrintWriter();
860 boolean managed = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700861 boolean mallocInfo = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700862 int userId = UserHandle.USER_CURRENT;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700863 boolean runGc = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700864
865 String opt;
866 while ((opt=getNextOption()) != null) {
867 if (opt.equals("--user")) {
868 userId = UserHandle.parseUserArg(getNextArgRequired());
869 if (userId == UserHandle.USER_ALL) {
870 err.println("Error: Can't dump heap with user 'all'");
871 return -1;
872 }
873 } else if (opt.equals("-n")) {
874 managed = false;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700875 } else if (opt.equals("-g")) {
876 runGc = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700877 } else if (opt.equals("-m")) {
878 managed = false;
879 mallocInfo = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700880 } else {
881 err.println("Error: Unknown option: " + opt);
882 return -1;
883 }
884 }
885 String process = getNextArgRequired();
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700886 String heapFile = getNextArg();
887 if (heapFile == null) {
888 final Time t = new Time();
889 t.set(System.currentTimeMillis());
890 heapFile = "/data/local/tmp/heapdump-" + t.format("%Y%m%d-%H%M%S") + ".prof";
891 }
892 pw.println("File: " + heapFile);
893 pw.flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -0700894
895 File file = new File(heapFile);
896 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700897 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700898 if (fd == null) {
899 return -1;
900 }
901
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700902 final CountDownLatch latch = new CountDownLatch(1);
903
904 final RemoteCallback finishCallback = new RemoteCallback(new OnResultListener() {
905 @Override
906 public void onResult(Bundle result) {
907 latch.countDown();
908 }
909 }, null);
910
911 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd,
912 finishCallback)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700913 err.println("HEAP DUMP FAILED on process " + process);
914 return -1;
915 }
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700916 pw.println("Waiting for dump to finish...");
917 pw.flush();
918 try {
919 latch.await();
920 } catch (InterruptedException e) {
921 err.println("Caught InterruptedException");
922 }
923
Dianne Hackborn331084d2016-10-07 17:57:00 -0700924 return 0;
925 }
926
927 int runSetDebugApp(PrintWriter pw) throws RemoteException {
928 boolean wait = false;
929 boolean persistent = false;
930
931 String opt;
932 while ((opt=getNextOption()) != null) {
933 if (opt.equals("-w")) {
934 wait = true;
935 } else if (opt.equals("--persistent")) {
936 persistent = true;
937 } else {
938 getErrPrintWriter().println("Error: Unknown option: " + opt);
939 return -1;
940 }
941 }
942
943 String pkg = getNextArgRequired();
944 mInterface.setDebugApp(pkg, wait, persistent);
945 return 0;
946 }
947
Andreas Gampe5b495d52018-01-22 15:15:54 -0800948 int runSetAgentApp(PrintWriter pw) throws RemoteException {
949 String pkg = getNextArgRequired();
950 String agent = getNextArg();
951 mInterface.setAgentApp(pkg, agent);
952 return 0;
953 }
954
Dianne Hackborn331084d2016-10-07 17:57:00 -0700955 int runClearDebugApp(PrintWriter pw) throws RemoteException {
956 mInterface.setDebugApp(null, false, true);
957 return 0;
958 }
959
960 int runSetWatchHeap(PrintWriter pw) throws RemoteException {
961 String proc = getNextArgRequired();
962 String limit = getNextArgRequired();
963 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
964 return 0;
965 }
966
967 int runClearWatchHeap(PrintWriter pw) throws RemoteException {
968 String proc = getNextArgRequired();
969 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null);
970 return 0;
971 }
972
973 int runBugReport(PrintWriter pw) throws RemoteException {
974 String opt;
975 int bugreportType = ActivityManager.BUGREPORT_OPTION_FULL;
976 while ((opt=getNextOption()) != null) {
977 if (opt.equals("--progress")) {
978 bugreportType = ActivityManager.BUGREPORT_OPTION_INTERACTIVE;
Felipe Leme9606c3b2017-01-05 14:57:12 -0800979 } else if (opt.equals("--telephony")) {
980 bugreportType = ActivityManager.BUGREPORT_OPTION_TELEPHONY;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700981 } else {
982 getErrPrintWriter().println("Error: Unknown option: " + opt);
983 return -1;
984 }
985 }
986 mInterface.requestBugReport(bugreportType);
987 pw.println("Your lovely bug report is being created; please be patient.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800988 return 0;
989 }
990
Dianne Hackborn2e441072015-10-28 18:00:57 -0700991 int runForceStop(PrintWriter pw) throws RemoteException {
992 int userId = UserHandle.USER_ALL;
993
994 String opt;
995 while ((opt = getNextOption()) != null) {
996 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800997 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -0700998 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700999 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001000 return -1;
1001 }
1002 }
1003 mInterface.forceStopPackage(getNextArgRequired(), userId);
1004 return 0;
1005 }
1006
Christopher Tate8aa8fe12017-01-20 17:50:32 -08001007 int runCrash(PrintWriter pw) throws RemoteException {
1008 int userId = UserHandle.USER_ALL;
1009
1010 String opt;
1011 while ((opt=getNextOption()) != null) {
1012 if (opt.equals("--user")) {
1013 userId = UserHandle.parseUserArg(getNextArgRequired());
1014 } else {
1015 getErrPrintWriter().println("Error: Unknown option: " + opt);
1016 return -1;
1017 }
1018 }
1019
1020 int pid = -1;
1021 String packageName = null;
1022 final String arg = getNextArgRequired();
1023 // The argument is either a pid or a package name
1024 try {
1025 pid = Integer.parseInt(arg);
1026 } catch (NumberFormatException e) {
1027 packageName = arg;
1028 }
1029 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
1030 return 0;
1031 }
1032
Dianne Hackborn2e441072015-10-28 18:00:57 -07001033 int runKill(PrintWriter pw) throws RemoteException {
1034 int userId = UserHandle.USER_ALL;
1035
1036 String opt;
1037 while ((opt=getNextOption()) != null) {
1038 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001039 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001040 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001041 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001042 return -1;
1043 }
1044 }
1045 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
1046 return 0;
1047 }
1048
1049 int runKillAll(PrintWriter pw) throws RemoteException {
1050 mInterface.killAllBackgroundProcesses();
1051 return 0;
1052 }
1053
Dianne Hackborne07641d2016-11-09 15:07:23 -08001054 int runMakeIdle(PrintWriter pw) throws RemoteException {
1055 int userId = UserHandle.USER_ALL;
1056
1057 String opt;
1058 while ((opt = getNextOption()) != null) {
1059 if (opt.equals("--user")) {
1060 userId = UserHandle.parseUserArg(getNextArgRequired());
1061 } else {
1062 getErrPrintWriter().println("Error: Unknown option: " + opt);
1063 return -1;
1064 }
1065 }
1066 mInterface.makePackageIdle(getNextArgRequired(), userId);
1067 return 0;
1068 }
1069
Dianne Hackborn331084d2016-10-07 17:57:00 -07001070 static final class MyActivityController extends IActivityController.Stub {
1071 final IActivityManager mInterface;
1072 final PrintWriter mPw;
1073 final InputStream mInput;
1074 final String mGdbPort;
1075 final boolean mMonkey;
1076
1077 static final int STATE_NORMAL = 0;
1078 static final int STATE_CRASHED = 1;
1079 static final int STATE_EARLY_ANR = 2;
1080 static final int STATE_ANR = 3;
1081
1082 int mState;
1083
1084 static final int RESULT_DEFAULT = 0;
1085
1086 static final int RESULT_CRASH_DIALOG = 0;
1087 static final int RESULT_CRASH_KILL = 1;
1088
1089 static final int RESULT_EARLY_ANR_CONTINUE = 0;
1090 static final int RESULT_EARLY_ANR_KILL = 1;
1091
1092 static final int RESULT_ANR_DIALOG = 0;
1093 static final int RESULT_ANR_KILL = 1;
1094 static final int RESULT_ANR_WAIT = 1;
1095
1096 int mResult;
1097
1098 Process mGdbProcess;
1099 Thread mGdbThread;
1100 boolean mGotGdbPrint;
1101
1102 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
1103 String gdbPort, boolean monkey) {
1104 mInterface = iam;
1105 mPw = pw;
1106 mInput = input;
1107 mGdbPort = gdbPort;
1108 mMonkey = monkey;
1109 }
1110
1111 @Override
1112 public boolean activityResuming(String pkg) {
1113 synchronized (this) {
1114 mPw.println("** Activity resuming: " + pkg);
1115 mPw.flush();
1116 }
1117 return true;
1118 }
1119
1120 @Override
1121 public boolean activityStarting(Intent intent, String pkg) {
1122 synchronized (this) {
1123 mPw.println("** Activity starting: " + pkg);
1124 mPw.flush();
1125 }
1126 return true;
1127 }
1128
1129 @Override
1130 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
1131 long timeMillis, String stackTrace) {
1132 synchronized (this) {
1133 mPw.println("** ERROR: PROCESS CRASHED");
1134 mPw.println("processName: " + processName);
1135 mPw.println("processPid: " + pid);
1136 mPw.println("shortMsg: " + shortMsg);
1137 mPw.println("longMsg: " + longMsg);
1138 mPw.println("timeMillis: " + timeMillis);
1139 mPw.println("stack:");
1140 mPw.print(stackTrace);
1141 mPw.println("#");
1142 mPw.flush();
1143 int result = waitControllerLocked(pid, STATE_CRASHED);
1144 return result == RESULT_CRASH_KILL ? false : true;
1145 }
1146 }
1147
1148 @Override
1149 public int appEarlyNotResponding(String processName, int pid, String annotation) {
1150 synchronized (this) {
1151 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING");
1152 mPw.println("processName: " + processName);
1153 mPw.println("processPid: " + pid);
1154 mPw.println("annotation: " + annotation);
1155 mPw.flush();
1156 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
1157 if (result == RESULT_EARLY_ANR_KILL) return -1;
1158 return 0;
1159 }
1160 }
1161
1162 @Override
1163 public int appNotResponding(String processName, int pid, String processStats) {
1164 synchronized (this) {
1165 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1166 mPw.println("processName: " + processName);
1167 mPw.println("processPid: " + pid);
1168 mPw.println("processStats:");
1169 mPw.print(processStats);
1170 mPw.println("#");
1171 mPw.flush();
1172 int result = waitControllerLocked(pid, STATE_ANR);
1173 if (result == RESULT_ANR_KILL) return -1;
1174 if (result == RESULT_ANR_WAIT) return 1;
1175 return 0;
1176 }
1177 }
1178
1179 @Override
1180 public int systemNotResponding(String message) {
1181 synchronized (this) {
1182 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1183 mPw.println("message: " + message);
1184 mPw.println("#");
1185 mPw.println("Allowing system to die.");
1186 mPw.flush();
1187 return -1;
1188 }
1189 }
1190
1191 void killGdbLocked() {
1192 mGotGdbPrint = false;
1193 if (mGdbProcess != null) {
1194 mPw.println("Stopping gdbserver");
1195 mPw.flush();
1196 mGdbProcess.destroy();
1197 mGdbProcess = null;
1198 }
1199 if (mGdbThread != null) {
1200 mGdbThread.interrupt();
1201 mGdbThread = null;
1202 }
1203 }
1204
1205 int waitControllerLocked(int pid, int state) {
1206 if (mGdbPort != null) {
1207 killGdbLocked();
1208
1209 try {
1210 mPw.println("Starting gdbserver on port " + mGdbPort);
1211 mPw.println("Do the following:");
1212 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
1213 mPw.println(" gdbclient app_process :" + mGdbPort);
1214 mPw.flush();
1215
1216 mGdbProcess = Runtime.getRuntime().exec(new String[] {
1217 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
1218 });
1219 final InputStreamReader converter = new InputStreamReader(
1220 mGdbProcess.getInputStream());
1221 mGdbThread = new Thread() {
1222 @Override
1223 public void run() {
1224 BufferedReader in = new BufferedReader(converter);
1225 String line;
1226 int count = 0;
1227 while (true) {
1228 synchronized (MyActivityController.this) {
1229 if (mGdbThread == null) {
1230 return;
1231 }
1232 if (count == 2) {
1233 mGotGdbPrint = true;
1234 MyActivityController.this.notifyAll();
1235 }
1236 }
1237 try {
1238 line = in.readLine();
1239 if (line == null) {
1240 return;
1241 }
1242 mPw.println("GDB: " + line);
1243 mPw.flush();
1244 count++;
1245 } catch (IOException e) {
1246 return;
1247 }
1248 }
1249 }
1250 };
1251 mGdbThread.start();
1252
1253 // Stupid waiting for .5s. Doesn't matter if we end early.
1254 try {
1255 this.wait(500);
1256 } catch (InterruptedException e) {
1257 }
1258
1259 } catch (IOException e) {
1260 mPw.println("Failure starting gdbserver: " + e);
1261 mPw.flush();
1262 killGdbLocked();
1263 }
1264 }
1265 mState = state;
1266 mPw.println("");
1267 printMessageForState();
1268 mPw.flush();
1269
1270 while (mState != STATE_NORMAL) {
1271 try {
1272 wait();
1273 } catch (InterruptedException e) {
1274 }
1275 }
1276
1277 killGdbLocked();
1278
1279 return mResult;
1280 }
1281
1282 void resumeController(int result) {
1283 synchronized (this) {
1284 mState = STATE_NORMAL;
1285 mResult = result;
1286 notifyAll();
1287 }
1288 }
1289
1290 void printMessageForState() {
1291 switch (mState) {
1292 case STATE_NORMAL:
1293 mPw.println("Monitoring activity manager... available commands:");
1294 break;
1295 case STATE_CRASHED:
1296 mPw.println("Waiting after crash... available commands:");
1297 mPw.println("(c)ontinue: show crash dialog");
1298 mPw.println("(k)ill: immediately kill app");
1299 break;
1300 case STATE_EARLY_ANR:
1301 mPw.println("Waiting after early ANR... available commands:");
1302 mPw.println("(c)ontinue: standard ANR processing");
1303 mPw.println("(k)ill: immediately kill app");
1304 break;
1305 case STATE_ANR:
1306 mPw.println("Waiting after ANR... available commands:");
1307 mPw.println("(c)ontinue: show ANR dialog");
1308 mPw.println("(k)ill: immediately kill app");
1309 mPw.println("(w)ait: wait some more");
1310 break;
1311 }
1312 mPw.println("(q)uit: finish monitoring");
1313 }
1314
1315 void run() throws RemoteException {
1316 try {
1317 printMessageForState();
1318 mPw.flush();
1319
1320 mInterface.setActivityController(this, mMonkey);
1321 mState = STATE_NORMAL;
1322
1323 InputStreamReader converter = new InputStreamReader(mInput);
1324 BufferedReader in = new BufferedReader(converter);
1325 String line;
1326
1327 while ((line = in.readLine()) != null) {
1328 boolean addNewline = true;
1329 if (line.length() <= 0) {
1330 addNewline = false;
1331 } else if ("q".equals(line) || "quit".equals(line)) {
1332 resumeController(RESULT_DEFAULT);
1333 break;
1334 } else if (mState == STATE_CRASHED) {
1335 if ("c".equals(line) || "continue".equals(line)) {
1336 resumeController(RESULT_CRASH_DIALOG);
1337 } else if ("k".equals(line) || "kill".equals(line)) {
1338 resumeController(RESULT_CRASH_KILL);
1339 } else {
1340 mPw.println("Invalid command: " + line);
1341 }
1342 } else if (mState == STATE_ANR) {
1343 if ("c".equals(line) || "continue".equals(line)) {
1344 resumeController(RESULT_ANR_DIALOG);
1345 } else if ("k".equals(line) || "kill".equals(line)) {
1346 resumeController(RESULT_ANR_KILL);
1347 } else if ("w".equals(line) || "wait".equals(line)) {
1348 resumeController(RESULT_ANR_WAIT);
1349 } else {
1350 mPw.println("Invalid command: " + line);
1351 }
1352 } else if (mState == STATE_EARLY_ANR) {
1353 if ("c".equals(line) || "continue".equals(line)) {
1354 resumeController(RESULT_EARLY_ANR_CONTINUE);
1355 } else if ("k".equals(line) || "kill".equals(line)) {
1356 resumeController(RESULT_EARLY_ANR_KILL);
1357 } else {
1358 mPw.println("Invalid command: " + line);
1359 }
1360 } else {
1361 mPw.println("Invalid command: " + line);
1362 }
1363
1364 synchronized (this) {
1365 if (addNewline) {
1366 mPw.println("");
1367 }
1368 printMessageForState();
1369 mPw.flush();
1370 }
1371 }
1372
1373 } catch (IOException e) {
1374 e.printStackTrace(mPw);
1375 mPw.flush();
1376 } finally {
1377 mInterface.setActivityController(null, mMonkey);
1378 }
1379 }
1380 }
1381
1382 int runMonitor(PrintWriter pw) throws RemoteException {
1383 String opt;
1384 String gdbPort = null;
1385 boolean monkey = false;
1386 while ((opt=getNextOption()) != null) {
1387 if (opt.equals("--gdb")) {
1388 gdbPort = getNextArgRequired();
1389 } else if (opt.equals("-m")) {
1390 monkey = true;
1391 } else {
1392 getErrPrintWriter().println("Error: Unknown option: " + opt);
1393 return -1;
1394 }
1395 }
1396
1397 MyActivityController controller = new MyActivityController(mInterface, pw,
1398 getRawInputStream(), gdbPort, monkey);
1399 controller.run();
1400 return 0;
1401 }
1402
Dianne Hackborne51505a2017-08-07 17:13:52 -07001403 static final class MyUidObserver extends IUidObserver.Stub
1404 implements ActivityManagerService.OomAdjObserver {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001405 final IActivityManager mInterface;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001406 final ActivityManagerService mInternal;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001407 final PrintWriter mPw;
1408 final InputStream mInput;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001409 final int mUid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001410
1411 static final int STATE_NORMAL = 0;
1412
1413 int mState;
1414
Dianne Hackborne51505a2017-08-07 17:13:52 -07001415 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
1416 mInterface = service;
1417 mInternal = service;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001418 mPw = pw;
1419 mInput = input;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001420 mUid = uid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001421 }
1422
1423 @Override
1424 public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException {
1425 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001426 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1427 try {
1428 mPw.print(uid);
1429 mPw.print(" procstate ");
1430 mPw.print(ProcessList.makeProcStateString(procState));
1431 mPw.print(" seq ");
1432 mPw.println(procStateSeq);
1433 mPw.flush();
1434 } finally {
1435 StrictMode.setThreadPolicy(oldPolicy);
1436 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001437 }
1438 }
1439
1440 @Override
1441 public void onUidGone(int uid, boolean disabled) throws RemoteException {
1442 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001443 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1444 try {
1445 mPw.print(uid);
1446 mPw.print(" gone");
1447 if (disabled) {
1448 mPw.print(" disabled");
1449 }
1450 mPw.println();
1451 mPw.flush();
1452 } finally {
1453 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001454 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001455 }
1456 }
1457
1458 @Override
1459 public void onUidActive(int uid) throws RemoteException {
1460 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001461 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1462 try {
1463 mPw.print(uid);
1464 mPw.println(" active");
1465 mPw.flush();
1466 } finally {
1467 StrictMode.setThreadPolicy(oldPolicy);
1468 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001469 }
1470 }
1471
1472 @Override
1473 public void onUidIdle(int uid, boolean disabled) throws RemoteException {
1474 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001475 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1476 try {
1477 mPw.print(uid);
1478 mPw.print(" idle");
1479 if (disabled) {
1480 mPw.print(" disabled");
1481 }
1482 mPw.println();
1483 mPw.flush();
1484 } finally {
1485 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001486 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001487 }
1488 }
1489
1490 @Override
1491 public void onUidCachedChanged(int uid, boolean cached) throws RemoteException {
1492 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001493 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1494 try {
1495 mPw.print(uid);
1496 mPw.println(cached ? " cached" : " uncached");
1497 mPw.flush();
1498 } finally {
1499 StrictMode.setThreadPolicy(oldPolicy);
1500 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001501 }
1502 }
1503
Dianne Hackborne51505a2017-08-07 17:13:52 -07001504 @Override
1505 public void onOomAdjMessage(String msg) {
1506 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001507 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1508 try {
1509 mPw.print("# ");
1510 mPw.println(msg);
1511 mPw.flush();
1512 } finally {
1513 StrictMode.setThreadPolicy(oldPolicy);
1514 }
Dianne Hackborne51505a2017-08-07 17:13:52 -07001515 }
1516 }
1517
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001518 void printMessageForState() {
1519 switch (mState) {
1520 case STATE_NORMAL:
1521 mPw.println("Watching uid states... available commands:");
1522 break;
1523 }
1524 mPw.println("(q)uit: finish watching");
1525 }
1526
1527 void run() throws RemoteException {
1528 try {
1529 printMessageForState();
1530 mPw.flush();
1531
1532 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE
1533 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
1534 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
1535 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackborne51505a2017-08-07 17:13:52 -07001536 if (mUid >= 0) {
1537 mInternal.setOomAdjObserver(mUid, this);
1538 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001539 mState = STATE_NORMAL;
1540
1541 InputStreamReader converter = new InputStreamReader(mInput);
1542 BufferedReader in = new BufferedReader(converter);
1543 String line;
1544
1545 while ((line = in.readLine()) != null) {
1546 boolean addNewline = true;
1547 if (line.length() <= 0) {
1548 addNewline = false;
1549 } else if ("q".equals(line) || "quit".equals(line)) {
1550 break;
1551 } else {
1552 mPw.println("Invalid command: " + line);
1553 }
1554
1555 synchronized (this) {
1556 if (addNewline) {
1557 mPw.println("");
1558 }
1559 printMessageForState();
1560 mPw.flush();
1561 }
1562 }
1563
1564 } catch (IOException e) {
1565 e.printStackTrace(mPw);
1566 mPw.flush();
1567 } finally {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001568 if (mUid >= 0) {
1569 mInternal.clearOomAdjObserver();
1570 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001571 mInterface.unregisterUidObserver(this);
1572 }
1573 }
1574 }
1575
1576 int runWatchUids(PrintWriter pw) throws RemoteException {
1577 String opt;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001578 int uid = -1;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001579 while ((opt=getNextOption()) != null) {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001580 if (opt.equals("--oom")) {
1581 uid = Integer.parseInt(getNextArgRequired());
1582 } else {
1583 getErrPrintWriter().println("Error: Unknown option: " + opt);
1584 return -1;
1585
1586 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001587 }
1588
Dianne Hackborne51505a2017-08-07 17:13:52 -07001589 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001590 controller.run();
1591 return 0;
1592 }
1593
Dianne Hackborn331084d2016-10-07 17:57:00 -07001594 int runHang(PrintWriter pw) throws RemoteException {
1595 String opt;
1596 boolean allowRestart = false;
1597 while ((opt=getNextOption()) != null) {
1598 if (opt.equals("--allow-restart")) {
1599 allowRestart = true;
1600 } else {
1601 getErrPrintWriter().println("Error: Unknown option: " + opt);
1602 return -1;
1603 }
1604 }
1605
1606 pw.println("Hanging the system...");
1607 pw.flush();
1608 mInterface.hang(new Binder(), allowRestart);
1609 return 0;
1610 }
1611
1612 int runRestart(PrintWriter pw) throws RemoteException {
1613 String opt;
1614 while ((opt=getNextOption()) != null) {
1615 getErrPrintWriter().println("Error: Unknown option: " + opt);
1616 return -1;
1617 }
1618
1619 pw.println("Restart the system...");
1620 pw.flush();
1621 mInterface.restart();
1622 return 0;
1623 }
1624
1625 int runIdleMaintenance(PrintWriter pw) throws RemoteException {
1626 String opt;
1627 while ((opt=getNextOption()) != null) {
1628 getErrPrintWriter().println("Error: Unknown option: " + opt);
1629 return -1;
1630 }
1631
1632 pw.println("Performing idle maintenance...");
1633 mInterface.sendIdleJobTrigger();
1634 return 0;
1635 }
1636
1637 int runScreenCompat(PrintWriter pw) throws RemoteException {
1638 String mode = getNextArgRequired();
1639 boolean enabled;
1640 if ("on".equals(mode)) {
1641 enabled = true;
1642 } else if ("off".equals(mode)) {
1643 enabled = false;
1644 } else {
1645 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode);
1646 return -1;
1647 }
1648
1649 String packageName = getNextArgRequired();
1650 do {
1651 try {
1652 mInterface.setPackageScreenCompatMode(packageName, enabled
1653 ? ActivityManager.COMPAT_MODE_ENABLED
1654 : ActivityManager.COMPAT_MODE_DISABLED);
1655 } catch (RemoteException e) {
1656 }
1657 packageName = getNextArg();
1658 } while (packageName != null);
1659 return 0;
1660 }
1661
1662 int runPackageImportance(PrintWriter pw) throws RemoteException {
1663 String packageName = getNextArgRequired();
1664 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell");
1665 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
1666 return 0;
1667 }
1668
1669 int runToUri(PrintWriter pw, int flags) throws RemoteException {
1670 Intent intent;
1671 try {
1672 intent = makeIntent(UserHandle.USER_CURRENT);
1673 } catch (URISyntaxException e) {
1674 throw new RuntimeException(e.getMessage(), e);
1675 }
1676 pw.println(intent.toUri(flags));
1677 return 0;
1678 }
1679
1680 int runSwitchUser(PrintWriter pw) throws RemoteException {
Alex Chau5c0df232018-02-22 15:57:17 +08001681 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
1682 if (!userManager.canSwitchUsers()) {
1683 getErrPrintWriter().println("Error: disallowed switching user");
1684 return -1;
1685 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001686 String user = getNextArgRequired();
1687 mInterface.switchUser(Integer.parseInt(user));
1688 return 0;
1689 }
1690
1691 int runGetCurrentUser(PrintWriter pw) throws RemoteException {
1692 UserInfo currentUser = Preconditions.checkNotNull(mInterface.getCurrentUser(),
1693 "Current user not set");
1694 pw.println(currentUser.id);
1695 return 0;
1696 }
1697
1698 int runStartUser(PrintWriter pw) throws RemoteException {
1699 String user = getNextArgRequired();
1700 boolean success = mInterface.startUserInBackground(Integer.parseInt(user));
1701 if (success) {
1702 pw.println("Success: user started");
1703 } else {
1704 getErrPrintWriter().println("Error: could not start user");
1705 }
1706 return 0;
1707 }
1708
1709 private static byte[] argToBytes(String arg) {
1710 if (arg.equals("!")) {
1711 return null;
1712 } else {
1713 return HexDump.hexStringToByteArray(arg);
1714 }
1715 }
1716
1717 int runUnlockUser(PrintWriter pw) throws RemoteException {
1718 int userId = Integer.parseInt(getNextArgRequired());
1719 byte[] token = argToBytes(getNextArgRequired());
1720 byte[] secret = argToBytes(getNextArgRequired());
1721 boolean success = mInterface.unlockUser(userId, token, secret, null);
1722 if (success) {
1723 pw.println("Success: user unlocked");
1724 } else {
1725 getErrPrintWriter().println("Error: could not unlock user");
1726 }
1727 return 0;
1728 }
1729
1730 static final class StopUserCallback extends IStopUserCallback.Stub {
1731 private boolean mFinished = false;
1732
1733 public synchronized void waitForFinish() {
1734 try {
1735 while (!mFinished) wait();
1736 } catch (InterruptedException e) {
1737 throw new IllegalStateException(e);
1738 }
1739 }
1740
1741 @Override
1742 public synchronized void userStopped(int userId) {
1743 mFinished = true;
1744 notifyAll();
1745 }
1746
1747 @Override
1748 public synchronized void userStopAborted(int userId) {
1749 mFinished = true;
1750 notifyAll();
1751 }
1752 }
1753
1754 int runStopUser(PrintWriter pw) throws RemoteException {
1755 boolean wait = false;
1756 boolean force = false;
1757 String opt;
1758 while ((opt = getNextOption()) != null) {
1759 if ("-w".equals(opt)) {
1760 wait = true;
1761 } else if ("-f".equals(opt)) {
1762 force = true;
1763 } else {
1764 getErrPrintWriter().println("Error: unknown option: " + opt);
1765 return -1;
1766 }
1767 }
1768 int user = Integer.parseInt(getNextArgRequired());
1769 StopUserCallback callback = wait ? new StopUserCallback() : null;
1770
1771 int res = mInterface.stopUser(user, force, callback);
1772 if (res != ActivityManager.USER_OP_SUCCESS) {
1773 String txt = "";
1774 switch (res) {
1775 case ActivityManager.USER_OP_IS_CURRENT:
1776 txt = " (Can't stop current user)";
1777 break;
1778 case ActivityManager.USER_OP_UNKNOWN_USER:
1779 txt = " (Unknown user " + user + ")";
1780 break;
1781 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
1782 txt = " (System user cannot be stopped)";
1783 break;
1784 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP:
1785 txt = " (Can't stop user " + user
1786 + " - one of its related users can't be stopped)";
1787 break;
1788 }
1789 getErrPrintWriter().println("Switch failed: " + res + txt);
1790 return -1;
1791 } else if (callback != null) {
1792 callback.waitForFinish();
1793 }
1794 return 0;
1795 }
1796
1797 int runIsUserStopped(PrintWriter pw) {
1798 int userId = UserHandle.parseUserArg(getNextArgRequired());
1799 boolean stopped = mInternal.isUserStopped(userId);
1800 pw.println(stopped);
1801 return 0;
1802 }
1803
1804 int runGetStartedUserState(PrintWriter pw) throws RemoteException {
1805 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1806 "runGetStartedUserState()");
1807 final int userId = Integer.parseInt(getNextArgRequired());
1808 try {
1809 pw.println(mInternal.getStartedUserState(userId));
1810 } catch (NullPointerException e) {
1811 pw.println("User is not started: " + userId);
1812 }
Dianne Hackborn2e441072015-10-28 18:00:57 -07001813 return 0;
1814 }
1815
1816 int runTrackAssociations(PrintWriter pw) {
1817 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1818 "registerUidObserver()");
1819 synchronized (mInternal) {
1820 if (!mInternal.mTrackingAssociations) {
1821 mInternal.mTrackingAssociations = true;
1822 pw.println("Association tracking started.");
1823 } else {
1824 pw.println("Association tracking already enabled.");
1825 }
1826 }
1827 return 0;
1828 }
1829
1830 int runUntrackAssociations(PrintWriter pw) {
1831 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1832 "registerUidObserver()");
1833 synchronized (mInternal) {
1834 if (mInternal.mTrackingAssociations) {
1835 mInternal.mTrackingAssociations = false;
1836 mInternal.mAssociations.clear();
1837 pw.println("Association tracking stopped.");
1838 } else {
1839 pw.println("Association tracking not running.");
1840 }
1841 }
1842 return 0;
1843 }
1844
Felipe Leme2f1b2272016-03-25 16:15:02 -07001845 int getUidState(PrintWriter pw) throws RemoteException {
1846 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1847 "getUidState()");
1848 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
1849 pw.print(state);
1850 pw.print(" (");
1851 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
1852 pw.println(")");
1853 return 0;
1854 }
1855
Dianne Hackborn331084d2016-10-07 17:57:00 -07001856 private List<Configuration> getRecentConfigurations(int days) {
1857 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1858 Context.USAGE_STATS_SERVICE));
1859 final long now = System.currentTimeMillis();
1860 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
Sudheer Shanka28537b62016-09-07 11:12:31 -07001861 try {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001862 @SuppressWarnings("unchecked")
1863 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
1864 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
1865 if (configStatsSlice == null) {
1866 return Collections.emptyList();
1867 }
1868
1869 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
1870 final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
1871 final int configStatsListSize = configStatsList.size();
1872 for (int i = 0; i < configStatsListSize; i++) {
1873 final ConfigurationStats stats = configStatsList.get(i);
1874 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
1875 if (indexOfKey < 0) {
1876 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
1877 } else {
1878 recentConfigs.setValueAt(indexOfKey,
1879 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
1880 }
1881 }
1882
1883 final Comparator<Configuration> comparator = new Comparator<Configuration>() {
1884 @Override
1885 public int compare(Configuration a, Configuration b) {
1886 return recentConfigs.get(b).compareTo(recentConfigs.get(a));
1887 }
1888 };
1889
1890 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
1891 configs.addAll(recentConfigs.keySet());
1892 Collections.sort(configs, comparator);
1893 return configs;
1894
1895 } catch (RemoteException e) {
1896 return Collections.emptyList();
Sudheer Shanka28537b62016-09-07 11:12:31 -07001897 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001898 }
1899
Dianne Hackborn337e01a2018-02-27 17:16:37 -08001900 /**
1901 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
1902 * and EGLSurface and querying extensions.
1903 *
1904 * @param egl An EGL API object
1905 * @param display An EGLDisplay to create a context and surface with
1906 * @param config The EGLConfig to get the extensions for
1907 * @param surfaceSize eglCreatePbufferSurface generic parameters
1908 * @param contextAttribs eglCreateContext generic parameters
1909 * @param glExtensions A Set<String> to add GL extensions to
1910 */
1911 private static void addExtensionsForConfig(
1912 EGL10 egl,
1913 EGLDisplay display,
1914 EGLConfig config,
1915 int[] surfaceSize,
1916 int[] contextAttribs,
1917 Set<String> glExtensions) {
1918 // Create a context.
1919 EGLContext context =
1920 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
1921 // No-op if we can't create a context.
1922 if (context == EGL10.EGL_NO_CONTEXT) {
1923 return;
1924 }
1925
1926 // Create a surface.
1927 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
1928 if (surface == EGL10.EGL_NO_SURFACE) {
1929 egl.eglDestroyContext(display, context);
1930 return;
1931 }
1932
1933 // Update the current surface and context.
1934 egl.eglMakeCurrent(display, surface, surface, context);
1935
1936 // Get the list of extensions.
1937 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
1938 if (!TextUtils.isEmpty(extensionList)) {
1939 // The list of extensions comes from the driver separated by spaces.
1940 // Split them apart and add them into a Set for deduping purposes.
1941 for (String extension : extensionList.split(" ")) {
1942 glExtensions.add(extension);
1943 }
1944 }
1945
1946 // Tear down the context and surface for this config.
1947 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
1948 egl.eglDestroySurface(display, surface);
1949 egl.eglDestroyContext(display, context);
1950 }
1951
1952
1953 Set<String> getGlExtensionsFromDriver() {
1954 Set<String> glExtensions = new HashSet<>();
1955
1956 // Get the EGL implementation.
1957 EGL10 egl = (EGL10) EGLContext.getEGL();
1958 if (egl == null) {
1959 getErrPrintWriter().println("Warning: couldn't get EGL");
1960 return glExtensions;
1961 }
1962
1963 // Get the default display and initialize it.
1964 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
1965 int[] version = new int[2];
1966 egl.eglInitialize(display, version);
1967
1968 // Call getConfigs() in order to find out how many there are.
1969 int[] numConfigs = new int[1];
1970 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
1971 getErrPrintWriter().println("Warning: couldn't get EGL config count");
1972 return glExtensions;
1973 }
1974
1975 // Allocate space for all configs and ask again.
1976 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
1977 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
1978 getErrPrintWriter().println("Warning: couldn't get EGL configs");
1979 return glExtensions;
1980 }
1981
1982 // Allocate surface size parameters outside of the main loop to cut down
1983 // on GC thrashing. 1x1 is enough since we are only using it to get at
1984 // the list of extensions.
1985 int[] surfaceSize =
1986 new int[] {
1987 EGL10.EGL_WIDTH, 1,
1988 EGL10.EGL_HEIGHT, 1,
1989 EGL10.EGL_NONE
1990 };
1991
1992 // For when we need to create a GLES2.0 context.
1993 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
1994 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
1995
1996 // For getting return values from eglGetConfigAttrib
1997 int[] attrib = new int[1];
1998
1999 for (int i = 0; i < numConfigs[0]; i++) {
2000 // Get caveat for this config in order to skip slow (i.e. software) configs.
2001 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
2002 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
2003 continue;
2004 }
2005
2006 // If the config does not support pbuffers we cannot do an eglMakeCurrent
2007 // on it in addExtensionsForConfig(), so skip it here. Attempting to make
2008 // it current with a pbuffer will result in an EGL_BAD_MATCH error
2009 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
2010 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
2011 continue;
2012 }
2013
2014 final int EGL_OPENGL_ES_BIT = 0x0001;
2015 final int EGL_OPENGL_ES2_BIT = 0x0004;
2016 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
2017 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
2018 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
2019 }
2020 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
2021 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
2022 }
2023 }
2024
2025 // Release all EGL resources.
2026 egl.eglTerminate(display);
2027
2028 return glExtensions;
2029 }
2030
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002031 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
Jeff Change9467b22018-09-28 11:40:38 +08002032 PrintWriter pw, Configuration config, DisplayMetrics displayMetrics) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002033 long token = -1;
2034 if (protoOutputStream != null) {
2035 token = protoOutputStream.start(fieldId);
Jeff Change9467b22018-09-28 11:40:38 +08002036 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX,
2037 displayMetrics.widthPixels);
2038 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX,
2039 displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002040 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI,
2041 DisplayMetrics.DENSITY_DEVICE_STABLE);
2042 }
2043 if (pw != null) {
Jeff Change9467b22018-09-28 11:40:38 +08002044 pw.print("stable-width-px: "); pw.println(displayMetrics.widthPixels);
2045 pw.print("stable-height-px: "); pw.println(displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002046 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE);
2047 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002048
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002049 MemInfoReader memreader = new MemInfoReader();
2050 memreader.readMemInfo();
2051 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class);
2052 if (protoOutputStream != null) {
2053 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize());
2054 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM,
2055 ActivityManager.isLowRamDeviceStatic());
2056 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES,
2057 Runtime.getRuntime().availableProcessors());
2058 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK,
2059 kgm.isDeviceSecure());
2060 }
2061 if (pw != null) {
2062 pw.print("total-ram: "); pw.println(memreader.getTotalSize());
2063 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic());
2064 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors());
2065 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
2066 }
2067
Yunfan Chen75157d72018-07-27 14:47:21 +09002068 ConfigurationInfo configInfo = null;
2069 try {
2070 configInfo = mTaskInterface.getDeviceConfigurationInfo();
2071 } catch (RemoteException e) {
2072 throw e.rethrowFromSystemServer();
2073 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002074 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
2075 if (protoOutputStream != null) {
2076 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
2077 configInfo.reqGlEsVersion);
2078 }
2079 if (pw != null) {
2080 pw.print("opengl-version: 0x");
2081 pw.println(Integer.toHexString(configInfo.reqGlEsVersion));
2082 }
2083 }
2084
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002085 Set<String> glExtensionsSet = getGlExtensionsFromDriver();
2086 String[] glExtensions = new String[glExtensionsSet.size()];
2087 glExtensions = glExtensionsSet.toArray(glExtensions);
2088 Arrays.sort(glExtensions);
2089 for (int i = 0; i < glExtensions.length; i++) {
2090 if (protoOutputStream != null) {
2091 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
2092 glExtensions[i]);
2093 }
2094 if (pw != null) {
2095 pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
2096 }
2097
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002098 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002099
2100 PackageManager pm = mInternal.mContext.getPackageManager();
2101 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002102 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002103 for (int i = 0; i < slibs.size(); i++) {
2104 if (protoOutputStream != null) {
2105 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
2106 slibs.get(i).getName());
2107 }
2108 if (pw != null) {
2109 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName());
2110 }
2111 }
2112
2113 FeatureInfo[] features = pm.getSystemAvailableFeatures();
weijuncheng12030002018-10-30 14:07:53 +08002114 Arrays.sort(features, (o1, o2) -> {
2115 if (o1.name == o2.name) return 0;
2116 if (o1.name == null) return -1;
2117 if (o2.name == null) return 1;
2118 return o1.name.compareTo(o2.name);
2119 });
2120
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002121 for (int i = 0; i < features.length; i++) {
2122 if (features[i].name != null) {
2123 if (protoOutputStream != null) {
2124 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name);
2125 }
2126 if (pw != null) {
2127 pw.print("features: "); pw.println(features[i].name);
2128 }
2129 }
2130 }
2131
2132 if (protoOutputStream != null) {
2133 protoOutputStream.end(token);
2134 }
2135 }
2136
2137 int runGetConfig(PrintWriter pw) throws RemoteException {
2138 int days = -1;
Jeff Change9467b22018-09-28 11:40:38 +08002139 int displayId = Display.DEFAULT_DISPLAY;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002140 boolean asProto = false;
2141 boolean inclDevice = false;
2142
2143 String opt;
Jeff Change9467b22018-09-28 11:40:38 +08002144 while ((opt = getNextOption()) != null) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002145 if (opt.equals("--days")) {
2146 days = Integer.parseInt(getNextArgRequired());
2147 if (days <= 0) {
2148 throw new IllegalArgumentException("--days must be a positive integer");
2149 }
2150 } else if (opt.equals("--proto")) {
2151 asProto = true;
2152 } else if (opt.equals("--device")) {
2153 inclDevice = true;
Jeff Change9467b22018-09-28 11:40:38 +08002154 } else if (opt.equals("--display")) {
2155 displayId = Integer.parseInt(getNextArgRequired());
2156 if (displayId < 0) {
2157 throw new IllegalArgumentException("--display must be a non-negative integer");
2158 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002159 } else {
2160 getErrPrintWriter().println("Error: Unknown option: " + opt);
2161 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -07002162 }
2163 }
2164
2165 Configuration config = mInterface.getConfiguration();
2166 if (config == null) {
2167 getErrPrintWriter().println("Activity manager has no configuration");
2168 return -1;
2169 }
2170
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002171 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class);
Jeff Change9467b22018-09-28 11:40:38 +08002172 Display display = dm.getDisplay(displayId);
2173
2174 if (display == null) {
2175 getErrPrintWriter().println("Error: Display does not exist: " + displayId);
2176 return -1;
2177 }
2178
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002179 DisplayMetrics metrics = new DisplayMetrics();
2180 display.getMetrics(metrics);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002181
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002182 if (asProto) {
2183 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor());
2184 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics);
2185 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002186 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002187 }
2188 proto.flush();
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002189 } else {
2190 pw.println("config: " + Configuration.resourceQualifierString(config, metrics));
2191 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
2192 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002193 writeDeviceConfig(null, -1, pw, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002194 }
2195
2196 if (days >= 0) {
2197 final List<Configuration> recentConfigs = getRecentConfigurations(days);
2198 final int recentConfigSize = recentConfigs.size();
2199 if (recentConfigSize > 0) {
2200 pw.println("recentConfigs:");
2201 for (int i = 0; i < recentConfigSize; i++) {
2202 pw.println(" config: " + Configuration.resourceQualifierString(
2203 recentConfigs.get(i)));
2204 }
2205 }
2206 }
2207
Dianne Hackborn331084d2016-10-07 17:57:00 -07002208 }
2209 return 0;
2210 }
2211
2212 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
2213 boolean suppress = Boolean.valueOf(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002214 mTaskInterface.suppressResizeConfigChanges(suppress);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002215 return 0;
2216 }
2217
2218 int runSetInactive(PrintWriter pw) throws RemoteException {
2219 int userId = UserHandle.USER_CURRENT;
2220
2221 String opt;
2222 while ((opt=getNextOption()) != null) {
2223 if (opt.equals("--user")) {
2224 userId = UserHandle.parseUserArg(getNextArgRequired());
2225 } else {
2226 getErrPrintWriter().println("Error: Unknown option: " + opt);
2227 return -1;
2228 }
2229 }
2230 String packageName = getNextArgRequired();
2231 String value = getNextArgRequired();
2232
2233 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2234 Context.USAGE_STATS_SERVICE));
2235 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId);
2236 return 0;
2237 }
2238
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002239 private int bucketNameToBucketValue(String name) {
2240 String lower = name.toLowerCase();
2241 if (lower.startsWith("ac")) {
2242 return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
2243 } else if (lower.startsWith("wo")) {
2244 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
2245 } else if (lower.startsWith("fr")) {
2246 return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
2247 } else if (lower.startsWith("ra")) {
2248 return UsageStatsManager.STANDBY_BUCKET_RARE;
2249 } else if (lower.startsWith("ne")) {
2250 return UsageStatsManager.STANDBY_BUCKET_NEVER;
2251 } else {
2252 try {
2253 int bucket = Integer.parseInt(lower);
2254 return bucket;
2255 } catch (NumberFormatException nfe) {
2256 getErrPrintWriter().println("Error: Unknown bucket: " + name);
2257 }
2258 }
2259 return -1;
2260 }
2261
Amith Yamasani17fffee2017-09-29 13:17:43 -07002262 int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
2263 int userId = UserHandle.USER_CURRENT;
2264
2265 String opt;
2266 while ((opt=getNextOption()) != null) {
2267 if (opt.equals("--user")) {
2268 userId = UserHandle.parseUserArg(getNextArgRequired());
2269 } else {
2270 getErrPrintWriter().println("Error: Unknown option: " + opt);
2271 return -1;
2272 }
2273 }
2274 String packageName = getNextArgRequired();
2275 String value = getNextArgRequired();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002276 int bucket = bucketNameToBucketValue(value);
2277 if (bucket < 0) return -1;
Amith Yamasanie8789312017-12-10 14:34:26 -08002278 boolean multiple = peekNextArg() != null;
2279
Amith Yamasani17fffee2017-09-29 13:17:43 -07002280
2281 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2282 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002283 if (!multiple) {
2284 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
2285 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002286 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
2287 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002288 while ((packageName = getNextArg()) != null) {
2289 value = getNextArgRequired();
2290 bucket = bucketNameToBucketValue(value);
2291 if (bucket < 0) continue;
Suprabh Shukla868bde22018-02-20 20:59:52 -08002292 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002293 }
Suprabh Shukla868bde22018-02-20 20:59:52 -08002294 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
2295 usm.setAppStandbyBuckets(slice, userId);
Amith Yamasanie8789312017-12-10 14:34:26 -08002296 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002297 return 0;
2298 }
2299
2300 int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
2301 int userId = UserHandle.USER_CURRENT;
2302
2303 String opt;
2304 while ((opt=getNextOption()) != null) {
2305 if (opt.equals("--user")) {
2306 userId = UserHandle.parseUserArg(getNextArgRequired());
2307 } else {
2308 getErrPrintWriter().println("Error: Unknown option: " + opt);
2309 return -1;
2310 }
2311 }
Amith Yamasanie8789312017-12-10 14:34:26 -08002312 String packageName = getNextArg();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002313
2314 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2315 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002316 if (packageName != null) {
2317 int bucket = usm.getAppStandbyBucket(packageName, null, userId);
2318 pw.println(bucket);
2319 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002320 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -08002321 SHELL_PACKAGE_NAME, userId);
Suprabh Shukla868bde22018-02-20 20:59:52 -08002322 for (AppStandbyInfo bucketInfo : buckets.getList()) {
2323 pw.print(bucketInfo.mPackageName); pw.print(": ");
2324 pw.println(bucketInfo.mStandbyBucket);
Amith Yamasanie8789312017-12-10 14:34:26 -08002325 }
2326 }
Amith Yamasani17fffee2017-09-29 13:17:43 -07002327 return 0;
2328 }
2329
Dianne Hackborn331084d2016-10-07 17:57:00 -07002330 int runGetInactive(PrintWriter pw) throws RemoteException {
2331 int userId = UserHandle.USER_CURRENT;
2332
2333 String opt;
2334 while ((opt=getNextOption()) != null) {
2335 if (opt.equals("--user")) {
2336 userId = UserHandle.parseUserArg(getNextArgRequired());
2337 } else {
2338 getErrPrintWriter().println("Error: Unknown option: " + opt);
2339 return -1;
2340 }
2341 }
2342 String packageName = getNextArgRequired();
2343
2344 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2345 Context.USAGE_STATS_SERVICE));
2346 boolean isIdle = usm.isAppInactive(packageName, userId);
2347 pw.println("Idle=" + isIdle);
2348 return 0;
2349 }
2350
2351 int runSendTrimMemory(PrintWriter pw) throws RemoteException {
2352 int userId = UserHandle.USER_CURRENT;
2353 String opt;
2354 while ((opt = getNextOption()) != null) {
2355 if (opt.equals("--user")) {
2356 userId = UserHandle.parseUserArg(getNextArgRequired());
2357 if (userId == UserHandle.USER_ALL) {
2358 getErrPrintWriter().println("Error: Can't use user 'all'");
2359 return -1;
2360 }
2361 } else {
2362 getErrPrintWriter().println("Error: Unknown option: " + opt);
2363 return -1;
2364 }
2365 }
2366
2367 String proc = getNextArgRequired();
2368 String levelArg = getNextArgRequired();
2369 int level;
2370 switch (levelArg) {
2371 case "HIDDEN":
2372 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
2373 break;
2374 case "RUNNING_MODERATE":
2375 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
2376 break;
2377 case "BACKGROUND":
2378 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
2379 break;
2380 case "RUNNING_LOW":
2381 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
2382 break;
2383 case "MODERATE":
2384 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
2385 break;
2386 case "RUNNING_CRITICAL":
2387 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
2388 break;
2389 case "COMPLETE":
2390 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
2391 break;
2392 default:
Dianne Hackborne51505a2017-08-07 17:13:52 -07002393 try {
2394 level = Integer.parseInt(levelArg);
2395 } catch (NumberFormatException e) {
2396 getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
2397 return -1;
2398 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002399 }
2400 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
2401 getErrPrintWriter().println("Unknown error: failed to set trim level");
2402 return -1;
2403 }
2404 return 0;
2405 }
2406
Andrii Kulian839def92016-11-02 10:58:58 -07002407 int runDisplay(PrintWriter pw) throws RemoteException {
2408 String op = getNextArgRequired();
2409 switch (op) {
2410 case "move-stack":
2411 return runDisplayMoveStack(pw);
2412 default:
2413 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2414 return -1;
2415 }
2416 }
2417
Dianne Hackborn331084d2016-10-07 17:57:00 -07002418 int runStack(PrintWriter pw) throws RemoteException {
2419 String op = getNextArgRequired();
2420 switch (op) {
Andrii Kulian839def92016-11-02 10:58:58 -07002421 case "move-task":
Dianne Hackborn331084d2016-10-07 17:57:00 -07002422 return runStackMoveTask(pw);
2423 case "resize":
2424 return runStackResize(pw);
2425 case "resize-animated":
2426 return runStackResizeAnimated(pw);
2427 case "resize-docked-stack":
2428 return runStackResizeDocked(pw);
2429 case "positiontask":
2430 return runStackPositionTask(pw);
2431 case "list":
2432 return runStackList(pw);
2433 case "info":
2434 return runStackInfo(pw);
2435 case "move-top-activity-to-pinned-stack":
2436 return runMoveTopActivityToPinnedStack(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002437 case "remove":
2438 return runStackRemove(pw);
2439 default:
2440 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2441 return -1;
2442 }
2443 }
2444
2445
2446 private Rect getBounds() {
2447 String leftStr = getNextArgRequired();
2448 int left = Integer.parseInt(leftStr);
2449 String topStr = getNextArgRequired();
2450 int top = Integer.parseInt(topStr);
2451 String rightStr = getNextArgRequired();
2452 int right = Integer.parseInt(rightStr);
2453 String bottomStr = getNextArgRequired();
2454 int bottom = Integer.parseInt(bottomStr);
2455 if (left < 0) {
2456 getErrPrintWriter().println("Error: bad left arg: " + leftStr);
2457 return null;
2458 }
2459 if (top < 0) {
2460 getErrPrintWriter().println("Error: bad top arg: " + topStr);
2461 return null;
2462 }
2463 if (right <= 0) {
2464 getErrPrintWriter().println("Error: bad right arg: " + rightStr);
2465 return null;
2466 }
2467 if (bottom <= 0) {
2468 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr);
2469 return null;
2470 }
2471 return new Rect(left, top, right, bottom);
2472 }
2473
Andrii Kulian839def92016-11-02 10:58:58 -07002474 int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
2475 String stackIdStr = getNextArgRequired();
2476 int stackId = Integer.parseInt(stackIdStr);
2477 String displayIdStr = getNextArgRequired();
2478 int displayId = Integer.parseInt(displayIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002479 mTaskInterface.moveStackToDisplay(stackId, displayId);
Andrii Kulian839def92016-11-02 10:58:58 -07002480 return 0;
2481 }
2482
Dianne Hackborn331084d2016-10-07 17:57:00 -07002483 int runStackMoveTask(PrintWriter pw) throws RemoteException {
2484 String taskIdStr = getNextArgRequired();
2485 int taskId = Integer.parseInt(taskIdStr);
2486 String stackIdStr = getNextArgRequired();
2487 int stackId = Integer.parseInt(stackIdStr);
2488 String toTopStr = getNextArgRequired();
2489 final boolean toTop;
2490 if ("true".equals(toTopStr)) {
2491 toTop = true;
2492 } else if ("false".equals(toTopStr)) {
2493 toTop = false;
2494 } else {
2495 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr);
2496 return -1;
2497 }
2498
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002499 mTaskInterface.moveTaskToStack(taskId, stackId, toTop);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002500 return 0;
2501 }
2502
2503 int runStackResize(PrintWriter pw) throws RemoteException {
2504 String stackIdStr = getNextArgRequired();
2505 int stackId = Integer.parseInt(stackIdStr);
2506 final Rect bounds = getBounds();
2507 if (bounds == null) {
2508 getErrPrintWriter().println("Error: invalid input bounds");
2509 return -1;
2510 }
2511 return resizeStack(stackId, bounds, 0);
2512 }
2513
2514 int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
2515 String stackIdStr = getNextArgRequired();
2516 int stackId = Integer.parseInt(stackIdStr);
2517 final Rect bounds;
2518 if ("null".equals(peekNextArg())) {
2519 bounds = null;
2520 } else {
2521 bounds = getBounds();
2522 if (bounds == null) {
2523 getErrPrintWriter().println("Error: invalid input bounds");
2524 return -1;
2525 }
2526 }
2527 return resizeStackUnchecked(stackId, bounds, 0, true);
2528 }
2529
2530 int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate)
2531 throws RemoteException {
2532 try {
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002533 mTaskInterface.resizeStack(stackId, bounds, false, false, animate, -1);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002534 Thread.sleep(delayMs);
2535 } catch (InterruptedException e) {
2536 }
2537 return 0;
2538 }
2539
2540 int runStackResizeDocked(PrintWriter pw) throws RemoteException {
2541 final Rect bounds = getBounds();
2542 final Rect taskBounds = getBounds();
2543 if (bounds == null || taskBounds == null) {
2544 getErrPrintWriter().println("Error: invalid input bounds");
2545 return -1;
2546 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002547 mTaskInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002548 return 0;
2549 }
2550
2551 int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException {
2552 if (bounds == null) {
2553 getErrPrintWriter().println("Error: invalid input bounds");
2554 return -1;
2555 }
2556 return resizeStackUnchecked(stackId, bounds, delayMs, false);
2557 }
2558
2559 int runStackPositionTask(PrintWriter pw) throws RemoteException {
2560 String taskIdStr = getNextArgRequired();
2561 int taskId = Integer.parseInt(taskIdStr);
2562 String stackIdStr = getNextArgRequired();
2563 int stackId = Integer.parseInt(stackIdStr);
2564 String positionStr = getNextArgRequired();
2565 int position = Integer.parseInt(positionStr);
2566
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002567 mTaskInterface.positionTaskInStack(taskId, stackId, position);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002568 return 0;
2569 }
2570
2571 int runStackList(PrintWriter pw) throws RemoteException {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002572 List<ActivityManager.StackInfo> stacks = mTaskInterface.getAllStackInfos();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002573 for (ActivityManager.StackInfo info : stacks) {
2574 pw.println(info);
2575 }
2576 return 0;
2577 }
2578
2579 int runStackInfo(PrintWriter pw) throws RemoteException {
Wale Ogunwale68278562017-09-23 17:13:55 -07002580 int windowingMode = Integer.parseInt(getNextArgRequired());
2581 int activityType = Integer.parseInt(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002582 ActivityManager.StackInfo info = mTaskInterface.getStackInfo(windowingMode, activityType);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002583 pw.println(info);
2584 return 0;
2585 }
2586
2587 int runStackRemove(PrintWriter pw) throws RemoteException {
2588 String stackIdStr = getNextArgRequired();
2589 int stackId = Integer.parseInt(stackIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002590 mTaskInterface.removeStack(stackId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002591 return 0;
2592 }
2593
2594 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException {
2595 int stackId = Integer.parseInt(getNextArgRequired());
2596 final Rect bounds = getBounds();
2597 if (bounds == null) {
2598 getErrPrintWriter().println("Error: invalid input bounds");
2599 return -1;
2600 }
2601
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002602 if (!mTaskInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -07002603 getErrPrintWriter().println("Didn't move top activity to pinned stack.");
2604 return -1;
2605 }
2606 return 0;
2607 }
2608
Dianne Hackborn331084d2016-10-07 17:57:00 -07002609 void setBoundsSide(Rect bounds, String side, int value) {
2610 switch (side) {
2611 case "l":
2612 bounds.left = value;
2613 break;
2614 case "r":
2615 bounds.right = value;
2616 break;
2617 case "t":
2618 bounds.top = value;
2619 break;
2620 case "b":
2621 bounds.bottom = value;
2622 break;
2623 default:
2624 getErrPrintWriter().println("Unknown set side: " + side);
2625 break;
2626 }
2627 }
2628
2629 int runTask(PrintWriter pw) throws RemoteException {
2630 String op = getNextArgRequired();
2631 if (op.equals("lock")) {
2632 return runTaskLock(pw);
2633 } else if (op.equals("resizeable")) {
2634 return runTaskResizeable(pw);
2635 } else if (op.equals("resize")) {
2636 return runTaskResize(pw);
David Stevensee9e2772017-02-09 16:30:27 -08002637 } else if (op.equals("focus")) {
2638 return runTaskFocus(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002639 } else {
2640 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2641 return -1;
2642 }
2643 }
2644
2645 int runTaskLock(PrintWriter pw) throws RemoteException {
2646 String taskIdStr = getNextArgRequired();
2647 if (taskIdStr.equals("stop")) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002648 mTaskInterface.stopSystemLockTaskMode();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002649 } else {
2650 int taskId = Integer.parseInt(taskIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002651 mTaskInterface.startSystemLockTaskMode(taskId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002652 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002653 pw.println("Activity manager is " + (mTaskInterface.isInLockTaskMode() ? "" : "not ") +
Dianne Hackborn331084d2016-10-07 17:57:00 -07002654 "in lockTaskMode");
2655 return 0;
2656 }
2657
2658 int runTaskResizeable(PrintWriter pw) throws RemoteException {
2659 final String taskIdStr = getNextArgRequired();
2660 final int taskId = Integer.parseInt(taskIdStr);
2661 final String resizeableStr = getNextArgRequired();
2662 final int resizeableMode = Integer.parseInt(resizeableStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002663 mTaskInterface.setTaskResizeable(taskId, resizeableMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002664 return 0;
2665 }
2666
2667 int runTaskResize(PrintWriter pw) throws RemoteException {
2668 final String taskIdStr = getNextArgRequired();
2669 final int taskId = Integer.parseInt(taskIdStr);
2670 final Rect bounds = getBounds();
2671 if (bounds == null) {
2672 getErrPrintWriter().println("Error: invalid input bounds");
2673 return -1;
2674 }
2675 taskResize(taskId, bounds, 0, false);
2676 return 0;
2677 }
2678
2679 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
2680 throws RemoteException {
2681 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002682 mTaskInterface.resizeTask(taskId, bounds, resizeMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002683 try {
2684 Thread.sleep(delay_ms);
2685 } catch (InterruptedException e) {
2686 }
2687 }
2688
Dianne Hackborn331084d2016-10-07 17:57:00 -07002689 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
2690 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
2691 throws RemoteException {
2692 int maxMove;
2693 if (movingForward) {
2694 while (maxToTravel > 0
2695 && ((horizontal && taskRect.right < stackRect.right)
2696 ||(!horizontal && taskRect.bottom < stackRect.bottom))) {
2697 if (horizontal) {
2698 maxMove = Math.min(stepSize, stackRect.right - taskRect.right);
2699 maxToTravel -= maxMove;
2700 taskRect.right += maxMove;
2701 taskRect.left += maxMove;
2702 } else {
2703 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom);
2704 maxToTravel -= maxMove;
2705 taskRect.top += maxMove;
2706 taskRect.bottom += maxMove;
2707 }
2708 taskResize(taskId, taskRect, delay_ms, false);
2709 }
2710 } else {
2711 while (maxToTravel < 0
2712 && ((horizontal && taskRect.left > stackRect.left)
2713 ||(!horizontal && taskRect.top > stackRect.top))) {
2714 if (horizontal) {
2715 maxMove = Math.min(stepSize, taskRect.left - stackRect.left);
2716 maxToTravel -= maxMove;
2717 taskRect.right -= maxMove;
2718 taskRect.left -= maxMove;
2719 } else {
2720 maxMove = Math.min(stepSize, taskRect.top - stackRect.top);
2721 maxToTravel -= maxMove;
2722 taskRect.top -= maxMove;
2723 taskRect.bottom -= maxMove;
2724 }
2725 taskResize(taskId, taskRect, delay_ms, false);
2726 }
2727 }
2728 // Return the remaining distance we didn't travel because we reached the target location.
2729 return maxToTravel;
2730 }
2731
2732 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) {
2733 int stepSize = 0;
2734 if (greaterThanTarget && target < current) {
2735 current -= inStepSize;
2736 stepSize = inStepSize;
2737 if (target > current) {
2738 stepSize -= (target - current);
2739 }
2740 }
2741 if (!greaterThanTarget && target > current) {
2742 current += inStepSize;
2743 stepSize = inStepSize;
2744 if (target < current) {
2745 stepSize += (current - target);
2746 }
2747 }
2748 return stepSize;
2749 }
2750
David Stevensee9e2772017-02-09 16:30:27 -08002751 int runTaskFocus(PrintWriter pw) throws RemoteException {
2752 final int taskId = Integer.parseInt(getNextArgRequired());
2753 pw.println("Setting focus to task " + taskId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002754 mTaskInterface.setFocusedTask(taskId);
David Stevensee9e2772017-02-09 16:30:27 -08002755 return 0;
2756 }
2757
Dianne Hackborn331084d2016-10-07 17:57:00 -07002758 int runWrite(PrintWriter pw) {
2759 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2760 "registerUidObserver()");
Wale Ogunwaled7889f52018-10-25 11:03:20 -07002761 mInternal.mAtmInternal.flushRecentTasks();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002762 pw.println("All tasks persisted.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002763 return 0;
2764 }
2765
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002766 int runAttachAgent(PrintWriter pw) {
2767 // TODO: revisit the permissions required for attaching agents
2768 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2769 "attach-agent");
2770 String process = getNextArgRequired();
2771 String agent = getNextArgRequired();
2772 String opt;
2773 if ((opt = getNextArg()) != null) {
2774 pw.println("Error: Unknown option: " + opt);
2775 return -1;
2776 }
2777 mInternal.attachAgent(process, agent);
2778 return 0;
2779 }
2780
Michael Kwan94438b72016-11-03 15:30:34 -07002781 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
Matthew Ng626e0cc2016-12-07 17:25:53 -08002782 final Resources res = getResources(pw);
2783 if (res == null) {
2784 return -1;
2785 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002786 pw.println(ActivityTaskManager.supportsMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002787 return 0;
2788 }
2789
2790 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException {
2791 final Resources res = getResources(pw);
2792 if (res == null) {
2793 return -1;
2794 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002795 pw.println(ActivityTaskManager.supportsSplitScreenMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002796 return 0;
2797 }
2798
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002799 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
2800 int userid = UserHandle.parseUserArg(getNextArgRequired());
2801 ArrayList<String> packages = new ArrayList<>();
2802 packages.add(getNextArgRequired());
2803 String packageName;
2804 while ((packageName = getNextArg()) != null) {
2805 packages.add(packageName);
2806 }
2807 mInternal.scheduleApplicationInfoChanged(packages, userid);
2808 pw.println("Packages updated with most recent ApplicationInfos.");
2809 return 0;
2810 }
2811
Arthur Hsuf3f3a602017-02-21 14:01:53 -08002812 int runNoHomeScreen(PrintWriter pw) throws RemoteException {
2813 final Resources res = getResources(pw);
2814 if (res == null) {
2815 return -1;
2816 }
2817 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen));
2818 return 0;
2819 }
2820
Jeff Sharkeyfd658132017-05-03 11:38:01 -06002821 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
2822 mInternal.waitForBroadcastIdle(pw);
2823 return 0;
2824 }
2825
Matthew Ng626e0cc2016-12-07 17:25:53 -08002826 private Resources getResources(PrintWriter pw) throws RemoteException {
Michael Kwan94438b72016-11-03 15:30:34 -07002827 // system resources does not contain all the device configuration, construct it manually.
2828 Configuration config = mInterface.getConfiguration();
2829 if (config == null) {
2830 pw.println("Error: Activity manager has no configuration");
Matthew Ng626e0cc2016-12-07 17:25:53 -08002831 return null;
Michael Kwan94438b72016-11-03 15:30:34 -07002832 }
2833
2834 final DisplayMetrics metrics = new DisplayMetrics();
2835 metrics.setToDefaults();
2836
Matthew Ng626e0cc2016-12-07 17:25:53 -08002837 return new Resources(AssetManager.getSystem(), metrics, config);
Michael Kwan94438b72016-11-03 15:30:34 -07002838 }
2839
Dianne Hackborn2e441072015-10-28 18:00:57 -07002840 @Override
2841 public void onHelp() {
2842 PrintWriter pw = getOutPrintWriter();
2843 dumpHelp(pw, mDumping);
2844 }
2845
2846 static void dumpHelp(PrintWriter pw, boolean dumping) {
2847 if (dumping) {
2848 pw.println("Activity manager dump options:");
2849 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
2850 pw.println(" WHAT may be one of:");
2851 pw.println(" a[ctivities]: activity stack state");
2852 pw.println(" r[recents]: recent activities state");
2853 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002854 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002855 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
2856 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
2857 pw.println(" o[om]: out of memory management");
2858 pw.println(" perm[issions]: URI permission grant state");
2859 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
2860 pw.println(" provider [COMP_SPEC]: provider client-side state");
2861 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborn769b2e72018-12-05 08:51:20 -08002862 pw.println(" allowed-associations: current package association restrictions");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002863 pw.println(" as[sociations]: tracked app associations");
Dianne Hackborna631d562018-11-20 15:58:15 -08002864 pw.println(" lmk: stats on low memory killer");
2865 pw.println(" lru: raw LRU process list");
2866 pw.println(" binder-proxies: stats on binder objects and IPCs");
Dianne Hackborn0ef403e2017-01-24 18:22:15 -08002867 pw.println(" settings: currently applied config settings");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002868 pw.println(" service [COMP_SPEC]: service client-side state");
2869 pw.println(" package [PACKAGE_NAME]: all state related to given package");
2870 pw.println(" all: dump all activities");
2871 pw.println(" top: dump the top activity");
2872 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
2873 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
2874 pw.println(" a partial substring in a component name, a");
2875 pw.println(" hex object identifier.");
2876 pw.println(" -a: include all available server state.");
2877 pw.println(" -c: include client state.");
2878 pw.println(" -p: limit output to given package.");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002879 pw.println(" --checkin: output checkin format, resetting data.");
2880 pw.println(" --C: output checkin format, not resetting data.");
Steven Timotius4346f0a2017-09-12 11:07:21 -07002881 pw.println(" --proto: output dump in protocol buffer format.");
Felipe Lemeb546ca72018-08-15 08:44:12 -07002882 pw.println(" --autofill: dump just the autofill-related state of an activity");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002883 } else {
2884 pw.println("Activity manager (activity) commands:");
2885 pw.println(" help");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002886 pw.println(" Print this help text.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002887 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002888 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002889 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002890 pw.println(" Start an Activity. Options are:");
2891 pw.println(" -D: enable debugging");
2892 pw.println(" -N: enable native debugging");
2893 pw.println(" -W: wait for launch to complete");
2894 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>");
2895 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2896 pw.println(" between samples (use with --start-profiler)");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002897 pw.println(" --streaming: stream the profiling output to the specified file");
2898 pw.println(" (use with --start-profiler)");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002899 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
Andreas Gampe83085bb2017-06-26 17:54:11 -07002900 pw.println(" --attach-agent <agent>: attach the given agent before binding");
Andreas Gampeab8a63b2018-01-05 13:55:15 -08002901 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002902 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
2903 pw.println(" the top activity will be finished.");
2904 pw.println(" -S: force stop the target app before starting the activity");
2905 pw.println(" --track-allocation: enable tracking of object allocations");
2906 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2907 pw.println(" specified then run as the current user.");
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002908 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into.");
2909 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
Louis Changf379f802018-07-13 09:41:28 +08002910 pw.println(" --display <DISPLAY_ID>: The display to launch the activity into.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002911 pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
2912 pw.println(" Start a Service. Options are:");
2913 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2914 pw.println(" specified then run as the current user.");
Jaewan Kim329b35f2017-04-11 11:19:49 +09002915 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
2916 pw.println(" Start a foreground Service. Options are:");
2917 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2918 pw.println(" specified then run as the current user.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002919 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
2920 pw.println(" Stop a Service. Options are:");
2921 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2922 pw.println(" specified then run as the current user.");
2923 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>");
2924 pw.println(" Send a broadcast Intent. Options are:");
2925 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not");
2926 pw.println(" specified then send to all users.");
2927 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002928 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
David Brazdild5d42172018-02-14 19:39:03 +00002929 pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07002930 pw.println(" [--no-isolated-storage]");
Dianne Hackborn28824062016-10-18 13:19:20 -07002931 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
2932 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
2933 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
2934 pw.println(" is only one instrumentation. Options are:");
2935 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with");
2936 pw.println(" [-e perf true] to generate raw output for performance measurements.");
2937 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a");
2938 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]].");
2939 pw.println(" -p <FILE>: write profiling data to <FILE>");
Mike Mad2239822017-10-31 12:30:42 -07002940 pw.println(" -m: Write output as protobuf to stdout (machine readable)");
2941 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine");
2942 pw.println(" readable). If path is not specified, default directory and file name will");
2943 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto");
Dianne Hackborn28824062016-10-18 13:19:20 -07002944 pw.println(" -w: wait for instrumentation to finish before returning. Required for");
2945 pw.println(" test runners.");
2946 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
2947 pw.println(" current user if not specified.");
David Brazdild5d42172018-02-14 19:39:03 +00002948 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07002949 pw.println(" --no-isolated-storage: don't use isolated storage sandbox and ");
2950 pw.println(" mount full external storage");
Dianne Hackborn28824062016-10-18 13:19:20 -07002951 pw.println(" --no-window-animation: turn off window animations while running.");
2952 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
2953 pw.println(" This assumes that the process supports the selected ABI.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002954 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]");
2955 pw.println(" Trace IPC transactions.");
2956 pw.println(" start: start tracing IPC transactions.");
2957 pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
2958 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
2959 pw.println(" profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002960 pw.println(" [--streaming] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002961 pw.println(" Start and stop profiler on a process. The given <PROCESS> argument");
2962 pw.println(" may be either a process name or pid. Options are:");
2963 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2964 pw.println(" specify user of process to profile; uses current user if not specified.");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002965 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2966 pw.println(" between samples");
2967 pw.println(" --streaming: stream the profiling output to the specified file");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002968 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002969 pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
2970 pw.println(" be either a process name or pid. Options are:");
2971 pw.println(" -n: dump native heap instead of managed heap");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002972 pw.println(" -g: force GC before dumping the heap");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002973 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2974 pw.println(" specify user of process to dump; uses current user if not specified.");
2975 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>");
2976 pw.println(" Set application <PACKAGE> to debug. Options are:");
2977 pw.println(" -w: wait for debugger when application starts");
2978 pw.println(" --persistent: retain this value");
2979 pw.println(" clear-debug-app");
2980 pw.println(" Clear the previously set-debug-app.");
2981 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>");
2982 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or");
2983 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
2984 pw.println(" clear-watch-heap");
2985 pw.println(" Clear the previously set-watch-heap.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002986 pw.println(" bug-report [--progress | --telephony]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002987 pw.println(" Request bug report generation; will launch a notification");
2988 pw.println(" when done to select where it should be delivered. Options are:");
2989 pw.println(" --progress: will launch a notification right away to show its progress.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002990 pw.println(" --telephony: will dump only telephony sections.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002991 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002992 pw.println(" Completely stop the given application package.");
Christopher Tate8aa8fe12017-01-20 17:50:32 -08002993 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>");
2994 pw.println(" Induce a VM crash in the specified package or process");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002995 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
Makoto Onuki6569c362018-02-27 15:52:01 -08002996 pw.println(" Kill all background processes associated with the given application.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002997 pw.println(" kill-all");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002998 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn85e35642017-01-12 15:10:57 -08002999 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
3000 pw.println(" If the given application's uid is in the background and waiting to");
3001 pw.println(" become idle (not allowing background services), do that now.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003002 pw.println(" monitor [--gdb <port>]");
3003 pw.println(" Start monitoring for crashes or ANRs.");
3004 pw.println(" --gdb: start gdbserv on the given port at crash/ANR");
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07003005 pw.println(" watch-uids [--oom <uid>]");
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01003006 pw.println(" Start watching for and reporting uid state changes.");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003007 pw.println(" --oom: specify a uid for which to report detailed change messages.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003008 pw.println(" hang [--allow-restart]");
3009 pw.println(" Hang the system.");
3010 pw.println(" --allow-restart: allow watchdog to perform normal system restart");
3011 pw.println(" restart");
3012 pw.println(" Restart the user-space system.");
3013 pw.println(" idle-maintenance");
3014 pw.println(" Perform idle maintenance now.");
3015 pw.println(" screen-compat [on|off] <PACKAGE>");
3016 pw.println(" Control screen compatibility mode of <PACKAGE>.");
3017 pw.println(" package-importance <PACKAGE>");
3018 pw.println(" Print current importance of <PACKAGE>.");
3019 pw.println(" to-uri [INTENT]");
3020 pw.println(" Print the given Intent specification as a URI.");
3021 pw.println(" to-intent-uri [INTENT]");
3022 pw.println(" Print the given Intent specification as an intent: URI.");
3023 pw.println(" to-app-uri [INTENT]");
3024 pw.println(" Print the given Intent specification as an android-app: URI.");
3025 pw.println(" switch-user <USER_ID>");
3026 pw.println(" Switch to put USER_ID in the foreground, starting");
3027 pw.println(" execution of that user if it is currently stopped.");
3028 pw.println(" get-current-user");
3029 pw.println(" Returns id of the current foreground user.");
3030 pw.println(" start-user <USER_ID>");
3031 pw.println(" Start USER_ID in background if it is currently stopped;");
3032 pw.println(" use switch-user if you want to start the user in foreground");
3033 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]");
3034 pw.println(" Attempt to unlock the given user using the given authorization token.");
3035 pw.println(" stop-user [-w] [-f] <USER_ID>");
3036 pw.println(" Stop execution of USER_ID, not allowing it to run any");
3037 pw.println(" code until a later explicit start or switch to it.");
3038 pw.println(" -w: wait for stop-user to complete.");
3039 pw.println(" -f: force stop even if there are related users that cannot be stopped.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003040 pw.println(" is-user-stopped <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003041 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07003042 pw.println(" get-started-user-state <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003043 pw.println(" Gets the current state of the given started user.");
3044 pw.println(" track-associations");
3045 pw.println(" Enable association tracking.");
3046 pw.println(" untrack-associations");
3047 pw.println(" Disable and clear association tracking.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003048 pw.println(" get-uid-state <UID>");
3049 pw.println(" Gets the process state of an app given its <UID>.");
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07003050 pw.println(" attach-agent <PROCESS> <FILE>");
3051 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 +08003052 pw.println(" get-config [--days N] [--device] [--proto] [--display <DISPLAY_ID>]");
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08003053 pw.println(" Retrieve the configuration and any recent configurations of the device.");
3054 pw.println(" --days: also return last N days of configurations that have been seen.");
3055 pw.println(" --device: also output global device configuration info.");
3056 pw.println(" --proto: return result as a proto; does not include --days info.");
Jeff Change9467b22018-09-28 11:40:38 +08003057 pw.println(" --display: Specify for which display to run the command; if not ");
3058 pw.println(" specified then run for the default display.");
Michael Kwan94438b72016-11-03 15:30:34 -07003059 pw.println(" supports-multiwindow");
3060 pw.println(" Returns true if the device supports multiwindow.");
Matthew Ng626e0cc2016-12-07 17:25:53 -08003061 pw.println(" supports-split-screen-multi-window");
3062 pw.println(" Returns true if the device supports split screen multiwindow.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003063 pw.println(" suppress-resize-config-changes <true|false>");
3064 pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
3065 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
3066 pw.println(" Sets the inactive state of an app.");
3067 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
3068 pw.println(" Returns the inactive state of an app.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003069 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
Amith Yamasani17fffee2017-09-29 13:17:43 -07003070 pw.println(" Puts an app in the standby bucket.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003071 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
3072 pw.println(" Returns the standby bucket of an app.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003073 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
3074 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003075 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 -07003076 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays.");
3077 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>");
3078 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003079 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
Andrii Kulian839def92016-11-02 10:58:58 -07003080 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003081 pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
3082 pw.println(" bottom (false) of <STACK_ID>.");
3083 pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3084 pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.");
3085 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3086 pw.println(" Same as resize, but allow animation.");
3087 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
3088 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
3089 pw.println(" and supplying temporary different task bounds indicated by");
3090 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003091 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3092 pw.println(" Moves the top activity from");
3093 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
3094 pw.println(" bounds of the pinned stack.");
3095 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>");
3096 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
3097 pw.println(" list");
3098 pw.println(" List all of the activity stacks and their sizes.");
Wale Ogunwale68278562017-09-23 17:13:55 -07003099 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
3100 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003101 pw.println(" remove <STACK_ID>");
3102 pw.println(" Remove stack <STACK_ID>.");
3103 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
3104 pw.println(" lock <TASK_ID>");
3105 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run.");
3106 pw.println(" lock stop");
3107 pw.println(" End the current task lock.");
3108 pw.println(" resizeable <TASK_ID> [0|1|2|3]");
3109 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:");
3110 pw.println(" 0: unresizeable");
3111 pw.println(" 1: crop_windows");
3112 pw.println(" 2: resizeable");
3113 pw.println(" 3: resizeable_and_pipable");
3114 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3115 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
3116 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
3117 pw.println(" has the specified bounds.");
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01003118 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
3119 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
3120 pw.println(" without restarting any processes.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003121 pw.println(" write");
3122 pw.println(" Write all pending state to storage.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003123 pw.println();
3124 Intent.printIntentArgsHelp(pw, "");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003125 }
3126 }
3127}