blob: cc901821030a6ee9da4231f1c7d3fb783d5d6910 [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;
Bookatz03bfe6f2019-03-01 15:46:04 -080068import android.os.IProgressListener;
Dianne Hackborn354736e2016-08-22 17:00:05 -070069import android.os.ParcelFileDescriptor;
Makoto Onuki2c6657f2018-06-06 15:24:02 -070070import android.os.RemoteCallback;
71import android.os.RemoteCallback.OnResultListener;
Dianne Hackborn2e441072015-10-28 18:00:57 -070072import android.os.RemoteException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070073import android.os.ServiceManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -070074import android.os.ShellCommand;
Dianne Hackborn5c3296a2017-12-13 17:52:26 -080075import android.os.StrictMode;
Dianne Hackborn354736e2016-08-22 17:00:05 -070076import android.os.SystemClock;
Dianne Hackborn331084d2016-10-07 17:57:00 -070077import android.os.SystemProperties;
Dianne Hackborn2e441072015-10-28 18:00:57 -070078import android.os.UserHandle;
Alex Chau5c0df232018-02-22 15:57:17 +080079import android.os.UserManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070080import android.text.TextUtils;
Makoto Onuki2c6657f2018-06-06 15:24:02 -070081import android.text.format.Time;
Dianne Hackborn331084d2016-10-07 17:57:00 -070082import android.util.ArrayMap;
Felipe Leme2f1b2272016-03-25 16:15:02 -070083import android.util.DebugUtils;
Michael Kwan94438b72016-11-03 15:30:34 -070084import android.util.DisplayMetrics;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080085import android.util.proto.ProtoOutputStream;
86import android.view.Display;
Dianne Hackborn2e441072015-10-28 18:00:57 -070087
Dianne Hackborn331084d2016-10-07 17:57:00 -070088import com.android.internal.util.HexDump;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080089import com.android.internal.util.MemInfoReader;
Dianne Hackborn331084d2016-10-07 17:57:00 -070090import com.android.internal.util.Preconditions;
91
92import java.io.BufferedReader;
93import java.io.File;
94import java.io.IOException;
95import java.io.InputStream;
96import java.io.InputStreamReader;
Dianne Hackborn2e441072015-10-28 18:00:57 -070097import java.io.PrintWriter;
Dianne Hackborn354736e2016-08-22 17:00:05 -070098import java.net.URISyntaxException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070099import java.util.ArrayList;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800100import java.util.Arrays;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700101import java.util.Collections;
102import java.util.Comparator;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800103import java.util.HashSet;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700104import java.util.List;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800105import java.util.Set;
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700106import java.util.concurrent.CountDownLatch;
Bookatz03bfe6f2019-03-01 15:46:04 -0800107import java.util.concurrent.TimeUnit;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700108
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800109import javax.microedition.khronos.egl.EGL10;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800110import javax.microedition.khronos.egl.EGLConfig;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800111import javax.microedition.khronos.egl.EGLContext;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800112import javax.microedition.khronos.egl.EGLDisplay;
113import javax.microedition.khronos.egl.EGLSurface;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800114
Dianne Hackborn331084d2016-10-07 17:57:00 -0700115final class ActivityManagerShellCommand extends ShellCommand {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700116 public static final String NO_CLASS_ERROR_CODE = "Error type 3";
Dianne Hackborn331084d2016-10-07 17:57:00 -0700117 private static final String SHELL_PACKAGE_NAME = "com.android.shell";
118
Bookatz03bfe6f2019-03-01 15:46:04 -0800119 private static final int USER_OPERATION_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes
120
Dianne Hackborn2e441072015-10-28 18:00:57 -0700121 // IPC interface to activity manager -- don't need to do additional security checks.
122 final IActivityManager mInterface;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700123 final IActivityTaskManager mTaskInterface;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700124
125 // Internal service impl -- must perform security checks before touching.
126 final ActivityManagerService mInternal;
127
Dianne Hackborn354736e2016-08-22 17:00:05 -0700128 // Convenience for interacting with package manager.
129 final IPackageManager mPm;
130
131 private int mStartFlags = 0;
132 private boolean mWaitOption = false;
133 private boolean mStopOption = false;
134
135 private int mRepeat = 0;
136 private int mUserId;
137 private String mReceiverPermission;
138
139 private String mProfileFile;
140 private int mSamplingInterval;
141 private boolean mAutoStop;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800142 private boolean mStreaming; // Streaming the profiling output to a file.
Andreas Gampe83085bb2017-06-26 17:54:11 -0700143 private String mAgent; // Agent to attach on startup.
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800144 private boolean mAttachAgentDuringBind; // Whether agent should be attached late.
Andrii Kulian16802aa2016-11-02 12:21:33 -0700145 private int mDisplayId;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700146 private int mWindowingMode;
147 private int mActivityType;
Winson Chung6954fc92017-03-24 16:22:12 -0700148 private int mTaskId;
149 private boolean mIsTaskOverlay;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000150 private boolean mIsLockTask;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700151
Dianne Hackborn2e441072015-10-28 18:00:57 -0700152 final boolean mDumping;
153
154 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
155 mInterface = service;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700156 mTaskInterface = service.mActivityTaskManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700157 mInternal = service;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700158 mPm = AppGlobals.getPackageManager();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700159 mDumping = dumping;
160 }
161
162 @Override
163 public int onCommand(String cmd) {
164 if (cmd == null) {
165 return handleDefaultCommands(cmd);
166 }
Dianne Hackborn5c3296a2017-12-13 17:52:26 -0800167 final PrintWriter pw = getOutPrintWriter();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700168 try {
169 switch (cmd) {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700170 case "start":
171 case "start-activity":
172 return runStartActivity(pw);
173 case "startservice":
174 case "start-service":
Christopher Tate7e1368d2017-03-30 17:20:12 -0700175 return runStartService(pw, false);
176 case "startforegroundservice":
177 case "startfgservice":
178 case "start-foreground-service":
179 case "start-fg-service":
180 return runStartService(pw, true);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700181 case "stopservice":
182 case "stop-service":
Dianne Hackborn331084d2016-10-07 17:57:00 -0700183 return runStopService(pw);
184 case "broadcast":
185 return runSendBroadcast(pw);
186 case "instrument":
Dianne Hackborn28824062016-10-18 13:19:20 -0700187 getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");
188 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700189 case "trace-ipc":
190 return runTraceIpc(pw);
191 case "profile":
192 return runProfile(pw);
193 case "dumpheap":
194 return runDumpHeap(pw);
195 case "set-debug-app":
196 return runSetDebugApp(pw);
Andreas Gampe5b495d52018-01-22 15:15:54 -0800197 case "set-agent-app":
198 return runSetAgentApp(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700199 case "clear-debug-app":
200 return runClearDebugApp(pw);
201 case "set-watch-heap":
202 return runSetWatchHeap(pw);
203 case "clear-watch-heap":
204 return runClearWatchHeap(pw);
205 case "bug-report":
206 return runBugReport(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700207 case "force-stop":
208 return runForceStop(pw);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800209 case "crash":
210 return runCrash(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700211 case "kill":
212 return runKill(pw);
213 case "kill-all":
214 return runKillAll(pw);
Dianne Hackborn85e35642017-01-12 15:10:57 -0800215 case "make-uid-idle":
Dianne Hackborne07641d2016-11-09 15:07:23 -0800216 return runMakeIdle(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700217 case "monitor":
218 return runMonitor(pw);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +0100219 case "watch-uids":
220 return runWatchUids(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700221 case "hang":
222 return runHang(pw);
223 case "restart":
224 return runRestart(pw);
225 case "idle-maintenance":
226 return runIdleMaintenance(pw);
227 case "screen-compat":
228 return runScreenCompat(pw);
229 case "package-importance":
230 return runPackageImportance(pw);
231 case "to-uri":
232 return runToUri(pw, 0);
233 case "to-intent-uri":
234 return runToUri(pw, Intent.URI_INTENT_SCHEME);
235 case "to-app-uri":
236 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME);
237 case "switch-user":
238 return runSwitchUser(pw);
239 case "get-current-user":
240 return runGetCurrentUser(pw);
241 case "start-user":
242 return runStartUser(pw);
243 case "unlock-user":
244 return runUnlockUser(pw);
245 case "stop-user":
246 return runStopUser(pw);
247 case "is-user-stopped":
248 return runIsUserStopped(pw);
249 case "get-started-user-state":
250 return runGetStartedUserState(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700251 case "track-associations":
252 return runTrackAssociations(pw);
253 case "untrack-associations":
254 return runUntrackAssociations(pw);
Felipe Leme2f1b2272016-03-25 16:15:02 -0700255 case "get-uid-state":
256 return getUidState(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700257 case "get-config":
258 return runGetConfig(pw);
259 case "suppress-resize-config-changes":
260 return runSuppressResizeConfigChanges(pw);
261 case "set-inactive":
262 return runSetInactive(pw);
263 case "get-inactive":
264 return runGetInactive(pw);
Amith Yamasani17fffee2017-09-29 13:17:43 -0700265 case "set-standby-bucket":
266 return runSetStandbyBucket(pw);
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800267 case "get-standby-bucket":
268 return runGetStandbyBucket(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700269 case "send-trim-memory":
270 return runSendTrimMemory(pw);
Andrii Kulian839def92016-11-02 10:58:58 -0700271 case "display":
272 return runDisplay(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700273 case "stack":
274 return runStack(pw);
275 case "task":
276 return runTask(pw);
277 case "write":
278 return runWrite(pw);
Leonard Mosescuf3409ce2016-10-06 17:32:05 -0700279 case "attach-agent":
280 return runAttachAgent(pw);
Michael Kwan94438b72016-11-03 15:30:34 -0700281 case "supports-multiwindow":
282 return runSupportsMultiwindow(pw);
Matthew Ng626e0cc2016-12-07 17:25:53 -0800283 case "supports-split-screen-multi-window":
284 return runSupportsSplitScreenMultiwindow(pw);
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +0100285 case "update-appinfo":
286 return runUpdateApplicationInfo(pw);
Arthur Hsuf3f3a602017-02-21 14:01:53 -0800287 case "no-home-screen":
288 return runNoHomeScreen(pw);
Jeff Sharkeyfd658132017-05-03 11:38:01 -0600289 case "wait-for-broadcast-idle":
290 return runWaitForBroadcastIdle(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700291 default:
292 return handleDefaultCommands(cmd);
293 }
294 } catch (RemoteException e) {
295 pw.println("Remote exception: " + e);
296 }
297 return -1;
298 }
299
Dianne Hackborn354736e2016-08-22 17:00:05 -0700300 private Intent makeIntent(int defUser) throws URISyntaxException {
301 mStartFlags = 0;
302 mWaitOption = false;
303 mStopOption = false;
304 mRepeat = 0;
305 mProfileFile = null;
306 mSamplingInterval = 0;
307 mAutoStop = false;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800308 mStreaming = false;
Ng Zhi An8ab52a22018-08-29 10:20:33 -0700309 mUserId = mInternal.mUserController.handleIncomingUser(Binder.getCallingPid(),
310 Binder.getCallingUid(), defUser, false, ALLOW_FULL_ONLY,
311 "ActivityManagerShellCommand", null);
Andrii Kulian16802aa2016-11-02 12:21:33 -0700312 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700313 mWindowingMode = WINDOWING_MODE_UNDEFINED;
314 mActivityType = ACTIVITY_TYPE_UNDEFINED;
Winson Chung6954fc92017-03-24 16:22:12 -0700315 mTaskId = INVALID_TASK_ID;
316 mIsTaskOverlay = false;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000317 mIsLockTask = false;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700318
319 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
320 @Override
321 public boolean handleOption(String opt, ShellCommand cmd) {
322 if (opt.equals("-D")) {
323 mStartFlags |= ActivityManager.START_FLAG_DEBUG;
324 } else if (opt.equals("-N")) {
325 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING;
326 } else if (opt.equals("-W")) {
327 mWaitOption = true;
328 } else if (opt.equals("-P")) {
329 mProfileFile = getNextArgRequired();
330 mAutoStop = true;
331 } else if (opt.equals("--start-profiler")) {
332 mProfileFile = getNextArgRequired();
333 mAutoStop = false;
334 } else if (opt.equals("--sampling")) {
335 mSamplingInterval = Integer.parseInt(getNextArgRequired());
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800336 } else if (opt.equals("--streaming")) {
337 mStreaming = true;
Andreas Gampe83085bb2017-06-26 17:54:11 -0700338 } else if (opt.equals("--attach-agent")) {
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800339 if (mAgent != null) {
340 cmd.getErrPrintWriter().println(
341 "Multiple --attach-agent(-bind) not supported");
342 return false;
343 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700344 mAgent = getNextArgRequired();
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800345 mAttachAgentDuringBind = false;
346 } else if (opt.equals("--attach-agent-bind")) {
347 if (mAgent != null) {
348 cmd.getErrPrintWriter().println(
349 "Multiple --attach-agent(-bind) not supported");
350 return false;
351 }
352 mAgent = getNextArgRequired();
353 mAttachAgentDuringBind = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700354 } else if (opt.equals("-R")) {
355 mRepeat = Integer.parseInt(getNextArgRequired());
356 } else if (opt.equals("-S")) {
357 mStopOption = true;
358 } else if (opt.equals("--track-allocation")) {
359 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
360 } else if (opt.equals("--user")) {
361 mUserId = UserHandle.parseUserArg(getNextArgRequired());
362 } else if (opt.equals("--receiver-permission")) {
363 mReceiverPermission = getNextArgRequired();
Andrii Kulian16802aa2016-11-02 12:21:33 -0700364 } else if (opt.equals("--display")) {
365 mDisplayId = Integer.parseInt(getNextArgRequired());
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700366 } else if (opt.equals("--windowingMode")) {
367 mWindowingMode = Integer.parseInt(getNextArgRequired());
368 } else if (opt.equals("--activityType")) {
369 mActivityType = Integer.parseInt(getNextArgRequired());
Winson Chung6954fc92017-03-24 16:22:12 -0700370 } else if (opt.equals("--task")) {
371 mTaskId = Integer.parseInt(getNextArgRequired());
372 } else if (opt.equals("--task-overlay")) {
373 mIsTaskOverlay = true;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000374 } else if (opt.equals("--lock-task")) {
375 mIsLockTask = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700376 } else {
377 return false;
378 }
379 return true;
380 }
381 });
382 }
383
Bookatz03bfe6f2019-03-01 15:46:04 -0800384 private class ProgressWaiter extends IProgressListener.Stub {
385 private final CountDownLatch mFinishedLatch = new CountDownLatch(1);
386
387 @Override
388 public void onStarted(int id, Bundle extras) {}
389
390 @Override
391 public void onProgress(int id, int progress, Bundle extras) {}
392
393 @Override
394 public void onFinished(int id, Bundle extras) {
395 mFinishedLatch.countDown();
396 }
397
398 public boolean waitForFinish(long timeoutMillis) {
399 try {
400 return mFinishedLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
401 } catch (InterruptedException e) {
402 System.err.println("Thread interrupted unexpectedly.");
403 return false;
404 }
405 }
406 }
407
Dianne Hackborn354736e2016-08-22 17:00:05 -0700408 int runStartActivity(PrintWriter pw) throws RemoteException {
409 Intent intent;
410 try {
411 intent = makeIntent(UserHandle.USER_CURRENT);
412 } catch (URISyntaxException e) {
413 throw new RuntimeException(e.getMessage(), e);
414 }
415
416 if (mUserId == UserHandle.USER_ALL) {
417 getErrPrintWriter().println("Error: Can't start service with user 'all'");
418 return 1;
419 }
420
421 String mimeType = intent.getType();
422 if (mimeType == null && intent.getData() != null
423 && "content".equals(intent.getData().getScheme())) {
424 mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId);
425 }
426
427 do {
428 if (mStopOption) {
429 String packageName;
430 if (intent.getComponent() != null) {
431 packageName = intent.getComponent().getPackageName();
432 } else {
433 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0,
434 mUserId).getList();
435 if (activities == null || activities.size() <= 0) {
436 getErrPrintWriter().println("Error: Intent does not match any activities: "
437 + intent);
438 return 1;
439 } else if (activities.size() > 1) {
440 getErrPrintWriter().println(
441 "Error: Intent matches multiple activities; can't stop: "
442 + intent);
443 return 1;
444 }
445 packageName = activities.get(0).activityInfo.packageName;
446 }
447 pw.println("Stopping: " + packageName);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700448 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700449 mInterface.forceStopPackage(packageName, mUserId);
450 try {
451 Thread.sleep(250);
452 } catch (InterruptedException e) {
453 }
454 }
455
456 ProfilerInfo profilerInfo = null;
457
Andreas Gampe83085bb2017-06-26 17:54:11 -0700458 if (mProfileFile != null || mAgent != null) {
459 ParcelFileDescriptor fd = null;
460 if (mProfileFile != null) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700461 fd = openFileForSystem(mProfileFile, "w");
Andreas Gampe83085bb2017-06-26 17:54:11 -0700462 if (fd == null) {
463 return 1;
464 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700465 }
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800466 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800467 mStreaming, mAgent, mAttachAgentDuringBind);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700468 }
469
470 pw.println("Starting: " + intent);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700471 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700472 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
473
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700474 WaitResult result = null;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700475 int res;
476 final long startTime = SystemClock.uptimeMillis();
477 ActivityOptions options = null;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700478 if (mDisplayId != INVALID_DISPLAY) {
479 options = ActivityOptions.makeBasic();
480 options.setLaunchDisplayId(mDisplayId);
481 }
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700482 if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
483 if (options == null) {
484 options = ActivityOptions.makeBasic();
485 }
486 options.setLaunchWindowingMode(mWindowingMode);
487 }
488 if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
489 if (options == null) {
490 options = ActivityOptions.makeBasic();
491 }
492 options.setLaunchActivityType(mActivityType);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700493 }
Winson Chung6954fc92017-03-24 16:22:12 -0700494 if (mTaskId != INVALID_TASK_ID) {
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000495 if (options == null) {
496 options = ActivityOptions.makeBasic();
497 }
Winson Chung6954fc92017-03-24 16:22:12 -0700498 options.setLaunchTaskId(mTaskId);
499
500 if (mIsTaskOverlay) {
501 options.setTaskOverlay(true, true /* canResume */);
502 }
503 }
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000504 if (mIsLockTask) {
505 if (options == null) {
506 options = ActivityOptions.makeBasic();
507 }
Benjamin Franzcaffa772018-02-05 16:36:10 +0000508 options.setLockTaskEnabled(true);
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000509 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700510 if (mWaitOption) {
Wale Ogunwale7056a062018-10-18 15:02:50 -0700511 result = mInternal.startActivityAndWait(null, null, intent, mimeType,
Dianne Hackborn354736e2016-08-22 17:00:05 -0700512 null, null, 0, mStartFlags, profilerInfo,
513 options != null ? options.toBundle() : null, mUserId);
514 res = result.result;
515 } else {
Wale Ogunwale7056a062018-10-18 15:02:50 -0700516 res = mInternal.startActivityAsUser(null, null, intent, mimeType,
Dianne Hackborn354736e2016-08-22 17:00:05 -0700517 null, null, 0, mStartFlags, profilerInfo,
518 options != null ? options.toBundle() : null, mUserId);
519 }
520 final long endTime = SystemClock.uptimeMillis();
521 PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
522 boolean launched = false;
523 switch (res) {
524 case ActivityManager.START_SUCCESS:
525 launched = true;
526 break;
527 case ActivityManager.START_SWITCHES_CANCELED:
528 launched = true;
529 out.println(
530 "Warning: Activity not started because the "
531 + " current activity is being kept for the user.");
532 break;
533 case ActivityManager.START_DELIVERED_TO_TOP:
534 launched = true;
535 out.println(
536 "Warning: Activity not started, intent has "
537 + "been delivered to currently running "
538 + "top-most instance.");
539 break;
540 case ActivityManager.START_RETURN_INTENT_TO_CALLER:
541 launched = true;
542 out.println(
543 "Warning: Activity not started because intent "
544 + "should be handled by the caller");
545 break;
546 case ActivityManager.START_TASK_TO_FRONT:
547 launched = true;
548 out.println(
549 "Warning: Activity not started, its current "
550 + "task has been brought to the front");
551 break;
552 case ActivityManager.START_INTENT_NOT_RESOLVED:
553 out.println(
554 "Error: Activity not started, unable to "
555 + "resolve " + intent.toString());
556 break;
557 case ActivityManager.START_CLASS_NOT_FOUND:
558 out.println(NO_CLASS_ERROR_CODE);
559 out.println("Error: Activity class " +
560 intent.getComponent().toShortString()
561 + " does not exist.");
562 break;
563 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
564 out.println(
565 "Error: Activity not started, you requested to "
566 + "both forward and receive its result");
567 break;
568 case ActivityManager.START_PERMISSION_DENIED:
569 out.println(
570 "Error: Activity not started, you do not "
571 + "have permission to access it.");
572 break;
573 case ActivityManager.START_NOT_VOICE_COMPATIBLE:
574 out.println(
575 "Error: Activity not started, voice control not allowed for: "
576 + intent);
577 break;
578 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
579 out.println(
580 "Error: Not allowed to start background user activity"
581 + " that shouldn't be displayed for all users.");
582 break;
583 default:
584 out.println(
585 "Error: Activity not started, unknown error code " + res);
586 break;
587 }
Dianne Hackborn331084d2016-10-07 17:57:00 -0700588 out.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700589 if (mWaitOption && launched) {
590 if (result == null) {
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700591 result = new WaitResult();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700592 result.who = intent.getComponent();
593 }
594 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
Louis Chang0513a942019-03-06 12:38:13 +0800595 pw.println("LaunchState: " + launchStateToString(result.launchState));
Dianne Hackborn354736e2016-08-22 17:00:05 -0700596 if (result.who != null) {
597 pw.println("Activity: " + result.who.flattenToShortString());
598 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700599 if (result.totalTime >= 0) {
600 pw.println("TotalTime: " + result.totalTime);
601 }
602 pw.println("WaitTime: " + (endTime-startTime));
603 pw.println("Complete");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700604 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700605 }
606 mRepeat--;
607 if (mRepeat > 0) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700608 mTaskInterface.unhandledBack();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700609 }
610 } while (mRepeat > 0);
611 return 0;
612 }
613
Christopher Tate7e1368d2017-03-30 17:20:12 -0700614 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700615 final PrintWriter err = getErrPrintWriter();
616 Intent intent;
617 try {
618 intent = makeIntent(UserHandle.USER_CURRENT);
619 } catch (URISyntaxException e) {
620 throw new RuntimeException(e.getMessage(), e);
621 }
622 if (mUserId == UserHandle.USER_ALL) {
623 err.println("Error: Can't start activity with user 'all'");
624 return -1;
625 }
626 pw.println("Starting service: " + intent);
627 pw.flush();
628 ComponentName cn = mInterface.startService(null, intent, intent.getType(),
Christopher Tate242ba3e92017-04-14 15:07:06 -0700629 asForeground, SHELL_PACKAGE_NAME, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700630 if (cn == null) {
631 err.println("Error: Not found; no service started.");
632 return -1;
633 } else if (cn.getPackageName().equals("!")) {
634 err.println("Error: Requires permission " + cn.getClassName());
635 return -1;
636 } else if (cn.getPackageName().equals("!!")) {
637 err.println("Error: " + cn.getClassName());
638 return -1;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800639 } else if (cn.getPackageName().equals("?")) {
640 err.println("Error: " + cn.getClassName());
641 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700642 }
643 return 0;
644 }
645
646 int runStopService(PrintWriter pw) throws RemoteException {
647 final PrintWriter err = getErrPrintWriter();
648 Intent intent;
649 try {
650 intent = makeIntent(UserHandle.USER_CURRENT);
651 } catch (URISyntaxException e) {
652 throw new RuntimeException(e.getMessage(), e);
653 }
654 if (mUserId == UserHandle.USER_ALL) {
655 err.println("Error: Can't stop activity with user 'all'");
656 return -1;
657 }
658 pw.println("Stopping service: " + intent);
659 pw.flush();
660 int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
661 if (result == 0) {
662 err.println("Service not stopped: was not running.");
663 return -1;
664 } else if (result == 1) {
665 err.println("Service stopped");
666 return -1;
667 } else if (result == -1) {
668 err.println("Error stopping service");
669 return -1;
670 }
671 return 0;
672 }
673
674 final static class IntentReceiver extends IIntentReceiver.Stub {
675 private final PrintWriter mPw;
676 private boolean mFinished = false;
677
678 IntentReceiver(PrintWriter pw) {
679 mPw = pw;
680 }
681
682 @Override
683 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
684 boolean ordered, boolean sticky, int sendingUser) {
685 String line = "Broadcast completed: result=" + resultCode;
686 if (data != null) line = line + ", data=\"" + data + "\"";
687 if (extras != null) line = line + ", extras: " + extras;
688 mPw.println(line);
689 mPw.flush();
690 synchronized (this) {
691 mFinished = true;
692 notifyAll();
693 }
694 }
695
696 public synchronized void waitForFinish() {
697 try {
698 while (!mFinished) wait();
699 } catch (InterruptedException e) {
700 throw new IllegalStateException(e);
701 }
702 }
703 }
704
705 int runSendBroadcast(PrintWriter pw) throws RemoteException {
706 Intent intent;
707 try {
708 intent = makeIntent(UserHandle.USER_CURRENT);
709 } catch (URISyntaxException e) {
710 throw new RuntimeException(e.getMessage(), e);
711 }
Jeff Sharkey6a34e562016-12-21 09:56:00 -0700712 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700713 IntentReceiver receiver = new IntentReceiver(pw);
714 String[] requiredPermissions = mReceiverPermission == null ? null
715 : new String[] {mReceiverPermission};
716 pw.println("Broadcasting: " + intent);
717 pw.flush();
718 mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
719 android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
720 receiver.waitForFinish();
721 return 0;
722 }
723
Dianne Hackborn331084d2016-10-07 17:57:00 -0700724 int runTraceIpc(PrintWriter pw) throws RemoteException {
725 String op = getNextArgRequired();
726 if (op.equals("start")) {
727 return runTraceIpcStart(pw);
728 } else if (op.equals("stop")) {
729 return runTraceIpcStop(pw);
730 } else {
731 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'");
732 return -1;
733 }
734 }
735
736 int runTraceIpcStart(PrintWriter pw) throws RemoteException {
737 pw.println("Starting IPC tracing.");
738 pw.flush();
739 mInterface.startBinderTracking();
740 return 0;
741 }
742
743 int runTraceIpcStop(PrintWriter pw) throws RemoteException {
744 final PrintWriter err = getErrPrintWriter();
745 String opt;
746 String filename = null;
747 while ((opt=getNextOption()) != null) {
748 if (opt.equals("--dump-file")) {
749 filename = getNextArgRequired();
750 } else {
751 err.println("Error: Unknown option: " + opt);
752 return -1;
753 }
754 }
755 if (filename == null) {
756 err.println("Error: Specify filename to dump logs to.");
757 return -1;
758 }
759
760 File file = new File(filename);
761 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700762 ParcelFileDescriptor fd = openFileForSystem(filename, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700763 if (fd == null) {
764 return -1;
765 }
766
Dianne Hackborn331084d2016-10-07 17:57:00 -0700767 if (!mInterface.stopBinderTrackingAndDump(fd)) {
768 err.println("STOP TRACE FAILED.");
769 return -1;
770 }
771
772 pw.println("Stopped IPC tracing. Dumping logs to: " + filename);
773 return 0;
774 }
775
776 static void removeWallOption() {
777 String props = SystemProperties.get("dalvik.vm.extra-opts");
778 if (props != null && props.contains("-Xprofile:wallclock")) {
779 props = props.replace("-Xprofile:wallclock", "");
780 props = props.trim();
781 SystemProperties.set("dalvik.vm.extra-opts", props);
782 }
783 }
784
785 private int runProfile(PrintWriter pw) throws RemoteException {
786 final PrintWriter err = getErrPrintWriter();
787 String profileFile = null;
788 boolean start = false;
789 boolean wall = false;
790 int userId = UserHandle.USER_CURRENT;
791 int profileType = 0;
792 mSamplingInterval = 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800793 mStreaming = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700794
795 String process = null;
796
797 String cmd = getNextArgRequired();
798
799 if ("start".equals(cmd)) {
800 start = true;
801 String opt;
802 while ((opt=getNextOption()) != null) {
803 if (opt.equals("--user")) {
804 userId = UserHandle.parseUserArg(getNextArgRequired());
805 } else if (opt.equals("--wall")) {
806 wall = true;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800807 } else if (opt.equals("--streaming")) {
808 mStreaming = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700809 } else if (opt.equals("--sampling")) {
810 mSamplingInterval = Integer.parseInt(getNextArgRequired());
811 } else {
812 err.println("Error: Unknown option: " + opt);
813 return -1;
814 }
815 }
816 process = getNextArgRequired();
817 } else if ("stop".equals(cmd)) {
818 String opt;
819 while ((opt=getNextOption()) != null) {
820 if (opt.equals("--user")) {
821 userId = UserHandle.parseUserArg(getNextArgRequired());
822 } else {
823 err.println("Error: Unknown option: " + opt);
824 return -1;
825 }
826 }
827 process = getNextArg();
828 } else {
829 // Compatibility with old syntax: process is specified first.
830 process = cmd;
831 cmd = getNextArgRequired();
832 if ("start".equals(cmd)) {
833 start = true;
834 } else if (!"stop".equals(cmd)) {
835 throw new IllegalArgumentException("Profile command " + process + " not valid");
836 }
837 }
838
839 if (userId == UserHandle.USER_ALL) {
840 err.println("Error: Can't profile with user 'all'");
841 return -1;
842 }
843
844 ParcelFileDescriptor fd = null;
845 ProfilerInfo profilerInfo = null;
846
847 if (start) {
848 profileFile = getNextArgRequired();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700849 fd = openFileForSystem(profileFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700850 if (fd == null) {
851 return -1;
852 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700853 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800854 null, false);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700855 }
856
857 try {
858 if (wall) {
859 // XXX doesn't work -- this needs to be set before booting.
860 String props = SystemProperties.get("dalvik.vm.extra-opts");
861 if (props == null || !props.contains("-Xprofile:wallclock")) {
862 props = props + " -Xprofile:wallclock";
863 //SystemProperties.set("dalvik.vm.extra-opts", props);
864 }
865 } else if (start) {
866 //removeWallOption();
867 }
868 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
869 wall = false;
870 err.println("PROFILE FAILED on process " + process);
871 return -1;
872 }
873 } finally {
874 if (!wall) {
875 //removeWallOption();
876 }
877 }
878 return 0;
879 }
880
881 int runDumpHeap(PrintWriter pw) throws RemoteException {
882 final PrintWriter err = getErrPrintWriter();
883 boolean managed = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700884 boolean mallocInfo = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700885 int userId = UserHandle.USER_CURRENT;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700886 boolean runGc = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700887
888 String opt;
889 while ((opt=getNextOption()) != null) {
890 if (opt.equals("--user")) {
891 userId = UserHandle.parseUserArg(getNextArgRequired());
892 if (userId == UserHandle.USER_ALL) {
893 err.println("Error: Can't dump heap with user 'all'");
894 return -1;
895 }
896 } else if (opt.equals("-n")) {
897 managed = false;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700898 } else if (opt.equals("-g")) {
899 runGc = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700900 } else if (opt.equals("-m")) {
901 managed = false;
902 mallocInfo = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700903 } else {
904 err.println("Error: Unknown option: " + opt);
905 return -1;
906 }
907 }
908 String process = getNextArgRequired();
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700909 String heapFile = getNextArg();
910 if (heapFile == null) {
911 final Time t = new Time();
912 t.set(System.currentTimeMillis());
913 heapFile = "/data/local/tmp/heapdump-" + t.format("%Y%m%d-%H%M%S") + ".prof";
914 }
915 pw.println("File: " + heapFile);
916 pw.flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -0700917
918 File file = new File(heapFile);
919 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700920 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700921 if (fd == null) {
922 return -1;
923 }
924
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700925 final CountDownLatch latch = new CountDownLatch(1);
926
927 final RemoteCallback finishCallback = new RemoteCallback(new OnResultListener() {
928 @Override
929 public void onResult(Bundle result) {
930 latch.countDown();
931 }
932 }, null);
933
934 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd,
935 finishCallback)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700936 err.println("HEAP DUMP FAILED on process " + process);
937 return -1;
938 }
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700939 pw.println("Waiting for dump to finish...");
940 pw.flush();
941 try {
942 latch.await();
943 } catch (InterruptedException e) {
944 err.println("Caught InterruptedException");
945 }
946
Dianne Hackborn331084d2016-10-07 17:57:00 -0700947 return 0;
948 }
949
950 int runSetDebugApp(PrintWriter pw) throws RemoteException {
951 boolean wait = false;
952 boolean persistent = false;
953
954 String opt;
955 while ((opt=getNextOption()) != null) {
956 if (opt.equals("-w")) {
957 wait = true;
958 } else if (opt.equals("--persistent")) {
959 persistent = true;
960 } else {
961 getErrPrintWriter().println("Error: Unknown option: " + opt);
962 return -1;
963 }
964 }
965
966 String pkg = getNextArgRequired();
967 mInterface.setDebugApp(pkg, wait, persistent);
968 return 0;
969 }
970
Andreas Gampe5b495d52018-01-22 15:15:54 -0800971 int runSetAgentApp(PrintWriter pw) throws RemoteException {
972 String pkg = getNextArgRequired();
973 String agent = getNextArg();
974 mInterface.setAgentApp(pkg, agent);
975 return 0;
976 }
977
Dianne Hackborn331084d2016-10-07 17:57:00 -0700978 int runClearDebugApp(PrintWriter pw) throws RemoteException {
979 mInterface.setDebugApp(null, false, true);
980 return 0;
981 }
982
983 int runSetWatchHeap(PrintWriter pw) throws RemoteException {
984 String proc = getNextArgRequired();
985 String limit = getNextArgRequired();
986 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
987 return 0;
988 }
989
990 int runClearWatchHeap(PrintWriter pw) throws RemoteException {
991 String proc = getNextArgRequired();
992 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null);
993 return 0;
994 }
995
996 int runBugReport(PrintWriter pw) throws RemoteException {
997 String opt;
998 int bugreportType = ActivityManager.BUGREPORT_OPTION_FULL;
999 while ((opt=getNextOption()) != null) {
1000 if (opt.equals("--progress")) {
1001 bugreportType = ActivityManager.BUGREPORT_OPTION_INTERACTIVE;
Felipe Leme9606c3b2017-01-05 14:57:12 -08001002 } else if (opt.equals("--telephony")) {
1003 bugreportType = ActivityManager.BUGREPORT_OPTION_TELEPHONY;
Dianne Hackborn331084d2016-10-07 17:57:00 -07001004 } else {
1005 getErrPrintWriter().println("Error: Unknown option: " + opt);
1006 return -1;
1007 }
1008 }
1009 mInterface.requestBugReport(bugreportType);
1010 pw.println("Your lovely bug report is being created; please be patient.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001011 return 0;
1012 }
1013
Dianne Hackborn2e441072015-10-28 18:00:57 -07001014 int runForceStop(PrintWriter pw) throws RemoteException {
1015 int userId = UserHandle.USER_ALL;
1016
1017 String opt;
1018 while ((opt = getNextOption()) != null) {
1019 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001020 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001021 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001022 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001023 return -1;
1024 }
1025 }
1026 mInterface.forceStopPackage(getNextArgRequired(), userId);
1027 return 0;
1028 }
1029
Christopher Tate8aa8fe12017-01-20 17:50:32 -08001030 int runCrash(PrintWriter pw) throws RemoteException {
1031 int userId = UserHandle.USER_ALL;
1032
1033 String opt;
1034 while ((opt=getNextOption()) != null) {
1035 if (opt.equals("--user")) {
1036 userId = UserHandle.parseUserArg(getNextArgRequired());
1037 } else {
1038 getErrPrintWriter().println("Error: Unknown option: " + opt);
1039 return -1;
1040 }
1041 }
1042
1043 int pid = -1;
1044 String packageName = null;
1045 final String arg = getNextArgRequired();
1046 // The argument is either a pid or a package name
1047 try {
1048 pid = Integer.parseInt(arg);
1049 } catch (NumberFormatException e) {
1050 packageName = arg;
1051 }
1052 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
1053 return 0;
1054 }
1055
Dianne Hackborn2e441072015-10-28 18:00:57 -07001056 int runKill(PrintWriter pw) throws RemoteException {
1057 int userId = UserHandle.USER_ALL;
1058
1059 String opt;
1060 while ((opt=getNextOption()) != null) {
1061 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001062 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001063 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001064 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001065 return -1;
1066 }
1067 }
1068 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
1069 return 0;
1070 }
1071
1072 int runKillAll(PrintWriter pw) throws RemoteException {
1073 mInterface.killAllBackgroundProcesses();
1074 return 0;
1075 }
1076
Dianne Hackborne07641d2016-11-09 15:07:23 -08001077 int runMakeIdle(PrintWriter pw) throws RemoteException {
1078 int userId = UserHandle.USER_ALL;
1079
1080 String opt;
1081 while ((opt = getNextOption()) != null) {
1082 if (opt.equals("--user")) {
1083 userId = UserHandle.parseUserArg(getNextArgRequired());
1084 } else {
1085 getErrPrintWriter().println("Error: Unknown option: " + opt);
1086 return -1;
1087 }
1088 }
1089 mInterface.makePackageIdle(getNextArgRequired(), userId);
1090 return 0;
1091 }
1092
Dianne Hackborn331084d2016-10-07 17:57:00 -07001093 static final class MyActivityController extends IActivityController.Stub {
1094 final IActivityManager mInterface;
1095 final PrintWriter mPw;
1096 final InputStream mInput;
1097 final String mGdbPort;
1098 final boolean mMonkey;
1099
1100 static final int STATE_NORMAL = 0;
1101 static final int STATE_CRASHED = 1;
1102 static final int STATE_EARLY_ANR = 2;
1103 static final int STATE_ANR = 3;
1104
1105 int mState;
1106
1107 static final int RESULT_DEFAULT = 0;
1108
1109 static final int RESULT_CRASH_DIALOG = 0;
1110 static final int RESULT_CRASH_KILL = 1;
1111
1112 static final int RESULT_EARLY_ANR_CONTINUE = 0;
1113 static final int RESULT_EARLY_ANR_KILL = 1;
1114
1115 static final int RESULT_ANR_DIALOG = 0;
1116 static final int RESULT_ANR_KILL = 1;
1117 static final int RESULT_ANR_WAIT = 1;
1118
1119 int mResult;
1120
1121 Process mGdbProcess;
1122 Thread mGdbThread;
1123 boolean mGotGdbPrint;
1124
1125 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
1126 String gdbPort, boolean monkey) {
1127 mInterface = iam;
1128 mPw = pw;
1129 mInput = input;
1130 mGdbPort = gdbPort;
1131 mMonkey = monkey;
1132 }
1133
1134 @Override
1135 public boolean activityResuming(String pkg) {
1136 synchronized (this) {
1137 mPw.println("** Activity resuming: " + pkg);
1138 mPw.flush();
1139 }
1140 return true;
1141 }
1142
1143 @Override
1144 public boolean activityStarting(Intent intent, String pkg) {
1145 synchronized (this) {
1146 mPw.println("** Activity starting: " + pkg);
1147 mPw.flush();
1148 }
1149 return true;
1150 }
1151
1152 @Override
1153 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
1154 long timeMillis, String stackTrace) {
1155 synchronized (this) {
1156 mPw.println("** ERROR: PROCESS CRASHED");
1157 mPw.println("processName: " + processName);
1158 mPw.println("processPid: " + pid);
1159 mPw.println("shortMsg: " + shortMsg);
1160 mPw.println("longMsg: " + longMsg);
1161 mPw.println("timeMillis: " + timeMillis);
1162 mPw.println("stack:");
1163 mPw.print(stackTrace);
1164 mPw.println("#");
1165 mPw.flush();
1166 int result = waitControllerLocked(pid, STATE_CRASHED);
1167 return result == RESULT_CRASH_KILL ? false : true;
1168 }
1169 }
1170
1171 @Override
1172 public int appEarlyNotResponding(String processName, int pid, String annotation) {
1173 synchronized (this) {
1174 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING");
1175 mPw.println("processName: " + processName);
1176 mPw.println("processPid: " + pid);
1177 mPw.println("annotation: " + annotation);
1178 mPw.flush();
1179 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
1180 if (result == RESULT_EARLY_ANR_KILL) return -1;
1181 return 0;
1182 }
1183 }
1184
1185 @Override
1186 public int appNotResponding(String processName, int pid, String processStats) {
1187 synchronized (this) {
1188 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1189 mPw.println("processName: " + processName);
1190 mPw.println("processPid: " + pid);
1191 mPw.println("processStats:");
1192 mPw.print(processStats);
1193 mPw.println("#");
1194 mPw.flush();
1195 int result = waitControllerLocked(pid, STATE_ANR);
1196 if (result == RESULT_ANR_KILL) return -1;
1197 if (result == RESULT_ANR_WAIT) return 1;
1198 return 0;
1199 }
1200 }
1201
1202 @Override
1203 public int systemNotResponding(String message) {
1204 synchronized (this) {
1205 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1206 mPw.println("message: " + message);
1207 mPw.println("#");
1208 mPw.println("Allowing system to die.");
1209 mPw.flush();
1210 return -1;
1211 }
1212 }
1213
1214 void killGdbLocked() {
1215 mGotGdbPrint = false;
1216 if (mGdbProcess != null) {
1217 mPw.println("Stopping gdbserver");
1218 mPw.flush();
1219 mGdbProcess.destroy();
1220 mGdbProcess = null;
1221 }
1222 if (mGdbThread != null) {
1223 mGdbThread.interrupt();
1224 mGdbThread = null;
1225 }
1226 }
1227
1228 int waitControllerLocked(int pid, int state) {
1229 if (mGdbPort != null) {
1230 killGdbLocked();
1231
1232 try {
1233 mPw.println("Starting gdbserver on port " + mGdbPort);
1234 mPw.println("Do the following:");
1235 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
1236 mPw.println(" gdbclient app_process :" + mGdbPort);
1237 mPw.flush();
1238
1239 mGdbProcess = Runtime.getRuntime().exec(new String[] {
1240 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
1241 });
1242 final InputStreamReader converter = new InputStreamReader(
1243 mGdbProcess.getInputStream());
1244 mGdbThread = new Thread() {
1245 @Override
1246 public void run() {
1247 BufferedReader in = new BufferedReader(converter);
1248 String line;
1249 int count = 0;
1250 while (true) {
1251 synchronized (MyActivityController.this) {
1252 if (mGdbThread == null) {
1253 return;
1254 }
1255 if (count == 2) {
1256 mGotGdbPrint = true;
1257 MyActivityController.this.notifyAll();
1258 }
1259 }
1260 try {
1261 line = in.readLine();
1262 if (line == null) {
1263 return;
1264 }
1265 mPw.println("GDB: " + line);
1266 mPw.flush();
1267 count++;
1268 } catch (IOException e) {
1269 return;
1270 }
1271 }
1272 }
1273 };
1274 mGdbThread.start();
1275
1276 // Stupid waiting for .5s. Doesn't matter if we end early.
1277 try {
1278 this.wait(500);
1279 } catch (InterruptedException e) {
1280 }
1281
1282 } catch (IOException e) {
1283 mPw.println("Failure starting gdbserver: " + e);
1284 mPw.flush();
1285 killGdbLocked();
1286 }
1287 }
1288 mState = state;
1289 mPw.println("");
1290 printMessageForState();
1291 mPw.flush();
1292
1293 while (mState != STATE_NORMAL) {
1294 try {
1295 wait();
1296 } catch (InterruptedException e) {
1297 }
1298 }
1299
1300 killGdbLocked();
1301
1302 return mResult;
1303 }
1304
1305 void resumeController(int result) {
1306 synchronized (this) {
1307 mState = STATE_NORMAL;
1308 mResult = result;
1309 notifyAll();
1310 }
1311 }
1312
1313 void printMessageForState() {
1314 switch (mState) {
1315 case STATE_NORMAL:
1316 mPw.println("Monitoring activity manager... available commands:");
1317 break;
1318 case STATE_CRASHED:
1319 mPw.println("Waiting after crash... available commands:");
1320 mPw.println("(c)ontinue: show crash dialog");
1321 mPw.println("(k)ill: immediately kill app");
1322 break;
1323 case STATE_EARLY_ANR:
1324 mPw.println("Waiting after early ANR... available commands:");
1325 mPw.println("(c)ontinue: standard ANR processing");
1326 mPw.println("(k)ill: immediately kill app");
1327 break;
1328 case STATE_ANR:
1329 mPw.println("Waiting after ANR... available commands:");
1330 mPw.println("(c)ontinue: show ANR dialog");
1331 mPw.println("(k)ill: immediately kill app");
1332 mPw.println("(w)ait: wait some more");
1333 break;
1334 }
1335 mPw.println("(q)uit: finish monitoring");
1336 }
1337
1338 void run() throws RemoteException {
1339 try {
1340 printMessageForState();
1341 mPw.flush();
1342
1343 mInterface.setActivityController(this, mMonkey);
1344 mState = STATE_NORMAL;
1345
1346 InputStreamReader converter = new InputStreamReader(mInput);
1347 BufferedReader in = new BufferedReader(converter);
1348 String line;
1349
1350 while ((line = in.readLine()) != null) {
1351 boolean addNewline = true;
1352 if (line.length() <= 0) {
1353 addNewline = false;
1354 } else if ("q".equals(line) || "quit".equals(line)) {
1355 resumeController(RESULT_DEFAULT);
1356 break;
1357 } else if (mState == STATE_CRASHED) {
1358 if ("c".equals(line) || "continue".equals(line)) {
1359 resumeController(RESULT_CRASH_DIALOG);
1360 } else if ("k".equals(line) || "kill".equals(line)) {
1361 resumeController(RESULT_CRASH_KILL);
1362 } else {
1363 mPw.println("Invalid command: " + line);
1364 }
1365 } else if (mState == STATE_ANR) {
1366 if ("c".equals(line) || "continue".equals(line)) {
1367 resumeController(RESULT_ANR_DIALOG);
1368 } else if ("k".equals(line) || "kill".equals(line)) {
1369 resumeController(RESULT_ANR_KILL);
1370 } else if ("w".equals(line) || "wait".equals(line)) {
1371 resumeController(RESULT_ANR_WAIT);
1372 } else {
1373 mPw.println("Invalid command: " + line);
1374 }
1375 } else if (mState == STATE_EARLY_ANR) {
1376 if ("c".equals(line) || "continue".equals(line)) {
1377 resumeController(RESULT_EARLY_ANR_CONTINUE);
1378 } else if ("k".equals(line) || "kill".equals(line)) {
1379 resumeController(RESULT_EARLY_ANR_KILL);
1380 } else {
1381 mPw.println("Invalid command: " + line);
1382 }
1383 } else {
1384 mPw.println("Invalid command: " + line);
1385 }
1386
1387 synchronized (this) {
1388 if (addNewline) {
1389 mPw.println("");
1390 }
1391 printMessageForState();
1392 mPw.flush();
1393 }
1394 }
1395
1396 } catch (IOException e) {
1397 e.printStackTrace(mPw);
1398 mPw.flush();
1399 } finally {
1400 mInterface.setActivityController(null, mMonkey);
1401 }
1402 }
1403 }
1404
1405 int runMonitor(PrintWriter pw) throws RemoteException {
1406 String opt;
1407 String gdbPort = null;
1408 boolean monkey = false;
1409 while ((opt=getNextOption()) != null) {
1410 if (opt.equals("--gdb")) {
1411 gdbPort = getNextArgRequired();
1412 } else if (opt.equals("-m")) {
1413 monkey = true;
1414 } else {
1415 getErrPrintWriter().println("Error: Unknown option: " + opt);
1416 return -1;
1417 }
1418 }
1419
1420 MyActivityController controller = new MyActivityController(mInterface, pw,
1421 getRawInputStream(), gdbPort, monkey);
1422 controller.run();
1423 return 0;
1424 }
1425
Dianne Hackborne51505a2017-08-07 17:13:52 -07001426 static final class MyUidObserver extends IUidObserver.Stub
1427 implements ActivityManagerService.OomAdjObserver {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001428 final IActivityManager mInterface;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001429 final ActivityManagerService mInternal;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001430 final PrintWriter mPw;
1431 final InputStream mInput;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001432 final int mUid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001433
1434 static final int STATE_NORMAL = 0;
1435
1436 int mState;
1437
Dianne Hackborne51505a2017-08-07 17:13:52 -07001438 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
1439 mInterface = service;
1440 mInternal = service;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001441 mPw = pw;
1442 mInput = input;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001443 mUid = uid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001444 }
1445
1446 @Override
1447 public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException {
1448 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001449 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1450 try {
1451 mPw.print(uid);
1452 mPw.print(" procstate ");
1453 mPw.print(ProcessList.makeProcStateString(procState));
1454 mPw.print(" seq ");
1455 mPw.println(procStateSeq);
1456 mPw.flush();
1457 } finally {
1458 StrictMode.setThreadPolicy(oldPolicy);
1459 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001460 }
1461 }
1462
1463 @Override
1464 public void onUidGone(int uid, boolean disabled) throws RemoteException {
1465 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001466 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1467 try {
1468 mPw.print(uid);
1469 mPw.print(" gone");
1470 if (disabled) {
1471 mPw.print(" disabled");
1472 }
1473 mPw.println();
1474 mPw.flush();
1475 } finally {
1476 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001477 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001478 }
1479 }
1480
1481 @Override
1482 public void onUidActive(int uid) throws RemoteException {
1483 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001484 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1485 try {
1486 mPw.print(uid);
1487 mPw.println(" active");
1488 mPw.flush();
1489 } finally {
1490 StrictMode.setThreadPolicy(oldPolicy);
1491 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001492 }
1493 }
1494
1495 @Override
1496 public void onUidIdle(int uid, boolean disabled) throws RemoteException {
1497 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001498 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1499 try {
1500 mPw.print(uid);
1501 mPw.print(" idle");
1502 if (disabled) {
1503 mPw.print(" disabled");
1504 }
1505 mPw.println();
1506 mPw.flush();
1507 } finally {
1508 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001509 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001510 }
1511 }
1512
1513 @Override
1514 public void onUidCachedChanged(int uid, boolean cached) throws RemoteException {
1515 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001516 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1517 try {
1518 mPw.print(uid);
1519 mPw.println(cached ? " cached" : " uncached");
1520 mPw.flush();
1521 } finally {
1522 StrictMode.setThreadPolicy(oldPolicy);
1523 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001524 }
1525 }
1526
Dianne Hackborne51505a2017-08-07 17:13:52 -07001527 @Override
1528 public void onOomAdjMessage(String msg) {
1529 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001530 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1531 try {
1532 mPw.print("# ");
1533 mPw.println(msg);
1534 mPw.flush();
1535 } finally {
1536 StrictMode.setThreadPolicy(oldPolicy);
1537 }
Dianne Hackborne51505a2017-08-07 17:13:52 -07001538 }
1539 }
1540
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001541 void printMessageForState() {
1542 switch (mState) {
1543 case STATE_NORMAL:
1544 mPw.println("Watching uid states... available commands:");
1545 break;
1546 }
1547 mPw.println("(q)uit: finish watching");
1548 }
1549
1550 void run() throws RemoteException {
1551 try {
1552 printMessageForState();
1553 mPw.flush();
1554
1555 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE
1556 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
1557 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
1558 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackborne51505a2017-08-07 17:13:52 -07001559 if (mUid >= 0) {
1560 mInternal.setOomAdjObserver(mUid, this);
1561 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001562 mState = STATE_NORMAL;
1563
1564 InputStreamReader converter = new InputStreamReader(mInput);
1565 BufferedReader in = new BufferedReader(converter);
1566 String line;
1567
1568 while ((line = in.readLine()) != null) {
1569 boolean addNewline = true;
1570 if (line.length() <= 0) {
1571 addNewline = false;
1572 } else if ("q".equals(line) || "quit".equals(line)) {
1573 break;
1574 } else {
1575 mPw.println("Invalid command: " + line);
1576 }
1577
1578 synchronized (this) {
1579 if (addNewline) {
1580 mPw.println("");
1581 }
1582 printMessageForState();
1583 mPw.flush();
1584 }
1585 }
1586
1587 } catch (IOException e) {
1588 e.printStackTrace(mPw);
1589 mPw.flush();
1590 } finally {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001591 if (mUid >= 0) {
1592 mInternal.clearOomAdjObserver();
1593 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001594 mInterface.unregisterUidObserver(this);
1595 }
1596 }
1597 }
1598
1599 int runWatchUids(PrintWriter pw) throws RemoteException {
1600 String opt;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001601 int uid = -1;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001602 while ((opt=getNextOption()) != null) {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001603 if (opt.equals("--oom")) {
1604 uid = Integer.parseInt(getNextArgRequired());
1605 } else {
1606 getErrPrintWriter().println("Error: Unknown option: " + opt);
1607 return -1;
1608
1609 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001610 }
1611
Dianne Hackborne51505a2017-08-07 17:13:52 -07001612 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001613 controller.run();
1614 return 0;
1615 }
1616
Dianne Hackborn331084d2016-10-07 17:57:00 -07001617 int runHang(PrintWriter pw) throws RemoteException {
1618 String opt;
1619 boolean allowRestart = false;
1620 while ((opt=getNextOption()) != null) {
1621 if (opt.equals("--allow-restart")) {
1622 allowRestart = true;
1623 } else {
1624 getErrPrintWriter().println("Error: Unknown option: " + opt);
1625 return -1;
1626 }
1627 }
1628
1629 pw.println("Hanging the system...");
1630 pw.flush();
1631 mInterface.hang(new Binder(), allowRestart);
1632 return 0;
1633 }
1634
1635 int runRestart(PrintWriter pw) throws RemoteException {
1636 String opt;
1637 while ((opt=getNextOption()) != null) {
1638 getErrPrintWriter().println("Error: Unknown option: " + opt);
1639 return -1;
1640 }
1641
1642 pw.println("Restart the system...");
1643 pw.flush();
1644 mInterface.restart();
1645 return 0;
1646 }
1647
1648 int runIdleMaintenance(PrintWriter pw) throws RemoteException {
1649 String opt;
1650 while ((opt=getNextOption()) != null) {
1651 getErrPrintWriter().println("Error: Unknown option: " + opt);
1652 return -1;
1653 }
1654
1655 pw.println("Performing idle maintenance...");
1656 mInterface.sendIdleJobTrigger();
1657 return 0;
1658 }
1659
1660 int runScreenCompat(PrintWriter pw) throws RemoteException {
1661 String mode = getNextArgRequired();
1662 boolean enabled;
1663 if ("on".equals(mode)) {
1664 enabled = true;
1665 } else if ("off".equals(mode)) {
1666 enabled = false;
1667 } else {
1668 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode);
1669 return -1;
1670 }
1671
1672 String packageName = getNextArgRequired();
1673 do {
1674 try {
1675 mInterface.setPackageScreenCompatMode(packageName, enabled
1676 ? ActivityManager.COMPAT_MODE_ENABLED
1677 : ActivityManager.COMPAT_MODE_DISABLED);
1678 } catch (RemoteException e) {
1679 }
1680 packageName = getNextArg();
1681 } while (packageName != null);
1682 return 0;
1683 }
1684
1685 int runPackageImportance(PrintWriter pw) throws RemoteException {
1686 String packageName = getNextArgRequired();
1687 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell");
1688 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
1689 return 0;
1690 }
1691
1692 int runToUri(PrintWriter pw, int flags) throws RemoteException {
1693 Intent intent;
1694 try {
1695 intent = makeIntent(UserHandle.USER_CURRENT);
1696 } catch (URISyntaxException e) {
1697 throw new RuntimeException(e.getMessage(), e);
1698 }
1699 pw.println(intent.toUri(flags));
1700 return 0;
1701 }
1702
1703 int runSwitchUser(PrintWriter pw) throws RemoteException {
Alex Chau5c0df232018-02-22 15:57:17 +08001704 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
Varun Shah50ef2002019-03-04 16:41:12 -08001705 final int userSwitchable = userManager.getUserSwitchability();
1706 if (userSwitchable != UserManager.SWITCHABILITY_STATUS_OK) {
1707 getErrPrintWriter().println("Error: " + userSwitchable);
Alex Chau5c0df232018-02-22 15:57:17 +08001708 return -1;
1709 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001710 String user = getNextArgRequired();
1711 mInterface.switchUser(Integer.parseInt(user));
1712 return 0;
1713 }
1714
1715 int runGetCurrentUser(PrintWriter pw) throws RemoteException {
1716 UserInfo currentUser = Preconditions.checkNotNull(mInterface.getCurrentUser(),
1717 "Current user not set");
1718 pw.println(currentUser.id);
1719 return 0;
1720 }
1721
1722 int runStartUser(PrintWriter pw) throws RemoteException {
Bookatz03bfe6f2019-03-01 15:46:04 -08001723 boolean wait = false;
1724 String opt;
1725 while ((opt = getNextOption()) != null) {
1726 if ("-w".equals(opt)) {
1727 wait = true;
1728 } else {
1729 getErrPrintWriter().println("Error: unknown option: " + opt);
1730 return -1;
1731 }
1732 }
1733 int userId = Integer.parseInt(getNextArgRequired());
1734
1735 final ProgressWaiter waiter = wait ? new ProgressWaiter() : null;
1736 boolean success = mInterface.startUserInBackgroundWithListener(userId, waiter);
1737 if (wait && success) {
1738 success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS);
1739 }
1740
Dianne Hackborn331084d2016-10-07 17:57:00 -07001741 if (success) {
1742 pw.println("Success: user started");
1743 } else {
1744 getErrPrintWriter().println("Error: could not start user");
1745 }
1746 return 0;
1747 }
1748
1749 private static byte[] argToBytes(String arg) {
1750 if (arg.equals("!")) {
1751 return null;
1752 } else {
1753 return HexDump.hexStringToByteArray(arg);
1754 }
1755 }
1756
1757 int runUnlockUser(PrintWriter pw) throws RemoteException {
1758 int userId = Integer.parseInt(getNextArgRequired());
1759 byte[] token = argToBytes(getNextArgRequired());
1760 byte[] secret = argToBytes(getNextArgRequired());
1761 boolean success = mInterface.unlockUser(userId, token, secret, null);
1762 if (success) {
1763 pw.println("Success: user unlocked");
1764 } else {
1765 getErrPrintWriter().println("Error: could not unlock user");
1766 }
1767 return 0;
1768 }
1769
1770 static final class StopUserCallback extends IStopUserCallback.Stub {
1771 private boolean mFinished = false;
1772
1773 public synchronized void waitForFinish() {
1774 try {
1775 while (!mFinished) wait();
1776 } catch (InterruptedException e) {
1777 throw new IllegalStateException(e);
1778 }
1779 }
1780
1781 @Override
1782 public synchronized void userStopped(int userId) {
1783 mFinished = true;
1784 notifyAll();
1785 }
1786
1787 @Override
1788 public synchronized void userStopAborted(int userId) {
1789 mFinished = true;
1790 notifyAll();
1791 }
1792 }
1793
1794 int runStopUser(PrintWriter pw) throws RemoteException {
1795 boolean wait = false;
1796 boolean force = false;
1797 String opt;
1798 while ((opt = getNextOption()) != null) {
1799 if ("-w".equals(opt)) {
1800 wait = true;
1801 } else if ("-f".equals(opt)) {
1802 force = true;
1803 } else {
1804 getErrPrintWriter().println("Error: unknown option: " + opt);
1805 return -1;
1806 }
1807 }
1808 int user = Integer.parseInt(getNextArgRequired());
1809 StopUserCallback callback = wait ? new StopUserCallback() : null;
1810
1811 int res = mInterface.stopUser(user, force, callback);
1812 if (res != ActivityManager.USER_OP_SUCCESS) {
1813 String txt = "";
1814 switch (res) {
1815 case ActivityManager.USER_OP_IS_CURRENT:
1816 txt = " (Can't stop current user)";
1817 break;
1818 case ActivityManager.USER_OP_UNKNOWN_USER:
1819 txt = " (Unknown user " + user + ")";
1820 break;
1821 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
1822 txt = " (System user cannot be stopped)";
1823 break;
1824 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP:
1825 txt = " (Can't stop user " + user
1826 + " - one of its related users can't be stopped)";
1827 break;
1828 }
1829 getErrPrintWriter().println("Switch failed: " + res + txt);
1830 return -1;
1831 } else if (callback != null) {
1832 callback.waitForFinish();
1833 }
1834 return 0;
1835 }
1836
1837 int runIsUserStopped(PrintWriter pw) {
1838 int userId = UserHandle.parseUserArg(getNextArgRequired());
1839 boolean stopped = mInternal.isUserStopped(userId);
1840 pw.println(stopped);
1841 return 0;
1842 }
1843
1844 int runGetStartedUserState(PrintWriter pw) throws RemoteException {
1845 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1846 "runGetStartedUserState()");
1847 final int userId = Integer.parseInt(getNextArgRequired());
1848 try {
1849 pw.println(mInternal.getStartedUserState(userId));
1850 } catch (NullPointerException e) {
1851 pw.println("User is not started: " + userId);
1852 }
Dianne Hackborn2e441072015-10-28 18:00:57 -07001853 return 0;
1854 }
1855
1856 int runTrackAssociations(PrintWriter pw) {
1857 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Makoto Onukid5e74ed2019-01-31 15:50:18 -08001858 "runTrackAssociations()");
Dianne Hackborn2e441072015-10-28 18:00:57 -07001859 synchronized (mInternal) {
1860 if (!mInternal.mTrackingAssociations) {
1861 mInternal.mTrackingAssociations = true;
1862 pw.println("Association tracking started.");
1863 } else {
1864 pw.println("Association tracking already enabled.");
1865 }
1866 }
1867 return 0;
1868 }
1869
1870 int runUntrackAssociations(PrintWriter pw) {
1871 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Makoto Onukid5e74ed2019-01-31 15:50:18 -08001872 "runUntrackAssociations()");
Dianne Hackborn2e441072015-10-28 18:00:57 -07001873 synchronized (mInternal) {
1874 if (mInternal.mTrackingAssociations) {
1875 mInternal.mTrackingAssociations = false;
1876 mInternal.mAssociations.clear();
1877 pw.println("Association tracking stopped.");
1878 } else {
1879 pw.println("Association tracking not running.");
1880 }
1881 }
1882 return 0;
1883 }
1884
Felipe Leme2f1b2272016-03-25 16:15:02 -07001885 int getUidState(PrintWriter pw) throws RemoteException {
1886 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1887 "getUidState()");
1888 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
1889 pw.print(state);
1890 pw.print(" (");
1891 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
1892 pw.println(")");
1893 return 0;
1894 }
1895
Dianne Hackborn331084d2016-10-07 17:57:00 -07001896 private List<Configuration> getRecentConfigurations(int days) {
1897 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1898 Context.USAGE_STATS_SERVICE));
1899 final long now = System.currentTimeMillis();
1900 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
Sudheer Shanka28537b62016-09-07 11:12:31 -07001901 try {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001902 @SuppressWarnings("unchecked")
1903 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
1904 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
1905 if (configStatsSlice == null) {
1906 return Collections.emptyList();
1907 }
1908
1909 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
1910 final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
1911 final int configStatsListSize = configStatsList.size();
1912 for (int i = 0; i < configStatsListSize; i++) {
1913 final ConfigurationStats stats = configStatsList.get(i);
1914 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
1915 if (indexOfKey < 0) {
1916 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
1917 } else {
1918 recentConfigs.setValueAt(indexOfKey,
1919 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
1920 }
1921 }
1922
1923 final Comparator<Configuration> comparator = new Comparator<Configuration>() {
1924 @Override
1925 public int compare(Configuration a, Configuration b) {
1926 return recentConfigs.get(b).compareTo(recentConfigs.get(a));
1927 }
1928 };
1929
1930 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
1931 configs.addAll(recentConfigs.keySet());
1932 Collections.sort(configs, comparator);
1933 return configs;
1934
1935 } catch (RemoteException e) {
1936 return Collections.emptyList();
Sudheer Shanka28537b62016-09-07 11:12:31 -07001937 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001938 }
1939
Dianne Hackborn337e01a2018-02-27 17:16:37 -08001940 /**
1941 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
1942 * and EGLSurface and querying extensions.
1943 *
1944 * @param egl An EGL API object
1945 * @param display An EGLDisplay to create a context and surface with
1946 * @param config The EGLConfig to get the extensions for
1947 * @param surfaceSize eglCreatePbufferSurface generic parameters
1948 * @param contextAttribs eglCreateContext generic parameters
1949 * @param glExtensions A Set<String> to add GL extensions to
1950 */
1951 private static void addExtensionsForConfig(
1952 EGL10 egl,
1953 EGLDisplay display,
1954 EGLConfig config,
1955 int[] surfaceSize,
1956 int[] contextAttribs,
1957 Set<String> glExtensions) {
1958 // Create a context.
1959 EGLContext context =
1960 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
1961 // No-op if we can't create a context.
1962 if (context == EGL10.EGL_NO_CONTEXT) {
1963 return;
1964 }
1965
1966 // Create a surface.
1967 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
1968 if (surface == EGL10.EGL_NO_SURFACE) {
1969 egl.eglDestroyContext(display, context);
1970 return;
1971 }
1972
1973 // Update the current surface and context.
1974 egl.eglMakeCurrent(display, surface, surface, context);
1975
1976 // Get the list of extensions.
1977 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
1978 if (!TextUtils.isEmpty(extensionList)) {
1979 // The list of extensions comes from the driver separated by spaces.
1980 // Split them apart and add them into a Set for deduping purposes.
1981 for (String extension : extensionList.split(" ")) {
1982 glExtensions.add(extension);
1983 }
1984 }
1985
1986 // Tear down the context and surface for this config.
1987 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
1988 egl.eglDestroySurface(display, surface);
1989 egl.eglDestroyContext(display, context);
1990 }
1991
1992
1993 Set<String> getGlExtensionsFromDriver() {
1994 Set<String> glExtensions = new HashSet<>();
1995
1996 // Get the EGL implementation.
1997 EGL10 egl = (EGL10) EGLContext.getEGL();
1998 if (egl == null) {
1999 getErrPrintWriter().println("Warning: couldn't get EGL");
2000 return glExtensions;
2001 }
2002
2003 // Get the default display and initialize it.
2004 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
2005 int[] version = new int[2];
2006 egl.eglInitialize(display, version);
2007
2008 // Call getConfigs() in order to find out how many there are.
2009 int[] numConfigs = new int[1];
2010 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
2011 getErrPrintWriter().println("Warning: couldn't get EGL config count");
2012 return glExtensions;
2013 }
2014
2015 // Allocate space for all configs and ask again.
2016 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
2017 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
2018 getErrPrintWriter().println("Warning: couldn't get EGL configs");
2019 return glExtensions;
2020 }
2021
2022 // Allocate surface size parameters outside of the main loop to cut down
2023 // on GC thrashing. 1x1 is enough since we are only using it to get at
2024 // the list of extensions.
2025 int[] surfaceSize =
2026 new int[] {
2027 EGL10.EGL_WIDTH, 1,
2028 EGL10.EGL_HEIGHT, 1,
2029 EGL10.EGL_NONE
2030 };
2031
2032 // For when we need to create a GLES2.0 context.
2033 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
2034 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
2035
2036 // For getting return values from eglGetConfigAttrib
2037 int[] attrib = new int[1];
2038
2039 for (int i = 0; i < numConfigs[0]; i++) {
2040 // Get caveat for this config in order to skip slow (i.e. software) configs.
2041 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
2042 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
2043 continue;
2044 }
2045
2046 // If the config does not support pbuffers we cannot do an eglMakeCurrent
2047 // on it in addExtensionsForConfig(), so skip it here. Attempting to make
2048 // it current with a pbuffer will result in an EGL_BAD_MATCH error
2049 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
2050 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
2051 continue;
2052 }
2053
2054 final int EGL_OPENGL_ES_BIT = 0x0001;
2055 final int EGL_OPENGL_ES2_BIT = 0x0004;
2056 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
2057 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
2058 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
2059 }
2060 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
2061 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
2062 }
2063 }
2064
2065 // Release all EGL resources.
2066 egl.eglTerminate(display);
2067
2068 return glExtensions;
2069 }
2070
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002071 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
Jeff Change9467b22018-09-28 11:40:38 +08002072 PrintWriter pw, Configuration config, DisplayMetrics displayMetrics) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002073 long token = -1;
2074 if (protoOutputStream != null) {
2075 token = protoOutputStream.start(fieldId);
Jeff Change9467b22018-09-28 11:40:38 +08002076 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX,
2077 displayMetrics.widthPixels);
2078 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX,
2079 displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002080 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI,
2081 DisplayMetrics.DENSITY_DEVICE_STABLE);
2082 }
2083 if (pw != null) {
Jeff Change9467b22018-09-28 11:40:38 +08002084 pw.print("stable-width-px: "); pw.println(displayMetrics.widthPixels);
2085 pw.print("stable-height-px: "); pw.println(displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002086 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE);
2087 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002088
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002089 MemInfoReader memreader = new MemInfoReader();
2090 memreader.readMemInfo();
2091 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class);
2092 if (protoOutputStream != null) {
2093 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize());
2094 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM,
2095 ActivityManager.isLowRamDeviceStatic());
2096 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES,
2097 Runtime.getRuntime().availableProcessors());
2098 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK,
2099 kgm.isDeviceSecure());
2100 }
2101 if (pw != null) {
2102 pw.print("total-ram: "); pw.println(memreader.getTotalSize());
2103 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic());
2104 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors());
2105 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
2106 }
2107
Yunfan Chen75157d72018-07-27 14:47:21 +09002108 ConfigurationInfo configInfo = null;
2109 try {
2110 configInfo = mTaskInterface.getDeviceConfigurationInfo();
2111 } catch (RemoteException e) {
2112 throw e.rethrowFromSystemServer();
2113 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002114 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
2115 if (protoOutputStream != null) {
2116 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
2117 configInfo.reqGlEsVersion);
2118 }
2119 if (pw != null) {
2120 pw.print("opengl-version: 0x");
2121 pw.println(Integer.toHexString(configInfo.reqGlEsVersion));
2122 }
2123 }
2124
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002125 Set<String> glExtensionsSet = getGlExtensionsFromDriver();
2126 String[] glExtensions = new String[glExtensionsSet.size()];
2127 glExtensions = glExtensionsSet.toArray(glExtensions);
2128 Arrays.sort(glExtensions);
2129 for (int i = 0; i < glExtensions.length; i++) {
2130 if (protoOutputStream != null) {
2131 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
2132 glExtensions[i]);
2133 }
2134 if (pw != null) {
2135 pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
2136 }
2137
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002138 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002139
2140 PackageManager pm = mInternal.mContext.getPackageManager();
2141 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002142 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002143 for (int i = 0; i < slibs.size(); i++) {
2144 if (protoOutputStream != null) {
2145 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
2146 slibs.get(i).getName());
2147 }
2148 if (pw != null) {
2149 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName());
2150 }
2151 }
2152
2153 FeatureInfo[] features = pm.getSystemAvailableFeatures();
weijuncheng12030002018-10-30 14:07:53 +08002154 Arrays.sort(features, (o1, o2) -> {
2155 if (o1.name == o2.name) return 0;
2156 if (o1.name == null) return -1;
2157 if (o2.name == null) return 1;
2158 return o1.name.compareTo(o2.name);
2159 });
2160
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002161 for (int i = 0; i < features.length; i++) {
2162 if (features[i].name != null) {
2163 if (protoOutputStream != null) {
2164 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name);
2165 }
2166 if (pw != null) {
2167 pw.print("features: "); pw.println(features[i].name);
2168 }
2169 }
2170 }
2171
2172 if (protoOutputStream != null) {
2173 protoOutputStream.end(token);
2174 }
2175 }
2176
2177 int runGetConfig(PrintWriter pw) throws RemoteException {
2178 int days = -1;
Jeff Change9467b22018-09-28 11:40:38 +08002179 int displayId = Display.DEFAULT_DISPLAY;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002180 boolean asProto = false;
2181 boolean inclDevice = false;
2182
2183 String opt;
Jeff Change9467b22018-09-28 11:40:38 +08002184 while ((opt = getNextOption()) != null) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002185 if (opt.equals("--days")) {
2186 days = Integer.parseInt(getNextArgRequired());
2187 if (days <= 0) {
2188 throw new IllegalArgumentException("--days must be a positive integer");
2189 }
2190 } else if (opt.equals("--proto")) {
2191 asProto = true;
2192 } else if (opt.equals("--device")) {
2193 inclDevice = true;
Jeff Change9467b22018-09-28 11:40:38 +08002194 } else if (opt.equals("--display")) {
2195 displayId = Integer.parseInt(getNextArgRequired());
2196 if (displayId < 0) {
2197 throw new IllegalArgumentException("--display must be a non-negative integer");
2198 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002199 } else {
2200 getErrPrintWriter().println("Error: Unknown option: " + opt);
2201 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -07002202 }
2203 }
2204
2205 Configuration config = mInterface.getConfiguration();
2206 if (config == null) {
2207 getErrPrintWriter().println("Activity manager has no configuration");
2208 return -1;
2209 }
2210
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002211 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class);
Jeff Change9467b22018-09-28 11:40:38 +08002212 Display display = dm.getDisplay(displayId);
2213
2214 if (display == null) {
2215 getErrPrintWriter().println("Error: Display does not exist: " + displayId);
2216 return -1;
2217 }
2218
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002219 DisplayMetrics metrics = new DisplayMetrics();
2220 display.getMetrics(metrics);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002221
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002222 if (asProto) {
2223 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor());
2224 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics);
2225 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002226 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002227 }
2228 proto.flush();
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002229 } else {
2230 pw.println("config: " + Configuration.resourceQualifierString(config, metrics));
2231 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
2232 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002233 writeDeviceConfig(null, -1, pw, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002234 }
2235
2236 if (days >= 0) {
2237 final List<Configuration> recentConfigs = getRecentConfigurations(days);
2238 final int recentConfigSize = recentConfigs.size();
2239 if (recentConfigSize > 0) {
2240 pw.println("recentConfigs:");
2241 for (int i = 0; i < recentConfigSize; i++) {
2242 pw.println(" config: " + Configuration.resourceQualifierString(
2243 recentConfigs.get(i)));
2244 }
2245 }
2246 }
2247
Dianne Hackborn331084d2016-10-07 17:57:00 -07002248 }
2249 return 0;
2250 }
2251
2252 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
2253 boolean suppress = Boolean.valueOf(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002254 mTaskInterface.suppressResizeConfigChanges(suppress);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002255 return 0;
2256 }
2257
2258 int runSetInactive(PrintWriter pw) throws RemoteException {
2259 int userId = UserHandle.USER_CURRENT;
2260
2261 String opt;
2262 while ((opt=getNextOption()) != null) {
2263 if (opt.equals("--user")) {
2264 userId = UserHandle.parseUserArg(getNextArgRequired());
2265 } else {
2266 getErrPrintWriter().println("Error: Unknown option: " + opt);
2267 return -1;
2268 }
2269 }
2270 String packageName = getNextArgRequired();
2271 String value = getNextArgRequired();
2272
2273 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2274 Context.USAGE_STATS_SERVICE));
2275 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId);
2276 return 0;
2277 }
2278
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002279 private int bucketNameToBucketValue(String name) {
2280 String lower = name.toLowerCase();
2281 if (lower.startsWith("ac")) {
2282 return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
2283 } else if (lower.startsWith("wo")) {
2284 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
2285 } else if (lower.startsWith("fr")) {
2286 return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
2287 } else if (lower.startsWith("ra")) {
2288 return UsageStatsManager.STANDBY_BUCKET_RARE;
2289 } else if (lower.startsWith("ne")) {
2290 return UsageStatsManager.STANDBY_BUCKET_NEVER;
2291 } else {
2292 try {
2293 int bucket = Integer.parseInt(lower);
2294 return bucket;
2295 } catch (NumberFormatException nfe) {
2296 getErrPrintWriter().println("Error: Unknown bucket: " + name);
2297 }
2298 }
2299 return -1;
2300 }
2301
Amith Yamasani17fffee2017-09-29 13:17:43 -07002302 int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
2303 int userId = UserHandle.USER_CURRENT;
2304
2305 String opt;
2306 while ((opt=getNextOption()) != null) {
2307 if (opt.equals("--user")) {
2308 userId = UserHandle.parseUserArg(getNextArgRequired());
2309 } else {
2310 getErrPrintWriter().println("Error: Unknown option: " + opt);
2311 return -1;
2312 }
2313 }
2314 String packageName = getNextArgRequired();
2315 String value = getNextArgRequired();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002316 int bucket = bucketNameToBucketValue(value);
2317 if (bucket < 0) return -1;
Amith Yamasanie8789312017-12-10 14:34:26 -08002318 boolean multiple = peekNextArg() != null;
2319
Amith Yamasani17fffee2017-09-29 13:17:43 -07002320
2321 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2322 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002323 if (!multiple) {
2324 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
2325 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002326 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
2327 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002328 while ((packageName = getNextArg()) != null) {
2329 value = getNextArgRequired();
2330 bucket = bucketNameToBucketValue(value);
2331 if (bucket < 0) continue;
Suprabh Shukla868bde22018-02-20 20:59:52 -08002332 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002333 }
Suprabh Shukla868bde22018-02-20 20:59:52 -08002334 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
2335 usm.setAppStandbyBuckets(slice, userId);
Amith Yamasanie8789312017-12-10 14:34:26 -08002336 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002337 return 0;
2338 }
2339
2340 int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
2341 int userId = UserHandle.USER_CURRENT;
2342
2343 String opt;
2344 while ((opt=getNextOption()) != null) {
2345 if (opt.equals("--user")) {
2346 userId = UserHandle.parseUserArg(getNextArgRequired());
2347 } else {
2348 getErrPrintWriter().println("Error: Unknown option: " + opt);
2349 return -1;
2350 }
2351 }
Amith Yamasanie8789312017-12-10 14:34:26 -08002352 String packageName = getNextArg();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002353
2354 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2355 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002356 if (packageName != null) {
2357 int bucket = usm.getAppStandbyBucket(packageName, null, userId);
2358 pw.println(bucket);
2359 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002360 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -08002361 SHELL_PACKAGE_NAME, userId);
Suprabh Shukla868bde22018-02-20 20:59:52 -08002362 for (AppStandbyInfo bucketInfo : buckets.getList()) {
2363 pw.print(bucketInfo.mPackageName); pw.print(": ");
2364 pw.println(bucketInfo.mStandbyBucket);
Amith Yamasanie8789312017-12-10 14:34:26 -08002365 }
2366 }
Amith Yamasani17fffee2017-09-29 13:17:43 -07002367 return 0;
2368 }
2369
Dianne Hackborn331084d2016-10-07 17:57:00 -07002370 int runGetInactive(PrintWriter pw) throws RemoteException {
2371 int userId = UserHandle.USER_CURRENT;
2372
2373 String opt;
2374 while ((opt=getNextOption()) != null) {
2375 if (opt.equals("--user")) {
2376 userId = UserHandle.parseUserArg(getNextArgRequired());
2377 } else {
2378 getErrPrintWriter().println("Error: Unknown option: " + opt);
2379 return -1;
2380 }
2381 }
2382 String packageName = getNextArgRequired();
2383
2384 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2385 Context.USAGE_STATS_SERVICE));
2386 boolean isIdle = usm.isAppInactive(packageName, userId);
2387 pw.println("Idle=" + isIdle);
2388 return 0;
2389 }
2390
2391 int runSendTrimMemory(PrintWriter pw) throws RemoteException {
2392 int userId = UserHandle.USER_CURRENT;
2393 String opt;
2394 while ((opt = getNextOption()) != null) {
2395 if (opt.equals("--user")) {
2396 userId = UserHandle.parseUserArg(getNextArgRequired());
2397 if (userId == UserHandle.USER_ALL) {
2398 getErrPrintWriter().println("Error: Can't use user 'all'");
2399 return -1;
2400 }
2401 } else {
2402 getErrPrintWriter().println("Error: Unknown option: " + opt);
2403 return -1;
2404 }
2405 }
2406
2407 String proc = getNextArgRequired();
2408 String levelArg = getNextArgRequired();
2409 int level;
2410 switch (levelArg) {
2411 case "HIDDEN":
2412 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
2413 break;
2414 case "RUNNING_MODERATE":
2415 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
2416 break;
2417 case "BACKGROUND":
2418 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
2419 break;
2420 case "RUNNING_LOW":
2421 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
2422 break;
2423 case "MODERATE":
2424 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
2425 break;
2426 case "RUNNING_CRITICAL":
2427 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
2428 break;
2429 case "COMPLETE":
2430 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
2431 break;
2432 default:
Dianne Hackborne51505a2017-08-07 17:13:52 -07002433 try {
2434 level = Integer.parseInt(levelArg);
2435 } catch (NumberFormatException e) {
2436 getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
2437 return -1;
2438 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002439 }
2440 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
2441 getErrPrintWriter().println("Unknown error: failed to set trim level");
2442 return -1;
2443 }
2444 return 0;
2445 }
2446
Andrii Kulian839def92016-11-02 10:58:58 -07002447 int runDisplay(PrintWriter pw) throws RemoteException {
2448 String op = getNextArgRequired();
2449 switch (op) {
2450 case "move-stack":
2451 return runDisplayMoveStack(pw);
2452 default:
2453 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2454 return -1;
2455 }
2456 }
2457
Dianne Hackborn331084d2016-10-07 17:57:00 -07002458 int runStack(PrintWriter pw) throws RemoteException {
2459 String op = getNextArgRequired();
2460 switch (op) {
Andrii Kulian839def92016-11-02 10:58:58 -07002461 case "move-task":
Dianne Hackborn331084d2016-10-07 17:57:00 -07002462 return runStackMoveTask(pw);
2463 case "resize":
2464 return runStackResize(pw);
2465 case "resize-animated":
2466 return runStackResizeAnimated(pw);
2467 case "resize-docked-stack":
2468 return runStackResizeDocked(pw);
2469 case "positiontask":
2470 return runStackPositionTask(pw);
2471 case "list":
2472 return runStackList(pw);
2473 case "info":
2474 return runStackInfo(pw);
2475 case "move-top-activity-to-pinned-stack":
2476 return runMoveTopActivityToPinnedStack(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002477 case "remove":
2478 return runStackRemove(pw);
2479 default:
2480 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2481 return -1;
2482 }
2483 }
2484
2485
2486 private Rect getBounds() {
2487 String leftStr = getNextArgRequired();
2488 int left = Integer.parseInt(leftStr);
2489 String topStr = getNextArgRequired();
2490 int top = Integer.parseInt(topStr);
2491 String rightStr = getNextArgRequired();
2492 int right = Integer.parseInt(rightStr);
2493 String bottomStr = getNextArgRequired();
2494 int bottom = Integer.parseInt(bottomStr);
2495 if (left < 0) {
2496 getErrPrintWriter().println("Error: bad left arg: " + leftStr);
2497 return null;
2498 }
2499 if (top < 0) {
2500 getErrPrintWriter().println("Error: bad top arg: " + topStr);
2501 return null;
2502 }
2503 if (right <= 0) {
2504 getErrPrintWriter().println("Error: bad right arg: " + rightStr);
2505 return null;
2506 }
2507 if (bottom <= 0) {
2508 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr);
2509 return null;
2510 }
2511 return new Rect(left, top, right, bottom);
2512 }
2513
Andrii Kulian839def92016-11-02 10:58:58 -07002514 int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
2515 String stackIdStr = getNextArgRequired();
2516 int stackId = Integer.parseInt(stackIdStr);
2517 String displayIdStr = getNextArgRequired();
2518 int displayId = Integer.parseInt(displayIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002519 mTaskInterface.moveStackToDisplay(stackId, displayId);
Andrii Kulian839def92016-11-02 10:58:58 -07002520 return 0;
2521 }
2522
Dianne Hackborn331084d2016-10-07 17:57:00 -07002523 int runStackMoveTask(PrintWriter pw) throws RemoteException {
2524 String taskIdStr = getNextArgRequired();
2525 int taskId = Integer.parseInt(taskIdStr);
2526 String stackIdStr = getNextArgRequired();
2527 int stackId = Integer.parseInt(stackIdStr);
2528 String toTopStr = getNextArgRequired();
2529 final boolean toTop;
2530 if ("true".equals(toTopStr)) {
2531 toTop = true;
2532 } else if ("false".equals(toTopStr)) {
2533 toTop = false;
2534 } else {
2535 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr);
2536 return -1;
2537 }
2538
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002539 mTaskInterface.moveTaskToStack(taskId, stackId, toTop);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002540 return 0;
2541 }
2542
2543 int runStackResize(PrintWriter pw) throws RemoteException {
2544 String stackIdStr = getNextArgRequired();
2545 int stackId = Integer.parseInt(stackIdStr);
2546 final Rect bounds = getBounds();
2547 if (bounds == null) {
2548 getErrPrintWriter().println("Error: invalid input bounds");
2549 return -1;
2550 }
2551 return resizeStack(stackId, bounds, 0);
2552 }
2553
2554 int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
2555 String stackIdStr = getNextArgRequired();
2556 int stackId = Integer.parseInt(stackIdStr);
2557 final Rect bounds;
2558 if ("null".equals(peekNextArg())) {
2559 bounds = null;
2560 } else {
2561 bounds = getBounds();
2562 if (bounds == null) {
2563 getErrPrintWriter().println("Error: invalid input bounds");
2564 return -1;
2565 }
2566 }
2567 return resizeStackUnchecked(stackId, bounds, 0, true);
2568 }
2569
2570 int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate)
2571 throws RemoteException {
2572 try {
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002573 mTaskInterface.resizeStack(stackId, bounds, false, false, animate, -1);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002574 Thread.sleep(delayMs);
2575 } catch (InterruptedException e) {
2576 }
2577 return 0;
2578 }
2579
2580 int runStackResizeDocked(PrintWriter pw) throws RemoteException {
2581 final Rect bounds = getBounds();
2582 final Rect taskBounds = getBounds();
2583 if (bounds == null || taskBounds == null) {
2584 getErrPrintWriter().println("Error: invalid input bounds");
2585 return -1;
2586 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002587 mTaskInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002588 return 0;
2589 }
2590
2591 int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException {
2592 if (bounds == null) {
2593 getErrPrintWriter().println("Error: invalid input bounds");
2594 return -1;
2595 }
2596 return resizeStackUnchecked(stackId, bounds, delayMs, false);
2597 }
2598
2599 int runStackPositionTask(PrintWriter pw) throws RemoteException {
2600 String taskIdStr = getNextArgRequired();
2601 int taskId = Integer.parseInt(taskIdStr);
2602 String stackIdStr = getNextArgRequired();
2603 int stackId = Integer.parseInt(stackIdStr);
2604 String positionStr = getNextArgRequired();
2605 int position = Integer.parseInt(positionStr);
2606
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002607 mTaskInterface.positionTaskInStack(taskId, stackId, position);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002608 return 0;
2609 }
2610
2611 int runStackList(PrintWriter pw) throws RemoteException {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002612 List<ActivityManager.StackInfo> stacks = mTaskInterface.getAllStackInfos();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002613 for (ActivityManager.StackInfo info : stacks) {
2614 pw.println(info);
2615 }
2616 return 0;
2617 }
2618
2619 int runStackInfo(PrintWriter pw) throws RemoteException {
Wale Ogunwale68278562017-09-23 17:13:55 -07002620 int windowingMode = Integer.parseInt(getNextArgRequired());
2621 int activityType = Integer.parseInt(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002622 ActivityManager.StackInfo info = mTaskInterface.getStackInfo(windowingMode, activityType);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002623 pw.println(info);
2624 return 0;
2625 }
2626
2627 int runStackRemove(PrintWriter pw) throws RemoteException {
2628 String stackIdStr = getNextArgRequired();
2629 int stackId = Integer.parseInt(stackIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002630 mTaskInterface.removeStack(stackId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002631 return 0;
2632 }
2633
2634 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException {
2635 int stackId = Integer.parseInt(getNextArgRequired());
2636 final Rect bounds = getBounds();
2637 if (bounds == null) {
2638 getErrPrintWriter().println("Error: invalid input bounds");
2639 return -1;
2640 }
2641
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002642 if (!mTaskInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -07002643 getErrPrintWriter().println("Didn't move top activity to pinned stack.");
2644 return -1;
2645 }
2646 return 0;
2647 }
2648
Dianne Hackborn331084d2016-10-07 17:57:00 -07002649 void setBoundsSide(Rect bounds, String side, int value) {
2650 switch (side) {
2651 case "l":
2652 bounds.left = value;
2653 break;
2654 case "r":
2655 bounds.right = value;
2656 break;
2657 case "t":
2658 bounds.top = value;
2659 break;
2660 case "b":
2661 bounds.bottom = value;
2662 break;
2663 default:
2664 getErrPrintWriter().println("Unknown set side: " + side);
2665 break;
2666 }
2667 }
2668
2669 int runTask(PrintWriter pw) throws RemoteException {
2670 String op = getNextArgRequired();
2671 if (op.equals("lock")) {
2672 return runTaskLock(pw);
2673 } else if (op.equals("resizeable")) {
2674 return runTaskResizeable(pw);
2675 } else if (op.equals("resize")) {
2676 return runTaskResize(pw);
David Stevensee9e2772017-02-09 16:30:27 -08002677 } else if (op.equals("focus")) {
2678 return runTaskFocus(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002679 } else {
2680 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2681 return -1;
2682 }
2683 }
2684
2685 int runTaskLock(PrintWriter pw) throws RemoteException {
2686 String taskIdStr = getNextArgRequired();
2687 if (taskIdStr.equals("stop")) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002688 mTaskInterface.stopSystemLockTaskMode();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002689 } else {
2690 int taskId = Integer.parseInt(taskIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002691 mTaskInterface.startSystemLockTaskMode(taskId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002692 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002693 pw.println("Activity manager is " + (mTaskInterface.isInLockTaskMode() ? "" : "not ") +
Dianne Hackborn331084d2016-10-07 17:57:00 -07002694 "in lockTaskMode");
2695 return 0;
2696 }
2697
2698 int runTaskResizeable(PrintWriter pw) throws RemoteException {
2699 final String taskIdStr = getNextArgRequired();
2700 final int taskId = Integer.parseInt(taskIdStr);
2701 final String resizeableStr = getNextArgRequired();
2702 final int resizeableMode = Integer.parseInt(resizeableStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002703 mTaskInterface.setTaskResizeable(taskId, resizeableMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002704 return 0;
2705 }
2706
2707 int runTaskResize(PrintWriter pw) throws RemoteException {
2708 final String taskIdStr = getNextArgRequired();
2709 final int taskId = Integer.parseInt(taskIdStr);
2710 final Rect bounds = getBounds();
2711 if (bounds == null) {
2712 getErrPrintWriter().println("Error: invalid input bounds");
2713 return -1;
2714 }
2715 taskResize(taskId, bounds, 0, false);
2716 return 0;
2717 }
2718
2719 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
2720 throws RemoteException {
2721 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002722 mTaskInterface.resizeTask(taskId, bounds, resizeMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002723 try {
2724 Thread.sleep(delay_ms);
2725 } catch (InterruptedException e) {
2726 }
2727 }
2728
Dianne Hackborn331084d2016-10-07 17:57:00 -07002729 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
2730 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
2731 throws RemoteException {
2732 int maxMove;
2733 if (movingForward) {
2734 while (maxToTravel > 0
2735 && ((horizontal && taskRect.right < stackRect.right)
2736 ||(!horizontal && taskRect.bottom < stackRect.bottom))) {
2737 if (horizontal) {
2738 maxMove = Math.min(stepSize, stackRect.right - taskRect.right);
2739 maxToTravel -= maxMove;
2740 taskRect.right += maxMove;
2741 taskRect.left += maxMove;
2742 } else {
2743 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom);
2744 maxToTravel -= maxMove;
2745 taskRect.top += maxMove;
2746 taskRect.bottom += maxMove;
2747 }
2748 taskResize(taskId, taskRect, delay_ms, false);
2749 }
2750 } else {
2751 while (maxToTravel < 0
2752 && ((horizontal && taskRect.left > stackRect.left)
2753 ||(!horizontal && taskRect.top > stackRect.top))) {
2754 if (horizontal) {
2755 maxMove = Math.min(stepSize, taskRect.left - stackRect.left);
2756 maxToTravel -= maxMove;
2757 taskRect.right -= maxMove;
2758 taskRect.left -= maxMove;
2759 } else {
2760 maxMove = Math.min(stepSize, taskRect.top - stackRect.top);
2761 maxToTravel -= maxMove;
2762 taskRect.top -= maxMove;
2763 taskRect.bottom -= maxMove;
2764 }
2765 taskResize(taskId, taskRect, delay_ms, false);
2766 }
2767 }
2768 // Return the remaining distance we didn't travel because we reached the target location.
2769 return maxToTravel;
2770 }
2771
2772 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) {
2773 int stepSize = 0;
2774 if (greaterThanTarget && target < current) {
2775 current -= inStepSize;
2776 stepSize = inStepSize;
2777 if (target > current) {
2778 stepSize -= (target - current);
2779 }
2780 }
2781 if (!greaterThanTarget && target > current) {
2782 current += inStepSize;
2783 stepSize = inStepSize;
2784 if (target < current) {
2785 stepSize += (current - target);
2786 }
2787 }
2788 return stepSize;
2789 }
2790
David Stevensee9e2772017-02-09 16:30:27 -08002791 int runTaskFocus(PrintWriter pw) throws RemoteException {
2792 final int taskId = Integer.parseInt(getNextArgRequired());
2793 pw.println("Setting focus to task " + taskId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002794 mTaskInterface.setFocusedTask(taskId);
David Stevensee9e2772017-02-09 16:30:27 -08002795 return 0;
2796 }
2797
Dianne Hackborn331084d2016-10-07 17:57:00 -07002798 int runWrite(PrintWriter pw) {
2799 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2800 "registerUidObserver()");
Wale Ogunwaled7889f52018-10-25 11:03:20 -07002801 mInternal.mAtmInternal.flushRecentTasks();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002802 pw.println("All tasks persisted.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002803 return 0;
2804 }
2805
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002806 int runAttachAgent(PrintWriter pw) {
2807 // TODO: revisit the permissions required for attaching agents
2808 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2809 "attach-agent");
2810 String process = getNextArgRequired();
2811 String agent = getNextArgRequired();
2812 String opt;
2813 if ((opt = getNextArg()) != null) {
2814 pw.println("Error: Unknown option: " + opt);
2815 return -1;
2816 }
2817 mInternal.attachAgent(process, agent);
2818 return 0;
2819 }
2820
Michael Kwan94438b72016-11-03 15:30:34 -07002821 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
Matthew Ng626e0cc2016-12-07 17:25:53 -08002822 final Resources res = getResources(pw);
2823 if (res == null) {
2824 return -1;
2825 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002826 pw.println(ActivityTaskManager.supportsMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002827 return 0;
2828 }
2829
2830 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException {
2831 final Resources res = getResources(pw);
2832 if (res == null) {
2833 return -1;
2834 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002835 pw.println(ActivityTaskManager.supportsSplitScreenMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002836 return 0;
2837 }
2838
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002839 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
2840 int userid = UserHandle.parseUserArg(getNextArgRequired());
2841 ArrayList<String> packages = new ArrayList<>();
2842 packages.add(getNextArgRequired());
2843 String packageName;
2844 while ((packageName = getNextArg()) != null) {
2845 packages.add(packageName);
2846 }
2847 mInternal.scheduleApplicationInfoChanged(packages, userid);
2848 pw.println("Packages updated with most recent ApplicationInfos.");
2849 return 0;
2850 }
2851
Arthur Hsuf3f3a602017-02-21 14:01:53 -08002852 int runNoHomeScreen(PrintWriter pw) throws RemoteException {
2853 final Resources res = getResources(pw);
2854 if (res == null) {
2855 return -1;
2856 }
2857 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen));
2858 return 0;
2859 }
2860
Jeff Sharkeyfd658132017-05-03 11:38:01 -06002861 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
2862 mInternal.waitForBroadcastIdle(pw);
2863 return 0;
2864 }
2865
Matthew Ng626e0cc2016-12-07 17:25:53 -08002866 private Resources getResources(PrintWriter pw) throws RemoteException {
Michael Kwan94438b72016-11-03 15:30:34 -07002867 // system resources does not contain all the device configuration, construct it manually.
2868 Configuration config = mInterface.getConfiguration();
2869 if (config == null) {
2870 pw.println("Error: Activity manager has no configuration");
Matthew Ng626e0cc2016-12-07 17:25:53 -08002871 return null;
Michael Kwan94438b72016-11-03 15:30:34 -07002872 }
2873
2874 final DisplayMetrics metrics = new DisplayMetrics();
2875 metrics.setToDefaults();
2876
Matthew Ng626e0cc2016-12-07 17:25:53 -08002877 return new Resources(AssetManager.getSystem(), metrics, config);
Michael Kwan94438b72016-11-03 15:30:34 -07002878 }
2879
Dianne Hackborn2e441072015-10-28 18:00:57 -07002880 @Override
2881 public void onHelp() {
2882 PrintWriter pw = getOutPrintWriter();
2883 dumpHelp(pw, mDumping);
2884 }
2885
2886 static void dumpHelp(PrintWriter pw, boolean dumping) {
2887 if (dumping) {
2888 pw.println("Activity manager dump options:");
2889 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
2890 pw.println(" WHAT may be one of:");
2891 pw.println(" a[ctivities]: activity stack state");
2892 pw.println(" r[recents]: recent activities state");
2893 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002894 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002895 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
2896 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
2897 pw.println(" o[om]: out of memory management");
2898 pw.println(" perm[issions]: URI permission grant state");
2899 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
2900 pw.println(" provider [COMP_SPEC]: provider client-side state");
2901 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborn769b2e72018-12-05 08:51:20 -08002902 pw.println(" allowed-associations: current package association restrictions");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002903 pw.println(" as[sociations]: tracked app associations");
Dianne Hackborna631d562018-11-20 15:58:15 -08002904 pw.println(" lmk: stats on low memory killer");
2905 pw.println(" lru: raw LRU process list");
2906 pw.println(" binder-proxies: stats on binder objects and IPCs");
Dianne Hackborn0ef403e2017-01-24 18:22:15 -08002907 pw.println(" settings: currently applied config settings");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002908 pw.println(" service [COMP_SPEC]: service client-side state");
2909 pw.println(" package [PACKAGE_NAME]: all state related to given package");
2910 pw.println(" all: dump all activities");
2911 pw.println(" top: dump the top activity");
2912 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
2913 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
2914 pw.println(" a partial substring in a component name, a");
2915 pw.println(" hex object identifier.");
2916 pw.println(" -a: include all available server state.");
2917 pw.println(" -c: include client state.");
2918 pw.println(" -p: limit output to given package.");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002919 pw.println(" --checkin: output checkin format, resetting data.");
2920 pw.println(" --C: output checkin format, not resetting data.");
Steven Timotius4346f0a2017-09-12 11:07:21 -07002921 pw.println(" --proto: output dump in protocol buffer format.");
Felipe Lemeb546ca72018-08-15 08:44:12 -07002922 pw.println(" --autofill: dump just the autofill-related state of an activity");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002923 } else {
2924 pw.println("Activity manager (activity) commands:");
2925 pw.println(" help");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002926 pw.println(" Print this help text.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002927 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002928 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002929 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002930 pw.println(" Start an Activity. Options are:");
2931 pw.println(" -D: enable debugging");
2932 pw.println(" -N: enable native debugging");
2933 pw.println(" -W: wait for launch to complete");
2934 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>");
2935 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2936 pw.println(" between samples (use with --start-profiler)");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002937 pw.println(" --streaming: stream the profiling output to the specified file");
2938 pw.println(" (use with --start-profiler)");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002939 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
Andreas Gampe83085bb2017-06-26 17:54:11 -07002940 pw.println(" --attach-agent <agent>: attach the given agent before binding");
Andreas Gampeab8a63b2018-01-05 13:55:15 -08002941 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002942 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
2943 pw.println(" the top activity will be finished.");
2944 pw.println(" -S: force stop the target app before starting the activity");
2945 pw.println(" --track-allocation: enable tracking of object allocations");
2946 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2947 pw.println(" specified then run as the current user.");
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002948 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into.");
2949 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
Louis Changf379f802018-07-13 09:41:28 +08002950 pw.println(" --display <DISPLAY_ID>: The display to launch the activity into.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002951 pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
2952 pw.println(" Start a Service. Options are:");
2953 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2954 pw.println(" specified then run as the current user.");
Jaewan Kim329b35f2017-04-11 11:19:49 +09002955 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
2956 pw.println(" Start a foreground Service. Options are:");
2957 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2958 pw.println(" specified then run as the current user.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002959 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
2960 pw.println(" Stop a Service. Options are:");
2961 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2962 pw.println(" specified then run as the current user.");
2963 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>");
2964 pw.println(" Send a broadcast Intent. Options are:");
2965 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not");
2966 pw.println(" specified then send to all users.");
2967 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002968 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
David Brazdild5d42172018-02-14 19:39:03 +00002969 pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07002970 pw.println(" [--no-isolated-storage]");
Dianne Hackborn28824062016-10-18 13:19:20 -07002971 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
2972 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
2973 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
2974 pw.println(" is only one instrumentation. Options are:");
2975 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with");
2976 pw.println(" [-e perf true] to generate raw output for performance measurements.");
2977 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a");
2978 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]].");
2979 pw.println(" -p <FILE>: write profiling data to <FILE>");
Mike Mad2239822017-10-31 12:30:42 -07002980 pw.println(" -m: Write output as protobuf to stdout (machine readable)");
2981 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine");
2982 pw.println(" readable). If path is not specified, default directory and file name will");
2983 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto");
Dianne Hackborn28824062016-10-18 13:19:20 -07002984 pw.println(" -w: wait for instrumentation to finish before returning. Required for");
2985 pw.println(" test runners.");
2986 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
2987 pw.println(" current user if not specified.");
David Brazdild5d42172018-02-14 19:39:03 +00002988 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07002989 pw.println(" --no-isolated-storage: don't use isolated storage sandbox and ");
2990 pw.println(" mount full external storage");
Dianne Hackborn28824062016-10-18 13:19:20 -07002991 pw.println(" --no-window-animation: turn off window animations while running.");
2992 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
2993 pw.println(" This assumes that the process supports the selected ABI.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002994 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]");
2995 pw.println(" Trace IPC transactions.");
2996 pw.println(" start: start tracing IPC transactions.");
2997 pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
2998 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
2999 pw.println(" profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08003000 pw.println(" [--streaming] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003001 pw.println(" Start and stop profiler on a process. The given <PROCESS> argument");
3002 pw.println(" may be either a process name or pid. Options are:");
3003 pw.println(" --user <USER_ID> | current: When supplying a process name,");
3004 pw.println(" specify user of process to profile; uses current user if not specified.");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08003005 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
3006 pw.println(" between samples");
3007 pw.println(" --streaming: stream the profiling output to the specified file");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07003008 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003009 pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
3010 pw.println(" be either a process name or pid. Options are:");
3011 pw.println(" -n: dump native heap instead of managed heap");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07003012 pw.println(" -g: force GC before dumping the heap");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003013 pw.println(" --user <USER_ID> | current: When supplying a process name,");
3014 pw.println(" specify user of process to dump; uses current user if not specified.");
3015 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>");
3016 pw.println(" Set application <PACKAGE> to debug. Options are:");
3017 pw.println(" -w: wait for debugger when application starts");
3018 pw.println(" --persistent: retain this value");
3019 pw.println(" clear-debug-app");
3020 pw.println(" Clear the previously set-debug-app.");
3021 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>");
3022 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or");
3023 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
3024 pw.println(" clear-watch-heap");
3025 pw.println(" Clear the previously set-watch-heap.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08003026 pw.println(" bug-report [--progress | --telephony]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003027 pw.println(" Request bug report generation; will launch a notification");
3028 pw.println(" when done to select where it should be delivered. Options are:");
3029 pw.println(" --progress: will launch a notification right away to show its progress.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08003030 pw.println(" --telephony: will dump only telephony sections.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003031 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003032 pw.println(" Completely stop the given application package.");
Christopher Tate8aa8fe12017-01-20 17:50:32 -08003033 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>");
3034 pw.println(" Induce a VM crash in the specified package or process");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003035 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
Makoto Onuki6569c362018-02-27 15:52:01 -08003036 pw.println(" Kill all background processes associated with the given application.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003037 pw.println(" kill-all");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003038 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn85e35642017-01-12 15:10:57 -08003039 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
3040 pw.println(" If the given application's uid is in the background and waiting to");
3041 pw.println(" become idle (not allowing background services), do that now.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003042 pw.println(" monitor [--gdb <port>]");
3043 pw.println(" Start monitoring for crashes or ANRs.");
3044 pw.println(" --gdb: start gdbserv on the given port at crash/ANR");
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07003045 pw.println(" watch-uids [--oom <uid>]");
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01003046 pw.println(" Start watching for and reporting uid state changes.");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003047 pw.println(" --oom: specify a uid for which to report detailed change messages.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003048 pw.println(" hang [--allow-restart]");
3049 pw.println(" Hang the system.");
3050 pw.println(" --allow-restart: allow watchdog to perform normal system restart");
3051 pw.println(" restart");
3052 pw.println(" Restart the user-space system.");
3053 pw.println(" idle-maintenance");
3054 pw.println(" Perform idle maintenance now.");
3055 pw.println(" screen-compat [on|off] <PACKAGE>");
3056 pw.println(" Control screen compatibility mode of <PACKAGE>.");
3057 pw.println(" package-importance <PACKAGE>");
3058 pw.println(" Print current importance of <PACKAGE>.");
3059 pw.println(" to-uri [INTENT]");
3060 pw.println(" Print the given Intent specification as a URI.");
3061 pw.println(" to-intent-uri [INTENT]");
3062 pw.println(" Print the given Intent specification as an intent: URI.");
3063 pw.println(" to-app-uri [INTENT]");
3064 pw.println(" Print the given Intent specification as an android-app: URI.");
3065 pw.println(" switch-user <USER_ID>");
3066 pw.println(" Switch to put USER_ID in the foreground, starting");
3067 pw.println(" execution of that user if it is currently stopped.");
3068 pw.println(" get-current-user");
3069 pw.println(" Returns id of the current foreground user.");
Bookatz03bfe6f2019-03-01 15:46:04 -08003070 pw.println(" start-user [-w] <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003071 pw.println(" Start USER_ID in background if it is currently stopped;");
Bookatz03bfe6f2019-03-01 15:46:04 -08003072 pw.println(" use switch-user if you want to start the user in foreground.");
3073 pw.println(" -w: wait for start-user to complete and the user to be unlocked.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003074 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]");
3075 pw.println(" Attempt to unlock the given user using the given authorization token.");
3076 pw.println(" stop-user [-w] [-f] <USER_ID>");
3077 pw.println(" Stop execution of USER_ID, not allowing it to run any");
3078 pw.println(" code until a later explicit start or switch to it.");
3079 pw.println(" -w: wait for stop-user to complete.");
3080 pw.println(" -f: force stop even if there are related users that cannot be stopped.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003081 pw.println(" is-user-stopped <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003082 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07003083 pw.println(" get-started-user-state <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003084 pw.println(" Gets the current state of the given started user.");
3085 pw.println(" track-associations");
3086 pw.println(" Enable association tracking.");
3087 pw.println(" untrack-associations");
3088 pw.println(" Disable and clear association tracking.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003089 pw.println(" get-uid-state <UID>");
3090 pw.println(" Gets the process state of an app given its <UID>.");
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07003091 pw.println(" attach-agent <PROCESS> <FILE>");
3092 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 +08003093 pw.println(" get-config [--days N] [--device] [--proto] [--display <DISPLAY_ID>]");
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08003094 pw.println(" Retrieve the configuration and any recent configurations of the device.");
3095 pw.println(" --days: also return last N days of configurations that have been seen.");
3096 pw.println(" --device: also output global device configuration info.");
3097 pw.println(" --proto: return result as a proto; does not include --days info.");
Jeff Change9467b22018-09-28 11:40:38 +08003098 pw.println(" --display: Specify for which display to run the command; if not ");
3099 pw.println(" specified then run for the default display.");
Michael Kwan94438b72016-11-03 15:30:34 -07003100 pw.println(" supports-multiwindow");
3101 pw.println(" Returns true if the device supports multiwindow.");
Matthew Ng626e0cc2016-12-07 17:25:53 -08003102 pw.println(" supports-split-screen-multi-window");
3103 pw.println(" Returns true if the device supports split screen multiwindow.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003104 pw.println(" suppress-resize-config-changes <true|false>");
3105 pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
3106 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
3107 pw.println(" Sets the inactive state of an app.");
3108 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
3109 pw.println(" Returns the inactive state of an app.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003110 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
Amith Yamasani17fffee2017-09-29 13:17:43 -07003111 pw.println(" Puts an app in the standby bucket.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003112 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
3113 pw.println(" Returns the standby bucket of an app.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003114 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
3115 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003116 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 -07003117 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays.");
3118 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>");
3119 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003120 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
Andrii Kulian839def92016-11-02 10:58:58 -07003121 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003122 pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
3123 pw.println(" bottom (false) of <STACK_ID>.");
3124 pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3125 pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.");
3126 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3127 pw.println(" Same as resize, but allow animation.");
3128 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
3129 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
3130 pw.println(" and supplying temporary different task bounds indicated by");
3131 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003132 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3133 pw.println(" Moves the top activity from");
3134 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
3135 pw.println(" bounds of the pinned stack.");
3136 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>");
3137 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
3138 pw.println(" list");
3139 pw.println(" List all of the activity stacks and their sizes.");
Wale Ogunwale68278562017-09-23 17:13:55 -07003140 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
3141 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003142 pw.println(" remove <STACK_ID>");
3143 pw.println(" Remove stack <STACK_ID>.");
3144 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
3145 pw.println(" lock <TASK_ID>");
3146 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run.");
3147 pw.println(" lock stop");
3148 pw.println(" End the current task lock.");
3149 pw.println(" resizeable <TASK_ID> [0|1|2|3]");
3150 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:");
3151 pw.println(" 0: unresizeable");
3152 pw.println(" 1: crop_windows");
3153 pw.println(" 2: resizeable");
3154 pw.println(" 3: resizeable_and_pipable");
3155 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3156 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
3157 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
3158 pw.println(" has the specified bounds.");
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01003159 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
3160 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
3161 pw.println(" without restarting any processes.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003162 pw.println(" write");
3163 pw.println(" Write all pending state to storage.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003164 pw.println();
3165 Intent.printIntentArgsHelp(pw, "");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003166 }
3167 }
3168}