blob: c0e98cd9b30a406bd1e2f6c62d42acf4738c7562 [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 An494d4fe2019-04-02 09:00:22 -070019import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
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;
Alan Stokesc76767c2019-05-30 09:33:47 +010032import android.app.BroadcastOptions;
Dianne Hackborn331084d2016-10-07 17:57:00 -070033import android.app.IActivityController;
Dianne Hackborn2e441072015-10-28 18:00:57 -070034import android.app.IActivityManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070035import android.app.IActivityTaskManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070036import android.app.IStopUserCallback;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +010037import android.app.IUidObserver;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080038import android.app.KeyguardManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070039import android.app.ProfilerInfo;
jovanake2043612019-10-31 16:49:24 -070040import android.app.UserSwitchObserver;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070041import android.app.WaitResult;
Suprabh Shukla868bde22018-02-20 20:59:52 -080042import android.app.usage.AppStandbyInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070043import android.app.usage.ConfigurationStats;
44import android.app.usage.IUsageStatsManager;
45import android.app.usage.UsageStatsManager;
atrostf69bbe12019-11-06 16:00:38 +000046import android.compat.Compatibility;
Dianne Hackborn331084d2016-10-07 17:57:00 -070047import android.content.ComponentCallbacks2;
48import android.content.ComponentName;
49import android.content.Context;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080050import android.content.DeviceConfigurationProto;
51import android.content.GlobalConfigurationProto;
Dianne Hackborn331084d2016-10-07 17:57:00 -070052import android.content.IIntentReceiver;
Dianne Hackborn354736e2016-08-22 17:00:05 -070053import android.content.Intent;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080054import android.content.pm.ConfigurationInfo;
55import android.content.pm.FeatureInfo;
Dianne Hackborn354736e2016-08-22 17:00:05 -070056import android.content.pm.IPackageManager;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080057import android.content.pm.PackageManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070058import android.content.pm.ParceledListSlice;
Dianne Hackborn354736e2016-08-22 17:00:05 -070059import android.content.pm.ResolveInfo;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080060import android.content.pm.SharedLibraryInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070061import android.content.pm.UserInfo;
Michael Kwan94438b72016-11-03 15:30:34 -070062import android.content.res.AssetManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070063import android.content.res.Configuration;
Michael Kwan94438b72016-11-03 15:30:34 -070064import android.content.res.Resources;
Dianne Hackborn331084d2016-10-07 17:57:00 -070065import android.graphics.Rect;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080066import android.hardware.display.DisplayManager;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080067import android.opengl.GLES10;
Dianne Hackborn331084d2016-10-07 17:57:00 -070068import android.os.Binder;
69import android.os.Build;
70import android.os.Bundle;
Bookatz03bfe6f2019-03-01 15:46:04 -080071import android.os.IProgressListener;
Dianne Hackborn354736e2016-08-22 17:00:05 -070072import android.os.ParcelFileDescriptor;
Makoto Onuki2c6657f2018-06-06 15:24:02 -070073import android.os.RemoteCallback;
74import android.os.RemoteCallback.OnResultListener;
Dianne Hackborn2e441072015-10-28 18:00:57 -070075import android.os.RemoteException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070076import android.os.ServiceManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -070077import android.os.ShellCommand;
Dianne Hackborn5c3296a2017-12-13 17:52:26 -080078import android.os.StrictMode;
Dianne Hackborn354736e2016-08-22 17:00:05 -070079import android.os.SystemClock;
Dianne Hackborn331084d2016-10-07 17:57:00 -070080import android.os.SystemProperties;
Dianne Hackborn2e441072015-10-28 18:00:57 -070081import android.os.UserHandle;
Alex Chau5c0df232018-02-22 15:57:17 +080082import android.os.UserManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070083import android.text.TextUtils;
84import android.util.ArrayMap;
atrostf69bbe12019-11-06 16:00:38 +000085import android.util.ArraySet;
Felipe Leme2f1b2272016-03-25 16:15:02 -070086import android.util.DebugUtils;
Michael Kwan94438b72016-11-03 15:30:34 -070087import android.util.DisplayMetrics;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080088import android.util.proto.ProtoOutputStream;
89import android.view.Display;
Dianne Hackborn2e441072015-10-28 18:00:57 -070090
atrostf69bbe12019-11-06 16:00:38 +000091import com.android.internal.compat.CompatibilityChangeConfig;
Dianne Hackborn331084d2016-10-07 17:57:00 -070092import com.android.internal.util.HexDump;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080093import com.android.internal.util.MemInfoReader;
atrostf69bbe12019-11-06 16:00:38 +000094import com.android.server.compat.PlatformCompat;
Dianne Hackborn331084d2016-10-07 17:57:00 -070095
96import java.io.BufferedReader;
97import java.io.File;
98import java.io.IOException;
99import java.io.InputStream;
100import java.io.InputStreamReader;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700101import java.io.PrintWriter;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700102import java.net.URISyntaxException;
Neil Fuller7046f2d2019-07-23 17:05:34 +0100103import java.time.Clock;
104import java.time.LocalDateTime;
105import java.time.format.DateTimeFormatter;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700106import java.util.ArrayList;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800107import java.util.Arrays;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700108import java.util.Collections;
109import java.util.Comparator;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800110import java.util.HashSet;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700111import java.util.List;
Neil Fuller7046f2d2019-07-23 17:05:34 +0100112import java.util.Locale;
Daulet Zhanguzin44eeff32020-01-03 09:44:46 +0000113import java.util.Objects;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800114import java.util.Set;
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700115import java.util.concurrent.CountDownLatch;
Bookatz03bfe6f2019-03-01 15:46:04 -0800116import java.util.concurrent.TimeUnit;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700117
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800118import javax.microedition.khronos.egl.EGL10;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800119import javax.microedition.khronos.egl.EGLConfig;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800120import javax.microedition.khronos.egl.EGLContext;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800121import javax.microedition.khronos.egl.EGLDisplay;
122import javax.microedition.khronos.egl.EGLSurface;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800123
Dianne Hackborn331084d2016-10-07 17:57:00 -0700124final class ActivityManagerShellCommand extends ShellCommand {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700125 public static final String NO_CLASS_ERROR_CODE = "Error type 3";
Neil Fuller7046f2d2019-07-23 17:05:34 +0100126
Dianne Hackborn331084d2016-10-07 17:57:00 -0700127 private static final String SHELL_PACKAGE_NAME = "com.android.shell";
128
Bookatz03bfe6f2019-03-01 15:46:04 -0800129 private static final int USER_OPERATION_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes
130
Neil Fuller7046f2d2019-07-23 17:05:34 +0100131 private static final DateTimeFormatter LOG_NAME_TIME_FORMATTER =
132 DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss", Locale.ROOT);
133
Dianne Hackborn2e441072015-10-28 18:00:57 -0700134 // IPC interface to activity manager -- don't need to do additional security checks.
135 final IActivityManager mInterface;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700136 final IActivityTaskManager mTaskInterface;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700137
138 // Internal service impl -- must perform security checks before touching.
139 final ActivityManagerService mInternal;
140
Dianne Hackborn354736e2016-08-22 17:00:05 -0700141 // Convenience for interacting with package manager.
142 final IPackageManager mPm;
143
144 private int mStartFlags = 0;
145 private boolean mWaitOption = false;
146 private boolean mStopOption = false;
147
148 private int mRepeat = 0;
149 private int mUserId;
150 private String mReceiverPermission;
151
152 private String mProfileFile;
153 private int mSamplingInterval;
154 private boolean mAutoStop;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800155 private boolean mStreaming; // Streaming the profiling output to a file.
Andreas Gampe83085bb2017-06-26 17:54:11 -0700156 private String mAgent; // Agent to attach on startup.
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800157 private boolean mAttachAgentDuringBind; // Whether agent should be attached late.
Andrii Kulian16802aa2016-11-02 12:21:33 -0700158 private int mDisplayId;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700159 private int mWindowingMode;
160 private int mActivityType;
Winson Chung6954fc92017-03-24 16:22:12 -0700161 private int mTaskId;
162 private boolean mIsTaskOverlay;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000163 private boolean mIsLockTask;
Alan Stokesc76767c2019-05-30 09:33:47 +0100164 private BroadcastOptions mBroadcastOptions;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700165
Dianne Hackborn2e441072015-10-28 18:00:57 -0700166 final boolean mDumping;
167
168 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
169 mInterface = service;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700170 mTaskInterface = service.mActivityTaskManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700171 mInternal = service;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700172 mPm = AppGlobals.getPackageManager();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700173 mDumping = dumping;
174 }
175
176 @Override
177 public int onCommand(String cmd) {
178 if (cmd == null) {
179 return handleDefaultCommands(cmd);
180 }
Dianne Hackborn5c3296a2017-12-13 17:52:26 -0800181 final PrintWriter pw = getOutPrintWriter();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700182 try {
183 switch (cmd) {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700184 case "start":
185 case "start-activity":
186 return runStartActivity(pw);
187 case "startservice":
188 case "start-service":
Christopher Tate7e1368d2017-03-30 17:20:12 -0700189 return runStartService(pw, false);
190 case "startforegroundservice":
191 case "startfgservice":
192 case "start-foreground-service":
193 case "start-fg-service":
194 return runStartService(pw, true);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700195 case "stopservice":
196 case "stop-service":
Dianne Hackborn331084d2016-10-07 17:57:00 -0700197 return runStopService(pw);
198 case "broadcast":
199 return runSendBroadcast(pw);
200 case "instrument":
Dianne Hackborn28824062016-10-18 13:19:20 -0700201 getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");
202 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700203 case "trace-ipc":
204 return runTraceIpc(pw);
205 case "profile":
206 return runProfile(pw);
207 case "dumpheap":
208 return runDumpHeap(pw);
209 case "set-debug-app":
210 return runSetDebugApp(pw);
Andreas Gampe5b495d52018-01-22 15:15:54 -0800211 case "set-agent-app":
212 return runSetAgentApp(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700213 case "clear-debug-app":
214 return runClearDebugApp(pw);
215 case "set-watch-heap":
216 return runSetWatchHeap(pw);
217 case "clear-watch-heap":
218 return runClearWatchHeap(pw);
Jing Ji8055a3a2019-12-17 15:55:33 -0800219 case "clear-exit-info":
220 return runClearExitInfo(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700221 case "bug-report":
222 return runBugReport(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700223 case "force-stop":
224 return runForceStop(pw);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800225 case "crash":
226 return runCrash(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700227 case "kill":
228 return runKill(pw);
229 case "kill-all":
230 return runKillAll(pw);
Dianne Hackborn85e35642017-01-12 15:10:57 -0800231 case "make-uid-idle":
Dianne Hackborne07641d2016-11-09 15:07:23 -0800232 return runMakeIdle(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700233 case "monitor":
234 return runMonitor(pw);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +0100235 case "watch-uids":
236 return runWatchUids(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700237 case "hang":
238 return runHang(pw);
239 case "restart":
240 return runRestart(pw);
241 case "idle-maintenance":
242 return runIdleMaintenance(pw);
243 case "screen-compat":
244 return runScreenCompat(pw);
245 case "package-importance":
246 return runPackageImportance(pw);
247 case "to-uri":
248 return runToUri(pw, 0);
249 case "to-intent-uri":
250 return runToUri(pw, Intent.URI_INTENT_SCHEME);
251 case "to-app-uri":
252 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME);
253 case "switch-user":
254 return runSwitchUser(pw);
255 case "get-current-user":
256 return runGetCurrentUser(pw);
257 case "start-user":
258 return runStartUser(pw);
259 case "unlock-user":
260 return runUnlockUser(pw);
261 case "stop-user":
262 return runStopUser(pw);
263 case "is-user-stopped":
264 return runIsUserStopped(pw);
265 case "get-started-user-state":
266 return runGetStartedUserState(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700267 case "track-associations":
268 return runTrackAssociations(pw);
269 case "untrack-associations":
270 return runUntrackAssociations(pw);
Felipe Leme2f1b2272016-03-25 16:15:02 -0700271 case "get-uid-state":
272 return getUidState(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700273 case "get-config":
274 return runGetConfig(pw);
275 case "suppress-resize-config-changes":
276 return runSuppressResizeConfigChanges(pw);
277 case "set-inactive":
278 return runSetInactive(pw);
279 case "get-inactive":
280 return runGetInactive(pw);
Amith Yamasani17fffee2017-09-29 13:17:43 -0700281 case "set-standby-bucket":
282 return runSetStandbyBucket(pw);
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800283 case "get-standby-bucket":
284 return runGetStandbyBucket(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700285 case "send-trim-memory":
286 return runSendTrimMemory(pw);
Andrii Kulian839def92016-11-02 10:58:58 -0700287 case "display":
288 return runDisplay(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700289 case "stack":
290 return runStack(pw);
291 case "task":
292 return runTask(pw);
293 case "write":
294 return runWrite(pw);
Leonard Mosescuf3409ce2016-10-06 17:32:05 -0700295 case "attach-agent":
296 return runAttachAgent(pw);
Michael Kwan94438b72016-11-03 15:30:34 -0700297 case "supports-multiwindow":
298 return runSupportsMultiwindow(pw);
Matthew Ng626e0cc2016-12-07 17:25:53 -0800299 case "supports-split-screen-multi-window":
300 return runSupportsSplitScreenMultiwindow(pw);
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +0100301 case "update-appinfo":
302 return runUpdateApplicationInfo(pw);
Arthur Hsuf3f3a602017-02-21 14:01:53 -0800303 case "no-home-screen":
304 return runNoHomeScreen(pw);
Jeff Sharkeyfd658132017-05-03 11:38:01 -0600305 case "wait-for-broadcast-idle":
306 return runWaitForBroadcastIdle(pw);
Andrei Oneaa2055012019-06-28 18:42:22 +0100307 case "compat":
308 return runCompat(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700309 default:
310 return handleDefaultCommands(cmd);
311 }
312 } catch (RemoteException e) {
313 pw.println("Remote exception: " + e);
314 }
315 return -1;
316 }
317
Dianne Hackborn354736e2016-08-22 17:00:05 -0700318 private Intent makeIntent(int defUser) throws URISyntaxException {
319 mStartFlags = 0;
320 mWaitOption = false;
321 mStopOption = false;
322 mRepeat = 0;
323 mProfileFile = null;
324 mSamplingInterval = 0;
325 mAutoStop = false;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800326 mStreaming = false;
Zhi An Ng6aab6f92019-03-29 22:33:25 +0000327 mUserId = defUser;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700328 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700329 mWindowingMode = WINDOWING_MODE_UNDEFINED;
330 mActivityType = ACTIVITY_TYPE_UNDEFINED;
Winson Chung6954fc92017-03-24 16:22:12 -0700331 mTaskId = INVALID_TASK_ID;
332 mIsTaskOverlay = false;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000333 mIsLockTask = false;
Alan Stokesc76767c2019-05-30 09:33:47 +0100334 mBroadcastOptions = null;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700335
336 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
337 @Override
338 public boolean handleOption(String opt, ShellCommand cmd) {
339 if (opt.equals("-D")) {
340 mStartFlags |= ActivityManager.START_FLAG_DEBUG;
341 } else if (opt.equals("-N")) {
342 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING;
343 } else if (opt.equals("-W")) {
344 mWaitOption = true;
345 } else if (opt.equals("-P")) {
346 mProfileFile = getNextArgRequired();
347 mAutoStop = true;
348 } else if (opt.equals("--start-profiler")) {
349 mProfileFile = getNextArgRequired();
350 mAutoStop = false;
351 } else if (opt.equals("--sampling")) {
352 mSamplingInterval = Integer.parseInt(getNextArgRequired());
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800353 } else if (opt.equals("--streaming")) {
354 mStreaming = true;
Andreas Gampe83085bb2017-06-26 17:54:11 -0700355 } else if (opt.equals("--attach-agent")) {
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800356 if (mAgent != null) {
357 cmd.getErrPrintWriter().println(
358 "Multiple --attach-agent(-bind) not supported");
359 return false;
360 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700361 mAgent = getNextArgRequired();
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800362 mAttachAgentDuringBind = false;
363 } else if (opt.equals("--attach-agent-bind")) {
364 if (mAgent != null) {
365 cmd.getErrPrintWriter().println(
366 "Multiple --attach-agent(-bind) not supported");
367 return false;
368 }
369 mAgent = getNextArgRequired();
370 mAttachAgentDuringBind = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700371 } else if (opt.equals("-R")) {
372 mRepeat = Integer.parseInt(getNextArgRequired());
373 } else if (opt.equals("-S")) {
374 mStopOption = true;
375 } else if (opt.equals("--track-allocation")) {
376 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
377 } else if (opt.equals("--user")) {
378 mUserId = UserHandle.parseUserArg(getNextArgRequired());
379 } else if (opt.equals("--receiver-permission")) {
380 mReceiverPermission = getNextArgRequired();
Andrii Kulian16802aa2016-11-02 12:21:33 -0700381 } else if (opt.equals("--display")) {
382 mDisplayId = Integer.parseInt(getNextArgRequired());
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700383 } else if (opt.equals("--windowingMode")) {
384 mWindowingMode = Integer.parseInt(getNextArgRequired());
385 } else if (opt.equals("--activityType")) {
386 mActivityType = Integer.parseInt(getNextArgRequired());
Winson Chung6954fc92017-03-24 16:22:12 -0700387 } else if (opt.equals("--task")) {
388 mTaskId = Integer.parseInt(getNextArgRequired());
389 } else if (opt.equals("--task-overlay")) {
390 mIsTaskOverlay = true;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000391 } else if (opt.equals("--lock-task")) {
392 mIsLockTask = true;
Alan Stokesc76767c2019-05-30 09:33:47 +0100393 } else if (opt.equals("--allow-background-activity-starts")) {
394 if (mBroadcastOptions == null) {
395 mBroadcastOptions = BroadcastOptions.makeBasic();
396 }
397 mBroadcastOptions.setBackgroundActivityStartsAllowed(true);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700398 } else {
399 return false;
400 }
401 return true;
402 }
403 });
404 }
405
Bookatz03bfe6f2019-03-01 15:46:04 -0800406 private class ProgressWaiter extends IProgressListener.Stub {
407 private final CountDownLatch mFinishedLatch = new CountDownLatch(1);
408
409 @Override
410 public void onStarted(int id, Bundle extras) {}
411
412 @Override
413 public void onProgress(int id, int progress, Bundle extras) {}
414
415 @Override
416 public void onFinished(int id, Bundle extras) {
417 mFinishedLatch.countDown();
418 }
419
420 public boolean waitForFinish(long timeoutMillis) {
421 try {
422 return mFinishedLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
423 } catch (InterruptedException e) {
424 System.err.println("Thread interrupted unexpectedly.");
425 return false;
426 }
427 }
428 }
429
Dianne Hackborn354736e2016-08-22 17:00:05 -0700430 int runStartActivity(PrintWriter pw) throws RemoteException {
431 Intent intent;
432 try {
433 intent = makeIntent(UserHandle.USER_CURRENT);
434 } catch (URISyntaxException e) {
435 throw new RuntimeException(e.getMessage(), e);
436 }
437
438 if (mUserId == UserHandle.USER_ALL) {
439 getErrPrintWriter().println("Error: Can't start service with user 'all'");
440 return 1;
441 }
442
443 String mimeType = intent.getType();
444 if (mimeType == null && intent.getData() != null
445 && "content".equals(intent.getData().getScheme())) {
446 mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId);
447 }
448
449 do {
450 if (mStopOption) {
451 String packageName;
452 if (intent.getComponent() != null) {
453 packageName = intent.getComponent().getPackageName();
454 } else {
Ng Zhi An494d4fe2019-04-02 09:00:22 -0700455 // queryIntentActivities does not convert user id, so we convert it here first
456 int userIdForQuery = mInternal.mUserController.handleIncomingUser(
457 Binder.getCallingPid(), Binder.getCallingUid(), mUserId, false,
458 ALLOW_NON_FULL, "ActivityManagerShellCommand", null);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700459 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0,
Ng Zhi An494d4fe2019-04-02 09:00:22 -0700460 userIdForQuery).getList();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700461 if (activities == null || activities.size() <= 0) {
462 getErrPrintWriter().println("Error: Intent does not match any activities: "
463 + intent);
464 return 1;
465 } else if (activities.size() > 1) {
466 getErrPrintWriter().println(
467 "Error: Intent matches multiple activities; can't stop: "
468 + intent);
469 return 1;
470 }
471 packageName = activities.get(0).activityInfo.packageName;
472 }
473 pw.println("Stopping: " + packageName);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700474 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700475 mInterface.forceStopPackage(packageName, mUserId);
476 try {
477 Thread.sleep(250);
478 } catch (InterruptedException e) {
479 }
480 }
481
482 ProfilerInfo profilerInfo = null;
483
Andreas Gampe83085bb2017-06-26 17:54:11 -0700484 if (mProfileFile != null || mAgent != null) {
485 ParcelFileDescriptor fd = null;
486 if (mProfileFile != null) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700487 fd = openFileForSystem(mProfileFile, "w");
Andreas Gampe83085bb2017-06-26 17:54:11 -0700488 if (fd == null) {
489 return 1;
490 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700491 }
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800492 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800493 mStreaming, mAgent, mAttachAgentDuringBind);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700494 }
495
496 pw.println("Starting: " + intent);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700497 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700498 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
499
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700500 WaitResult result = null;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700501 int res;
502 final long startTime = SystemClock.uptimeMillis();
503 ActivityOptions options = null;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700504 if (mDisplayId != INVALID_DISPLAY) {
505 options = ActivityOptions.makeBasic();
506 options.setLaunchDisplayId(mDisplayId);
507 }
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700508 if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
509 if (options == null) {
510 options = ActivityOptions.makeBasic();
511 }
512 options.setLaunchWindowingMode(mWindowingMode);
513 }
514 if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
515 if (options == null) {
516 options = ActivityOptions.makeBasic();
517 }
518 options.setLaunchActivityType(mActivityType);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700519 }
Winson Chung6954fc92017-03-24 16:22:12 -0700520 if (mTaskId != INVALID_TASK_ID) {
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000521 if (options == null) {
522 options = ActivityOptions.makeBasic();
523 }
Winson Chung6954fc92017-03-24 16:22:12 -0700524 options.setLaunchTaskId(mTaskId);
525
526 if (mIsTaskOverlay) {
527 options.setTaskOverlay(true, true /* canResume */);
528 }
529 }
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000530 if (mIsLockTask) {
531 if (options == null) {
532 options = ActivityOptions.makeBasic();
533 }
Benjamin Franzcaffa772018-02-05 16:36:10 +0000534 options.setLockTaskEnabled(true);
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000535 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700536 if (mWaitOption) {
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800537 result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, null, intent,
538 mimeType, null, null, 0, mStartFlags, profilerInfo,
Dianne Hackborn354736e2016-08-22 17:00:05 -0700539 options != null ? options.toBundle() : null, mUserId);
540 res = result.result;
541 } else {
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800542 res = mInternal.startActivityAsUserWithFeature(null, SHELL_PACKAGE_NAME, null,
543 intent, mimeType, null, null, 0, mStartFlags, profilerInfo,
Dianne Hackborn354736e2016-08-22 17:00:05 -0700544 options != null ? options.toBundle() : null, mUserId);
545 }
546 final long endTime = SystemClock.uptimeMillis();
547 PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
548 boolean launched = false;
549 switch (res) {
550 case ActivityManager.START_SUCCESS:
551 launched = true;
552 break;
553 case ActivityManager.START_SWITCHES_CANCELED:
554 launched = true;
555 out.println(
556 "Warning: Activity not started because the "
557 + " current activity is being kept for the user.");
558 break;
559 case ActivityManager.START_DELIVERED_TO_TOP:
560 launched = true;
561 out.println(
562 "Warning: Activity not started, intent has "
563 + "been delivered to currently running "
564 + "top-most instance.");
565 break;
566 case ActivityManager.START_RETURN_INTENT_TO_CALLER:
567 launched = true;
568 out.println(
569 "Warning: Activity not started because intent "
570 + "should be handled by the caller");
571 break;
572 case ActivityManager.START_TASK_TO_FRONT:
573 launched = true;
574 out.println(
575 "Warning: Activity not started, its current "
576 + "task has been brought to the front");
577 break;
578 case ActivityManager.START_INTENT_NOT_RESOLVED:
579 out.println(
580 "Error: Activity not started, unable to "
581 + "resolve " + intent.toString());
582 break;
583 case ActivityManager.START_CLASS_NOT_FOUND:
584 out.println(NO_CLASS_ERROR_CODE);
585 out.println("Error: Activity class " +
586 intent.getComponent().toShortString()
587 + " does not exist.");
588 break;
589 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
590 out.println(
591 "Error: Activity not started, you requested to "
592 + "both forward and receive its result");
593 break;
594 case ActivityManager.START_PERMISSION_DENIED:
595 out.println(
596 "Error: Activity not started, you do not "
597 + "have permission to access it.");
598 break;
599 case ActivityManager.START_NOT_VOICE_COMPATIBLE:
600 out.println(
601 "Error: Activity not started, voice control not allowed for: "
602 + intent);
603 break;
604 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
605 out.println(
606 "Error: Not allowed to start background user activity"
607 + " that shouldn't be displayed for all users.");
608 break;
609 default:
610 out.println(
611 "Error: Activity not started, unknown error code " + res);
612 break;
613 }
Dianne Hackborn331084d2016-10-07 17:57:00 -0700614 out.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700615 if (mWaitOption && launched) {
616 if (result == null) {
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700617 result = new WaitResult();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700618 result.who = intent.getComponent();
619 }
620 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
Louis Chang0513a942019-03-06 12:38:13 +0800621 pw.println("LaunchState: " + launchStateToString(result.launchState));
Dianne Hackborn354736e2016-08-22 17:00:05 -0700622 if (result.who != null) {
623 pw.println("Activity: " + result.who.flattenToShortString());
624 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700625 if (result.totalTime >= 0) {
626 pw.println("TotalTime: " + result.totalTime);
627 }
628 pw.println("WaitTime: " + (endTime-startTime));
629 pw.println("Complete");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700630 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700631 }
632 mRepeat--;
633 if (mRepeat > 0) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700634 mTaskInterface.unhandledBack();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700635 }
636 } while (mRepeat > 0);
637 return 0;
638 }
639
Christopher Tate7e1368d2017-03-30 17:20:12 -0700640 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700641 final PrintWriter err = getErrPrintWriter();
642 Intent intent;
643 try {
644 intent = makeIntent(UserHandle.USER_CURRENT);
645 } catch (URISyntaxException e) {
646 throw new RuntimeException(e.getMessage(), e);
647 }
648 if (mUserId == UserHandle.USER_ALL) {
649 err.println("Error: Can't start activity with user 'all'");
650 return -1;
651 }
652 pw.println("Starting service: " + intent);
653 pw.flush();
654 ComponentName cn = mInterface.startService(null, intent, intent.getType(),
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800655 asForeground, SHELL_PACKAGE_NAME, null, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700656 if (cn == null) {
657 err.println("Error: Not found; no service started.");
658 return -1;
659 } else if (cn.getPackageName().equals("!")) {
660 err.println("Error: Requires permission " + cn.getClassName());
661 return -1;
662 } else if (cn.getPackageName().equals("!!")) {
663 err.println("Error: " + cn.getClassName());
664 return -1;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800665 } else if (cn.getPackageName().equals("?")) {
666 err.println("Error: " + cn.getClassName());
667 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700668 }
669 return 0;
670 }
671
672 int runStopService(PrintWriter pw) throws RemoteException {
673 final PrintWriter err = getErrPrintWriter();
674 Intent intent;
675 try {
676 intent = makeIntent(UserHandle.USER_CURRENT);
677 } catch (URISyntaxException e) {
678 throw new RuntimeException(e.getMessage(), e);
679 }
680 if (mUserId == UserHandle.USER_ALL) {
681 err.println("Error: Can't stop activity with user 'all'");
682 return -1;
683 }
684 pw.println("Stopping service: " + intent);
685 pw.flush();
686 int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
687 if (result == 0) {
688 err.println("Service not stopped: was not running.");
689 return -1;
690 } else if (result == 1) {
691 err.println("Service stopped");
692 return -1;
693 } else if (result == -1) {
694 err.println("Error stopping service");
695 return -1;
696 }
697 return 0;
698 }
699
700 final static class IntentReceiver extends IIntentReceiver.Stub {
701 private final PrintWriter mPw;
702 private boolean mFinished = false;
703
704 IntentReceiver(PrintWriter pw) {
705 mPw = pw;
706 }
707
708 @Override
709 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
710 boolean ordered, boolean sticky, int sendingUser) {
711 String line = "Broadcast completed: result=" + resultCode;
712 if (data != null) line = line + ", data=\"" + data + "\"";
713 if (extras != null) line = line + ", extras: " + extras;
714 mPw.println(line);
715 mPw.flush();
716 synchronized (this) {
717 mFinished = true;
718 notifyAll();
719 }
720 }
721
722 public synchronized void waitForFinish() {
723 try {
724 while (!mFinished) wait();
725 } catch (InterruptedException e) {
726 throw new IllegalStateException(e);
727 }
728 }
729 }
730
731 int runSendBroadcast(PrintWriter pw) throws RemoteException {
732 Intent intent;
733 try {
734 intent = makeIntent(UserHandle.USER_CURRENT);
735 } catch (URISyntaxException e) {
736 throw new RuntimeException(e.getMessage(), e);
737 }
Jeff Sharkey6a34e562016-12-21 09:56:00 -0700738 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700739 IntentReceiver receiver = new IntentReceiver(pw);
740 String[] requiredPermissions = mReceiverPermission == null ? null
741 : new String[] {mReceiverPermission};
742 pw.println("Broadcasting: " + intent);
743 pw.flush();
Alan Stokesc76767c2019-05-30 09:33:47 +0100744 Bundle bundle = mBroadcastOptions == null ? null : mBroadcastOptions.toBundle();
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800745 mInterface.broadcastIntentWithFeature(null, null, intent, null, receiver, 0, null, null,
746 requiredPermissions, android.app.AppOpsManager.OP_NONE, bundle, true, false,
747 mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700748 receiver.waitForFinish();
749 return 0;
750 }
751
Dianne Hackborn331084d2016-10-07 17:57:00 -0700752 int runTraceIpc(PrintWriter pw) throws RemoteException {
753 String op = getNextArgRequired();
754 if (op.equals("start")) {
755 return runTraceIpcStart(pw);
756 } else if (op.equals("stop")) {
757 return runTraceIpcStop(pw);
758 } else {
759 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'");
760 return -1;
761 }
762 }
763
764 int runTraceIpcStart(PrintWriter pw) throws RemoteException {
765 pw.println("Starting IPC tracing.");
766 pw.flush();
767 mInterface.startBinderTracking();
768 return 0;
769 }
770
771 int runTraceIpcStop(PrintWriter pw) throws RemoteException {
772 final PrintWriter err = getErrPrintWriter();
773 String opt;
774 String filename = null;
775 while ((opt=getNextOption()) != null) {
776 if (opt.equals("--dump-file")) {
777 filename = getNextArgRequired();
778 } else {
779 err.println("Error: Unknown option: " + opt);
780 return -1;
781 }
782 }
783 if (filename == null) {
784 err.println("Error: Specify filename to dump logs to.");
785 return -1;
786 }
787
788 File file = new File(filename);
789 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700790 ParcelFileDescriptor fd = openFileForSystem(filename, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700791 if (fd == null) {
792 return -1;
793 }
794
Dianne Hackborn331084d2016-10-07 17:57:00 -0700795 if (!mInterface.stopBinderTrackingAndDump(fd)) {
796 err.println("STOP TRACE FAILED.");
797 return -1;
798 }
799
800 pw.println("Stopped IPC tracing. Dumping logs to: " + filename);
801 return 0;
802 }
803
804 static void removeWallOption() {
805 String props = SystemProperties.get("dalvik.vm.extra-opts");
806 if (props != null && props.contains("-Xprofile:wallclock")) {
807 props = props.replace("-Xprofile:wallclock", "");
808 props = props.trim();
809 SystemProperties.set("dalvik.vm.extra-opts", props);
810 }
811 }
812
813 private int runProfile(PrintWriter pw) throws RemoteException {
814 final PrintWriter err = getErrPrintWriter();
815 String profileFile = null;
816 boolean start = false;
817 boolean wall = false;
818 int userId = UserHandle.USER_CURRENT;
819 int profileType = 0;
820 mSamplingInterval = 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800821 mStreaming = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700822
823 String process = null;
824
825 String cmd = getNextArgRequired();
826
827 if ("start".equals(cmd)) {
828 start = true;
829 String opt;
830 while ((opt=getNextOption()) != null) {
831 if (opt.equals("--user")) {
832 userId = UserHandle.parseUserArg(getNextArgRequired());
833 } else if (opt.equals("--wall")) {
834 wall = true;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800835 } else if (opt.equals("--streaming")) {
836 mStreaming = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700837 } else if (opt.equals("--sampling")) {
838 mSamplingInterval = Integer.parseInt(getNextArgRequired());
839 } else {
840 err.println("Error: Unknown option: " + opt);
841 return -1;
842 }
843 }
844 process = getNextArgRequired();
845 } else if ("stop".equals(cmd)) {
846 String opt;
847 while ((opt=getNextOption()) != null) {
848 if (opt.equals("--user")) {
849 userId = UserHandle.parseUserArg(getNextArgRequired());
850 } else {
851 err.println("Error: Unknown option: " + opt);
852 return -1;
853 }
854 }
Orion Hodson4e6a3142019-04-08 10:12:02 +0100855 process = getNextArgRequired();
Dianne Hackborn331084d2016-10-07 17:57:00 -0700856 } else {
857 // Compatibility with old syntax: process is specified first.
858 process = cmd;
859 cmd = getNextArgRequired();
860 if ("start".equals(cmd)) {
861 start = true;
862 } else if (!"stop".equals(cmd)) {
863 throw new IllegalArgumentException("Profile command " + process + " not valid");
864 }
865 }
866
867 if (userId == UserHandle.USER_ALL) {
868 err.println("Error: Can't profile with user 'all'");
869 return -1;
870 }
871
872 ParcelFileDescriptor fd = null;
873 ProfilerInfo profilerInfo = null;
874
875 if (start) {
876 profileFile = getNextArgRequired();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700877 fd = openFileForSystem(profileFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700878 if (fd == null) {
879 return -1;
880 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700881 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800882 null, false);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700883 }
884
885 try {
886 if (wall) {
887 // XXX doesn't work -- this needs to be set before booting.
888 String props = SystemProperties.get("dalvik.vm.extra-opts");
889 if (props == null || !props.contains("-Xprofile:wallclock")) {
890 props = props + " -Xprofile:wallclock";
891 //SystemProperties.set("dalvik.vm.extra-opts", props);
892 }
893 } else if (start) {
894 //removeWallOption();
895 }
896 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
897 wall = false;
898 err.println("PROFILE FAILED on process " + process);
899 return -1;
900 }
901 } finally {
902 if (!wall) {
903 //removeWallOption();
904 }
905 }
906 return 0;
907 }
908
909 int runDumpHeap(PrintWriter pw) throws RemoteException {
910 final PrintWriter err = getErrPrintWriter();
911 boolean managed = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700912 boolean mallocInfo = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700913 int userId = UserHandle.USER_CURRENT;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700914 boolean runGc = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700915
916 String opt;
917 while ((opt=getNextOption()) != null) {
918 if (opt.equals("--user")) {
919 userId = UserHandle.parseUserArg(getNextArgRequired());
920 if (userId == UserHandle.USER_ALL) {
921 err.println("Error: Can't dump heap with user 'all'");
922 return -1;
923 }
924 } else if (opt.equals("-n")) {
925 managed = false;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700926 } else if (opt.equals("-g")) {
927 runGc = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700928 } else if (opt.equals("-m")) {
929 managed = false;
930 mallocInfo = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700931 } else {
932 err.println("Error: Unknown option: " + opt);
933 return -1;
934 }
935 }
936 String process = getNextArgRequired();
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700937 String heapFile = getNextArg();
938 if (heapFile == null) {
Neil Fuller7046f2d2019-07-23 17:05:34 +0100939 LocalDateTime localDateTime = LocalDateTime.now(Clock.systemDefaultZone());
940 String logNameTimeString = LOG_NAME_TIME_FORMATTER.format(localDateTime);
941 heapFile = "/data/local/tmp/heapdump-" + logNameTimeString + ".prof";
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700942 }
943 pw.println("File: " + heapFile);
944 pw.flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -0700945
946 File file = new File(heapFile);
947 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700948 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700949 if (fd == null) {
950 return -1;
951 }
952
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700953 final CountDownLatch latch = new CountDownLatch(1);
954
955 final RemoteCallback finishCallback = new RemoteCallback(new OnResultListener() {
956 @Override
957 public void onResult(Bundle result) {
958 latch.countDown();
959 }
960 }, null);
961
962 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd,
963 finishCallback)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700964 err.println("HEAP DUMP FAILED on process " + process);
965 return -1;
966 }
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700967 pw.println("Waiting for dump to finish...");
968 pw.flush();
969 try {
970 latch.await();
971 } catch (InterruptedException e) {
972 err.println("Caught InterruptedException");
973 }
974
Dianne Hackborn331084d2016-10-07 17:57:00 -0700975 return 0;
976 }
977
978 int runSetDebugApp(PrintWriter pw) throws RemoteException {
979 boolean wait = false;
980 boolean persistent = false;
981
982 String opt;
983 while ((opt=getNextOption()) != null) {
984 if (opt.equals("-w")) {
985 wait = true;
986 } else if (opt.equals("--persistent")) {
987 persistent = true;
988 } else {
989 getErrPrintWriter().println("Error: Unknown option: " + opt);
990 return -1;
991 }
992 }
993
994 String pkg = getNextArgRequired();
995 mInterface.setDebugApp(pkg, wait, persistent);
996 return 0;
997 }
998
Andreas Gampe5b495d52018-01-22 15:15:54 -0800999 int runSetAgentApp(PrintWriter pw) throws RemoteException {
1000 String pkg = getNextArgRequired();
1001 String agent = getNextArg();
1002 mInterface.setAgentApp(pkg, agent);
1003 return 0;
1004 }
1005
Dianne Hackborn331084d2016-10-07 17:57:00 -07001006 int runClearDebugApp(PrintWriter pw) throws RemoteException {
1007 mInterface.setDebugApp(null, false, true);
1008 return 0;
1009 }
1010
1011 int runSetWatchHeap(PrintWriter pw) throws RemoteException {
1012 String proc = getNextArgRequired();
1013 String limit = getNextArgRequired();
1014 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
1015 return 0;
1016 }
1017
1018 int runClearWatchHeap(PrintWriter pw) throws RemoteException {
1019 String proc = getNextArgRequired();
1020 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null);
1021 return 0;
1022 }
1023
Jing Ji8055a3a2019-12-17 15:55:33 -08001024 int runClearExitInfo(PrintWriter pw) throws RemoteException {
1025 mInternal.enforceCallingPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
1026 "runClearExitInfo()");
1027 String opt;
1028 int userId = UserHandle.USER_CURRENT;
1029 String packageName = null;
1030 while ((opt = getNextOption()) != null) {
1031 if (opt.equals("--user")) {
1032 userId = UserHandle.parseUserArg(getNextArgRequired());
1033 } else {
1034 packageName = opt;
1035 }
1036 }
1037 if (userId == UserHandle.USER_CURRENT) {
1038 UserInfo user = mInterface.getCurrentUser();
1039 if (user == null) {
1040 return -1;
1041 }
1042 userId = user.id;
1043 }
1044 mInternal.mProcessList.mAppExitInfoTracker.clearHistoryProcessExitInfo(packageName, userId);
1045 return 0;
1046 }
1047
Dianne Hackborn331084d2016-10-07 17:57:00 -07001048 int runBugReport(PrintWriter pw) throws RemoteException {
1049 String opt;
Abhijeet Kaur16207e32019-08-22 15:05:38 +01001050 boolean fullBugreport = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -07001051 while ((opt=getNextOption()) != null) {
1052 if (opt.equals("--progress")) {
Abhijeet Kaur16207e32019-08-22 15:05:38 +01001053 fullBugreport = false;
1054 mInterface.requestInteractiveBugReport();
Felipe Leme9606c3b2017-01-05 14:57:12 -08001055 } else if (opt.equals("--telephony")) {
Abhijeet Kaur16207e32019-08-22 15:05:38 +01001056 fullBugreport = false;
1057 // no title and description specified
1058 mInterface.requestTelephonyBugReport("" /* no title */, "" /* no descriptions */);
Dianne Hackborn331084d2016-10-07 17:57:00 -07001059 } else {
1060 getErrPrintWriter().println("Error: Unknown option: " + opt);
1061 return -1;
1062 }
1063 }
Abhijeet Kaur16207e32019-08-22 15:05:38 +01001064 if (fullBugreport) {
1065 mInterface.requestFullBugReport();
1066 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001067 pw.println("Your lovely bug report is being created; please be patient.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001068 return 0;
1069 }
1070
Dianne Hackborn2e441072015-10-28 18:00:57 -07001071 int runForceStop(PrintWriter pw) throws RemoteException {
1072 int userId = UserHandle.USER_ALL;
1073
1074 String opt;
1075 while ((opt = getNextOption()) != null) {
1076 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001077 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001078 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001079 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001080 return -1;
1081 }
1082 }
1083 mInterface.forceStopPackage(getNextArgRequired(), userId);
1084 return 0;
1085 }
1086
Christopher Tate8aa8fe12017-01-20 17:50:32 -08001087 int runCrash(PrintWriter pw) throws RemoteException {
1088 int userId = UserHandle.USER_ALL;
1089
1090 String opt;
1091 while ((opt=getNextOption()) != null) {
1092 if (opt.equals("--user")) {
1093 userId = UserHandle.parseUserArg(getNextArgRequired());
1094 } else {
1095 getErrPrintWriter().println("Error: Unknown option: " + opt);
1096 return -1;
1097 }
1098 }
1099
1100 int pid = -1;
1101 String packageName = null;
1102 final String arg = getNextArgRequired();
1103 // The argument is either a pid or a package name
1104 try {
1105 pid = Integer.parseInt(arg);
1106 } catch (NumberFormatException e) {
1107 packageName = arg;
1108 }
Christopher Tate9fbc5e72019-08-19 16:16:20 -07001109 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false);
Christopher Tate8aa8fe12017-01-20 17:50:32 -08001110 return 0;
1111 }
1112
Dianne Hackborn2e441072015-10-28 18:00:57 -07001113 int runKill(PrintWriter pw) throws RemoteException {
1114 int userId = UserHandle.USER_ALL;
1115
1116 String opt;
1117 while ((opt=getNextOption()) != null) {
1118 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001119 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001120 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001121 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001122 return -1;
1123 }
1124 }
1125 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
1126 return 0;
1127 }
1128
1129 int runKillAll(PrintWriter pw) throws RemoteException {
1130 mInterface.killAllBackgroundProcesses();
1131 return 0;
1132 }
1133
Dianne Hackborne07641d2016-11-09 15:07:23 -08001134 int runMakeIdle(PrintWriter pw) throws RemoteException {
1135 int userId = UserHandle.USER_ALL;
1136
1137 String opt;
1138 while ((opt = getNextOption()) != null) {
1139 if (opt.equals("--user")) {
1140 userId = UserHandle.parseUserArg(getNextArgRequired());
1141 } else {
1142 getErrPrintWriter().println("Error: Unknown option: " + opt);
1143 return -1;
1144 }
1145 }
1146 mInterface.makePackageIdle(getNextArgRequired(), userId);
1147 return 0;
1148 }
1149
Dianne Hackborn331084d2016-10-07 17:57:00 -07001150 static final class MyActivityController extends IActivityController.Stub {
1151 final IActivityManager mInterface;
1152 final PrintWriter mPw;
1153 final InputStream mInput;
1154 final String mGdbPort;
1155 final boolean mMonkey;
1156
1157 static final int STATE_NORMAL = 0;
1158 static final int STATE_CRASHED = 1;
1159 static final int STATE_EARLY_ANR = 2;
1160 static final int STATE_ANR = 3;
1161
1162 int mState;
1163
1164 static final int RESULT_DEFAULT = 0;
1165
1166 static final int RESULT_CRASH_DIALOG = 0;
1167 static final int RESULT_CRASH_KILL = 1;
1168
1169 static final int RESULT_EARLY_ANR_CONTINUE = 0;
1170 static final int RESULT_EARLY_ANR_KILL = 1;
1171
1172 static final int RESULT_ANR_DIALOG = 0;
1173 static final int RESULT_ANR_KILL = 1;
Jing Ji8055a3a2019-12-17 15:55:33 -08001174 static final int RESULT_ANR_WAIT = 2;
Dianne Hackborn331084d2016-10-07 17:57:00 -07001175
1176 int mResult;
1177
1178 Process mGdbProcess;
1179 Thread mGdbThread;
1180 boolean mGotGdbPrint;
1181
1182 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
1183 String gdbPort, boolean monkey) {
1184 mInterface = iam;
1185 mPw = pw;
1186 mInput = input;
1187 mGdbPort = gdbPort;
1188 mMonkey = monkey;
1189 }
1190
1191 @Override
1192 public boolean activityResuming(String pkg) {
1193 synchronized (this) {
1194 mPw.println("** Activity resuming: " + pkg);
1195 mPw.flush();
1196 }
1197 return true;
1198 }
1199
1200 @Override
1201 public boolean activityStarting(Intent intent, String pkg) {
1202 synchronized (this) {
1203 mPw.println("** Activity starting: " + pkg);
1204 mPw.flush();
1205 }
1206 return true;
1207 }
1208
1209 @Override
1210 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
1211 long timeMillis, String stackTrace) {
1212 synchronized (this) {
1213 mPw.println("** ERROR: PROCESS CRASHED");
1214 mPw.println("processName: " + processName);
1215 mPw.println("processPid: " + pid);
1216 mPw.println("shortMsg: " + shortMsg);
1217 mPw.println("longMsg: " + longMsg);
1218 mPw.println("timeMillis: " + timeMillis);
1219 mPw.println("stack:");
1220 mPw.print(stackTrace);
1221 mPw.println("#");
1222 mPw.flush();
1223 int result = waitControllerLocked(pid, STATE_CRASHED);
1224 return result == RESULT_CRASH_KILL ? false : true;
1225 }
1226 }
1227
1228 @Override
1229 public int appEarlyNotResponding(String processName, int pid, String annotation) {
1230 synchronized (this) {
1231 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING");
1232 mPw.println("processName: " + processName);
1233 mPw.println("processPid: " + pid);
1234 mPw.println("annotation: " + annotation);
1235 mPw.flush();
1236 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
1237 if (result == RESULT_EARLY_ANR_KILL) return -1;
1238 return 0;
1239 }
1240 }
1241
1242 @Override
1243 public int appNotResponding(String processName, int pid, String processStats) {
1244 synchronized (this) {
1245 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1246 mPw.println("processName: " + processName);
1247 mPw.println("processPid: " + pid);
1248 mPw.println("processStats:");
1249 mPw.print(processStats);
1250 mPw.println("#");
1251 mPw.flush();
1252 int result = waitControllerLocked(pid, STATE_ANR);
1253 if (result == RESULT_ANR_KILL) return -1;
1254 if (result == RESULT_ANR_WAIT) return 1;
1255 return 0;
1256 }
1257 }
1258
1259 @Override
1260 public int systemNotResponding(String message) {
1261 synchronized (this) {
1262 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1263 mPw.println("message: " + message);
1264 mPw.println("#");
1265 mPw.println("Allowing system to die.");
1266 mPw.flush();
1267 return -1;
1268 }
1269 }
1270
1271 void killGdbLocked() {
1272 mGotGdbPrint = false;
1273 if (mGdbProcess != null) {
1274 mPw.println("Stopping gdbserver");
1275 mPw.flush();
1276 mGdbProcess.destroy();
1277 mGdbProcess = null;
1278 }
1279 if (mGdbThread != null) {
1280 mGdbThread.interrupt();
1281 mGdbThread = null;
1282 }
1283 }
1284
1285 int waitControllerLocked(int pid, int state) {
1286 if (mGdbPort != null) {
1287 killGdbLocked();
1288
1289 try {
1290 mPw.println("Starting gdbserver on port " + mGdbPort);
1291 mPw.println("Do the following:");
1292 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
1293 mPw.println(" gdbclient app_process :" + mGdbPort);
1294 mPw.flush();
1295
1296 mGdbProcess = Runtime.getRuntime().exec(new String[] {
1297 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
1298 });
1299 final InputStreamReader converter = new InputStreamReader(
1300 mGdbProcess.getInputStream());
1301 mGdbThread = new Thread() {
1302 @Override
1303 public void run() {
1304 BufferedReader in = new BufferedReader(converter);
1305 String line;
1306 int count = 0;
1307 while (true) {
1308 synchronized (MyActivityController.this) {
1309 if (mGdbThread == null) {
1310 return;
1311 }
1312 if (count == 2) {
1313 mGotGdbPrint = true;
1314 MyActivityController.this.notifyAll();
1315 }
1316 }
1317 try {
1318 line = in.readLine();
1319 if (line == null) {
1320 return;
1321 }
1322 mPw.println("GDB: " + line);
1323 mPw.flush();
1324 count++;
1325 } catch (IOException e) {
1326 return;
1327 }
1328 }
1329 }
1330 };
1331 mGdbThread.start();
1332
1333 // Stupid waiting for .5s. Doesn't matter if we end early.
1334 try {
1335 this.wait(500);
1336 } catch (InterruptedException e) {
1337 }
1338
1339 } catch (IOException e) {
1340 mPw.println("Failure starting gdbserver: " + e);
1341 mPw.flush();
1342 killGdbLocked();
1343 }
1344 }
1345 mState = state;
1346 mPw.println("");
1347 printMessageForState();
1348 mPw.flush();
1349
1350 while (mState != STATE_NORMAL) {
1351 try {
1352 wait();
1353 } catch (InterruptedException e) {
1354 }
1355 }
1356
1357 killGdbLocked();
1358
1359 return mResult;
1360 }
1361
1362 void resumeController(int result) {
1363 synchronized (this) {
1364 mState = STATE_NORMAL;
1365 mResult = result;
1366 notifyAll();
1367 }
1368 }
1369
1370 void printMessageForState() {
1371 switch (mState) {
1372 case STATE_NORMAL:
1373 mPw.println("Monitoring activity manager... available commands:");
1374 break;
1375 case STATE_CRASHED:
1376 mPw.println("Waiting after crash... available commands:");
1377 mPw.println("(c)ontinue: show crash dialog");
1378 mPw.println("(k)ill: immediately kill app");
1379 break;
1380 case STATE_EARLY_ANR:
1381 mPw.println("Waiting after early ANR... available commands:");
1382 mPw.println("(c)ontinue: standard ANR processing");
1383 mPw.println("(k)ill: immediately kill app");
1384 break;
1385 case STATE_ANR:
1386 mPw.println("Waiting after ANR... available commands:");
1387 mPw.println("(c)ontinue: show ANR dialog");
1388 mPw.println("(k)ill: immediately kill app");
1389 mPw.println("(w)ait: wait some more");
1390 break;
1391 }
1392 mPw.println("(q)uit: finish monitoring");
1393 }
1394
1395 void run() throws RemoteException {
1396 try {
1397 printMessageForState();
1398 mPw.flush();
1399
1400 mInterface.setActivityController(this, mMonkey);
1401 mState = STATE_NORMAL;
1402
1403 InputStreamReader converter = new InputStreamReader(mInput);
1404 BufferedReader in = new BufferedReader(converter);
1405 String line;
1406
1407 while ((line = in.readLine()) != null) {
1408 boolean addNewline = true;
1409 if (line.length() <= 0) {
1410 addNewline = false;
1411 } else if ("q".equals(line) || "quit".equals(line)) {
1412 resumeController(RESULT_DEFAULT);
1413 break;
1414 } else if (mState == STATE_CRASHED) {
1415 if ("c".equals(line) || "continue".equals(line)) {
1416 resumeController(RESULT_CRASH_DIALOG);
1417 } else if ("k".equals(line) || "kill".equals(line)) {
1418 resumeController(RESULT_CRASH_KILL);
1419 } else {
1420 mPw.println("Invalid command: " + line);
1421 }
1422 } else if (mState == STATE_ANR) {
1423 if ("c".equals(line) || "continue".equals(line)) {
1424 resumeController(RESULT_ANR_DIALOG);
1425 } else if ("k".equals(line) || "kill".equals(line)) {
1426 resumeController(RESULT_ANR_KILL);
1427 } else if ("w".equals(line) || "wait".equals(line)) {
1428 resumeController(RESULT_ANR_WAIT);
1429 } else {
1430 mPw.println("Invalid command: " + line);
1431 }
1432 } else if (mState == STATE_EARLY_ANR) {
1433 if ("c".equals(line) || "continue".equals(line)) {
1434 resumeController(RESULT_EARLY_ANR_CONTINUE);
1435 } else if ("k".equals(line) || "kill".equals(line)) {
1436 resumeController(RESULT_EARLY_ANR_KILL);
1437 } else {
1438 mPw.println("Invalid command: " + line);
1439 }
1440 } else {
1441 mPw.println("Invalid command: " + line);
1442 }
1443
1444 synchronized (this) {
1445 if (addNewline) {
1446 mPw.println("");
1447 }
1448 printMessageForState();
1449 mPw.flush();
1450 }
1451 }
1452
1453 } catch (IOException e) {
1454 e.printStackTrace(mPw);
1455 mPw.flush();
1456 } finally {
1457 mInterface.setActivityController(null, mMonkey);
1458 }
1459 }
1460 }
1461
1462 int runMonitor(PrintWriter pw) throws RemoteException {
1463 String opt;
1464 String gdbPort = null;
1465 boolean monkey = false;
1466 while ((opt=getNextOption()) != null) {
1467 if (opt.equals("--gdb")) {
1468 gdbPort = getNextArgRequired();
1469 } else if (opt.equals("-m")) {
1470 monkey = true;
1471 } else {
1472 getErrPrintWriter().println("Error: Unknown option: " + opt);
1473 return -1;
1474 }
1475 }
1476
1477 MyActivityController controller = new MyActivityController(mInterface, pw,
1478 getRawInputStream(), gdbPort, monkey);
1479 controller.run();
1480 return 0;
1481 }
1482
Dianne Hackborne51505a2017-08-07 17:13:52 -07001483 static final class MyUidObserver extends IUidObserver.Stub
1484 implements ActivityManagerService.OomAdjObserver {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001485 final IActivityManager mInterface;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001486 final ActivityManagerService mInternal;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001487 final PrintWriter mPw;
1488 final InputStream mInput;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001489 final int mUid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001490
1491 static final int STATE_NORMAL = 0;
1492
1493 int mState;
1494
Dianne Hackborne51505a2017-08-07 17:13:52 -07001495 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
1496 mInterface = service;
1497 mInternal = service;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001498 mPw = pw;
1499 mInput = input;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001500 mUid = uid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001501 }
1502
1503 @Override
Hui Yu26969322019-08-21 14:56:35 -07001504 public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability)
1505 throws RemoteException {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001506 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001507 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1508 try {
1509 mPw.print(uid);
1510 mPw.print(" procstate ");
1511 mPw.print(ProcessList.makeProcStateString(procState));
1512 mPw.print(" seq ");
Hui Yu26969322019-08-21 14:56:35 -07001513 mPw.print(procStateSeq);
1514 mPw.print(" capability ");
1515 mPw.println(capability);
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001516 mPw.flush();
1517 } finally {
1518 StrictMode.setThreadPolicy(oldPolicy);
1519 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001520 }
1521 }
1522
1523 @Override
1524 public void onUidGone(int uid, boolean disabled) throws RemoteException {
1525 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001526 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1527 try {
1528 mPw.print(uid);
1529 mPw.print(" gone");
1530 if (disabled) {
1531 mPw.print(" disabled");
1532 }
1533 mPw.println();
1534 mPw.flush();
1535 } finally {
1536 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001537 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001538 }
1539 }
1540
1541 @Override
1542 public void onUidActive(int uid) throws RemoteException {
1543 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001544 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1545 try {
1546 mPw.print(uid);
1547 mPw.println(" active");
1548 mPw.flush();
1549 } finally {
1550 StrictMode.setThreadPolicy(oldPolicy);
1551 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001552 }
1553 }
1554
1555 @Override
1556 public void onUidIdle(int uid, boolean disabled) throws RemoteException {
1557 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001558 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1559 try {
1560 mPw.print(uid);
1561 mPw.print(" idle");
1562 if (disabled) {
1563 mPw.print(" disabled");
1564 }
1565 mPw.println();
1566 mPw.flush();
1567 } finally {
1568 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001569 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001570 }
1571 }
1572
1573 @Override
1574 public void onUidCachedChanged(int uid, boolean cached) throws RemoteException {
1575 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001576 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1577 try {
1578 mPw.print(uid);
1579 mPw.println(cached ? " cached" : " uncached");
1580 mPw.flush();
1581 } finally {
1582 StrictMode.setThreadPolicy(oldPolicy);
1583 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001584 }
1585 }
1586
Dianne Hackborne51505a2017-08-07 17:13:52 -07001587 @Override
1588 public void onOomAdjMessage(String msg) {
1589 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001590 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1591 try {
1592 mPw.print("# ");
1593 mPw.println(msg);
1594 mPw.flush();
1595 } finally {
1596 StrictMode.setThreadPolicy(oldPolicy);
1597 }
Dianne Hackborne51505a2017-08-07 17:13:52 -07001598 }
1599 }
1600
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001601 void printMessageForState() {
1602 switch (mState) {
1603 case STATE_NORMAL:
1604 mPw.println("Watching uid states... available commands:");
1605 break;
1606 }
1607 mPw.println("(q)uit: finish watching");
1608 }
1609
1610 void run() throws RemoteException {
1611 try {
1612 printMessageForState();
1613 mPw.flush();
1614
1615 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE
1616 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
1617 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
1618 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackborne51505a2017-08-07 17:13:52 -07001619 if (mUid >= 0) {
1620 mInternal.setOomAdjObserver(mUid, this);
1621 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001622 mState = STATE_NORMAL;
1623
1624 InputStreamReader converter = new InputStreamReader(mInput);
1625 BufferedReader in = new BufferedReader(converter);
1626 String line;
1627
1628 while ((line = in.readLine()) != null) {
1629 boolean addNewline = true;
1630 if (line.length() <= 0) {
1631 addNewline = false;
1632 } else if ("q".equals(line) || "quit".equals(line)) {
1633 break;
1634 } else {
1635 mPw.println("Invalid command: " + line);
1636 }
1637
1638 synchronized (this) {
1639 if (addNewline) {
1640 mPw.println("");
1641 }
1642 printMessageForState();
1643 mPw.flush();
1644 }
1645 }
1646
1647 } catch (IOException e) {
1648 e.printStackTrace(mPw);
1649 mPw.flush();
1650 } finally {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001651 if (mUid >= 0) {
1652 mInternal.clearOomAdjObserver();
1653 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001654 mInterface.unregisterUidObserver(this);
1655 }
1656 }
1657 }
1658
1659 int runWatchUids(PrintWriter pw) throws RemoteException {
1660 String opt;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001661 int uid = -1;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001662 while ((opt=getNextOption()) != null) {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001663 if (opt.equals("--oom")) {
1664 uid = Integer.parseInt(getNextArgRequired());
1665 } else {
1666 getErrPrintWriter().println("Error: Unknown option: " + opt);
1667 return -1;
1668
1669 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001670 }
1671
Dianne Hackborne51505a2017-08-07 17:13:52 -07001672 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001673 controller.run();
1674 return 0;
1675 }
1676
Dianne Hackborn331084d2016-10-07 17:57:00 -07001677 int runHang(PrintWriter pw) throws RemoteException {
1678 String opt;
1679 boolean allowRestart = false;
1680 while ((opt=getNextOption()) != null) {
1681 if (opt.equals("--allow-restart")) {
1682 allowRestart = true;
1683 } else {
1684 getErrPrintWriter().println("Error: Unknown option: " + opt);
1685 return -1;
1686 }
1687 }
1688
1689 pw.println("Hanging the system...");
1690 pw.flush();
1691 mInterface.hang(new Binder(), allowRestart);
1692 return 0;
1693 }
1694
1695 int runRestart(PrintWriter pw) throws RemoteException {
1696 String opt;
1697 while ((opt=getNextOption()) != null) {
1698 getErrPrintWriter().println("Error: Unknown option: " + opt);
1699 return -1;
1700 }
1701
1702 pw.println("Restart the system...");
1703 pw.flush();
1704 mInterface.restart();
1705 return 0;
1706 }
1707
1708 int runIdleMaintenance(PrintWriter pw) throws RemoteException {
1709 String opt;
1710 while ((opt=getNextOption()) != null) {
1711 getErrPrintWriter().println("Error: Unknown option: " + opt);
1712 return -1;
1713 }
1714
1715 pw.println("Performing idle maintenance...");
1716 mInterface.sendIdleJobTrigger();
1717 return 0;
1718 }
1719
1720 int runScreenCompat(PrintWriter pw) throws RemoteException {
1721 String mode = getNextArgRequired();
1722 boolean enabled;
1723 if ("on".equals(mode)) {
1724 enabled = true;
1725 } else if ("off".equals(mode)) {
1726 enabled = false;
1727 } else {
1728 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode);
1729 return -1;
1730 }
1731
1732 String packageName = getNextArgRequired();
1733 do {
1734 try {
1735 mInterface.setPackageScreenCompatMode(packageName, enabled
1736 ? ActivityManager.COMPAT_MODE_ENABLED
1737 : ActivityManager.COMPAT_MODE_DISABLED);
1738 } catch (RemoteException e) {
1739 }
1740 packageName = getNextArg();
1741 } while (packageName != null);
1742 return 0;
1743 }
1744
1745 int runPackageImportance(PrintWriter pw) throws RemoteException {
1746 String packageName = getNextArgRequired();
1747 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell");
1748 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
1749 return 0;
1750 }
1751
1752 int runToUri(PrintWriter pw, int flags) throws RemoteException {
1753 Intent intent;
1754 try {
1755 intent = makeIntent(UserHandle.USER_CURRENT);
1756 } catch (URISyntaxException e) {
1757 throw new RuntimeException(e.getMessage(), e);
1758 }
1759 pw.println(intent.toUri(flags));
1760 return 0;
1761 }
1762
Felipe Leme75aeb682020-01-21 14:22:14 -08001763 private boolean switchUserAndWaitForComplete(int userId) throws RemoteException {
jovanake2043612019-10-31 16:49:24 -07001764 // Register switch observer.
1765 final CountDownLatch switchLatch = new CountDownLatch(1);
1766 mInterface.registerUserSwitchObserver(
1767 new UserSwitchObserver() {
1768 @Override
1769 public void onUserSwitchComplete(int newUserId) {
1770 if (userId == newUserId) {
1771 switchLatch.countDown();
1772 }
1773 }
1774 }, ActivityManagerShellCommand.class.getName());
1775
1776 // Switch.
Felipe Leme75aeb682020-01-21 14:22:14 -08001777 boolean switched = mInterface.switchUser(userId);
jovanake2043612019-10-31 16:49:24 -07001778
1779 // Wait.
1780 try {
1781 switchLatch.await(USER_OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
1782 } catch (InterruptedException e) {
1783 getErrPrintWriter().println("Thread interrupted unexpectedly.");
1784 }
Felipe Leme75aeb682020-01-21 14:22:14 -08001785 return switched;
jovanake2043612019-10-31 16:49:24 -07001786 }
1787
Dianne Hackborn331084d2016-10-07 17:57:00 -07001788 int runSwitchUser(PrintWriter pw) throws RemoteException {
Alex Chau5c0df232018-02-22 15:57:17 +08001789 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
Varun Shah50ef2002019-03-04 16:41:12 -08001790 final int userSwitchable = userManager.getUserSwitchability();
1791 if (userSwitchable != UserManager.SWITCHABILITY_STATUS_OK) {
1792 getErrPrintWriter().println("Error: " + userSwitchable);
Alex Chau5c0df232018-02-22 15:57:17 +08001793 return -1;
1794 }
jovanake2043612019-10-31 16:49:24 -07001795 boolean wait = false;
1796 String opt;
1797 while ((opt = getNextOption()) != null) {
1798 if ("-w".equals(opt)) {
1799 wait = true;
1800 } else {
1801 getErrPrintWriter().println("Error: unknown option: " + opt);
1802 return -1;
1803 }
1804 }
1805
1806 int userId = Integer.parseInt(getNextArgRequired());
Felipe Leme75aeb682020-01-21 14:22:14 -08001807 boolean switched;
jovanake2043612019-10-31 16:49:24 -07001808 if (wait) {
Felipe Leme75aeb682020-01-21 14:22:14 -08001809 switched = switchUserAndWaitForComplete(userId);
jovanake2043612019-10-31 16:49:24 -07001810 } else {
Felipe Leme75aeb682020-01-21 14:22:14 -08001811 switched = mInterface.switchUser(userId);
jovanake2043612019-10-31 16:49:24 -07001812 }
Felipe Leme75aeb682020-01-21 14:22:14 -08001813 if (switched) {
1814 return 0;
1815 } else {
1816 pw.printf("Failed to switch to user %d\n", userId);
1817 return 1;
1818 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001819 }
1820
1821 int runGetCurrentUser(PrintWriter pw) throws RemoteException {
Daulet Zhanguzin44eeff32020-01-03 09:44:46 +00001822 UserInfo currentUser = Objects.requireNonNull(mInterface.getCurrentUser(),
Dianne Hackborn331084d2016-10-07 17:57:00 -07001823 "Current user not set");
1824 pw.println(currentUser.id);
1825 return 0;
1826 }
1827
1828 int runStartUser(PrintWriter pw) throws RemoteException {
Bookatz03bfe6f2019-03-01 15:46:04 -08001829 boolean wait = false;
1830 String opt;
1831 while ((opt = getNextOption()) != null) {
1832 if ("-w".equals(opt)) {
1833 wait = true;
1834 } else {
1835 getErrPrintWriter().println("Error: unknown option: " + opt);
1836 return -1;
1837 }
1838 }
1839 int userId = Integer.parseInt(getNextArgRequired());
1840
1841 final ProgressWaiter waiter = wait ? new ProgressWaiter() : null;
1842 boolean success = mInterface.startUserInBackgroundWithListener(userId, waiter);
1843 if (wait && success) {
1844 success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS);
1845 }
1846
Dianne Hackborn331084d2016-10-07 17:57:00 -07001847 if (success) {
1848 pw.println("Success: user started");
1849 } else {
1850 getErrPrintWriter().println("Error: could not start user");
1851 }
1852 return 0;
1853 }
1854
1855 private static byte[] argToBytes(String arg) {
1856 if (arg.equals("!")) {
1857 return null;
1858 } else {
1859 return HexDump.hexStringToByteArray(arg);
1860 }
1861 }
1862
1863 int runUnlockUser(PrintWriter pw) throws RemoteException {
1864 int userId = Integer.parseInt(getNextArgRequired());
1865 byte[] token = argToBytes(getNextArgRequired());
1866 byte[] secret = argToBytes(getNextArgRequired());
1867 boolean success = mInterface.unlockUser(userId, token, secret, null);
1868 if (success) {
1869 pw.println("Success: user unlocked");
1870 } else {
1871 getErrPrintWriter().println("Error: could not unlock user");
1872 }
1873 return 0;
1874 }
1875
1876 static final class StopUserCallback extends IStopUserCallback.Stub {
1877 private boolean mFinished = false;
1878
1879 public synchronized void waitForFinish() {
1880 try {
1881 while (!mFinished) wait();
1882 } catch (InterruptedException e) {
1883 throw new IllegalStateException(e);
1884 }
1885 }
1886
1887 @Override
1888 public synchronized void userStopped(int userId) {
1889 mFinished = true;
1890 notifyAll();
1891 }
1892
1893 @Override
1894 public synchronized void userStopAborted(int userId) {
1895 mFinished = true;
1896 notifyAll();
1897 }
1898 }
1899
1900 int runStopUser(PrintWriter pw) throws RemoteException {
1901 boolean wait = false;
1902 boolean force = false;
1903 String opt;
1904 while ((opt = getNextOption()) != null) {
1905 if ("-w".equals(opt)) {
1906 wait = true;
1907 } else if ("-f".equals(opt)) {
1908 force = true;
1909 } else {
1910 getErrPrintWriter().println("Error: unknown option: " + opt);
1911 return -1;
1912 }
1913 }
1914 int user = Integer.parseInt(getNextArgRequired());
1915 StopUserCallback callback = wait ? new StopUserCallback() : null;
1916
1917 int res = mInterface.stopUser(user, force, callback);
1918 if (res != ActivityManager.USER_OP_SUCCESS) {
1919 String txt = "";
1920 switch (res) {
1921 case ActivityManager.USER_OP_IS_CURRENT:
1922 txt = " (Can't stop current user)";
1923 break;
1924 case ActivityManager.USER_OP_UNKNOWN_USER:
1925 txt = " (Unknown user " + user + ")";
1926 break;
1927 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
1928 txt = " (System user cannot be stopped)";
1929 break;
1930 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP:
1931 txt = " (Can't stop user " + user
1932 + " - one of its related users can't be stopped)";
1933 break;
1934 }
1935 getErrPrintWriter().println("Switch failed: " + res + txt);
1936 return -1;
1937 } else if (callback != null) {
1938 callback.waitForFinish();
1939 }
1940 return 0;
1941 }
1942
1943 int runIsUserStopped(PrintWriter pw) {
1944 int userId = UserHandle.parseUserArg(getNextArgRequired());
1945 boolean stopped = mInternal.isUserStopped(userId);
1946 pw.println(stopped);
1947 return 0;
1948 }
1949
1950 int runGetStartedUserState(PrintWriter pw) throws RemoteException {
1951 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1952 "runGetStartedUserState()");
1953 final int userId = Integer.parseInt(getNextArgRequired());
1954 try {
1955 pw.println(mInternal.getStartedUserState(userId));
1956 } catch (NullPointerException e) {
1957 pw.println("User is not started: " + userId);
1958 }
Dianne Hackborn2e441072015-10-28 18:00:57 -07001959 return 0;
1960 }
1961
1962 int runTrackAssociations(PrintWriter pw) {
1963 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Makoto Onukid5e74ed2019-01-31 15:50:18 -08001964 "runTrackAssociations()");
Dianne Hackborn2e441072015-10-28 18:00:57 -07001965 synchronized (mInternal) {
1966 if (!mInternal.mTrackingAssociations) {
1967 mInternal.mTrackingAssociations = true;
1968 pw.println("Association tracking started.");
1969 } else {
1970 pw.println("Association tracking already enabled.");
1971 }
1972 }
1973 return 0;
1974 }
1975
1976 int runUntrackAssociations(PrintWriter pw) {
1977 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Makoto Onukid5e74ed2019-01-31 15:50:18 -08001978 "runUntrackAssociations()");
Dianne Hackborn2e441072015-10-28 18:00:57 -07001979 synchronized (mInternal) {
1980 if (mInternal.mTrackingAssociations) {
1981 mInternal.mTrackingAssociations = false;
1982 mInternal.mAssociations.clear();
1983 pw.println("Association tracking stopped.");
1984 } else {
1985 pw.println("Association tracking not running.");
1986 }
1987 }
1988 return 0;
1989 }
1990
Felipe Leme2f1b2272016-03-25 16:15:02 -07001991 int getUidState(PrintWriter pw) throws RemoteException {
1992 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1993 "getUidState()");
1994 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
1995 pw.print(state);
1996 pw.print(" (");
1997 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
1998 pw.println(")");
1999 return 0;
2000 }
2001
Dianne Hackborn331084d2016-10-07 17:57:00 -07002002 private List<Configuration> getRecentConfigurations(int days) {
2003 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2004 Context.USAGE_STATS_SERVICE));
2005 final long now = System.currentTimeMillis();
2006 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
Sudheer Shanka28537b62016-09-07 11:12:31 -07002007 try {
Dianne Hackborn331084d2016-10-07 17:57:00 -07002008 @SuppressWarnings("unchecked")
2009 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
2010 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
2011 if (configStatsSlice == null) {
2012 return Collections.emptyList();
2013 }
2014
2015 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
2016 final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
2017 final int configStatsListSize = configStatsList.size();
2018 for (int i = 0; i < configStatsListSize; i++) {
2019 final ConfigurationStats stats = configStatsList.get(i);
2020 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
2021 if (indexOfKey < 0) {
2022 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
2023 } else {
2024 recentConfigs.setValueAt(indexOfKey,
2025 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
2026 }
2027 }
2028
2029 final Comparator<Configuration> comparator = new Comparator<Configuration>() {
2030 @Override
2031 public int compare(Configuration a, Configuration b) {
2032 return recentConfigs.get(b).compareTo(recentConfigs.get(a));
2033 }
2034 };
2035
2036 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
2037 configs.addAll(recentConfigs.keySet());
2038 Collections.sort(configs, comparator);
2039 return configs;
2040
2041 } catch (RemoteException e) {
2042 return Collections.emptyList();
Sudheer Shanka28537b62016-09-07 11:12:31 -07002043 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002044 }
2045
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002046 /**
2047 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
2048 * and EGLSurface and querying extensions.
2049 *
2050 * @param egl An EGL API object
2051 * @param display An EGLDisplay to create a context and surface with
2052 * @param config The EGLConfig to get the extensions for
2053 * @param surfaceSize eglCreatePbufferSurface generic parameters
2054 * @param contextAttribs eglCreateContext generic parameters
2055 * @param glExtensions A Set<String> to add GL extensions to
2056 */
2057 private static void addExtensionsForConfig(
2058 EGL10 egl,
2059 EGLDisplay display,
2060 EGLConfig config,
2061 int[] surfaceSize,
2062 int[] contextAttribs,
2063 Set<String> glExtensions) {
2064 // Create a context.
2065 EGLContext context =
2066 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
2067 // No-op if we can't create a context.
2068 if (context == EGL10.EGL_NO_CONTEXT) {
2069 return;
2070 }
2071
2072 // Create a surface.
2073 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
2074 if (surface == EGL10.EGL_NO_SURFACE) {
2075 egl.eglDestroyContext(display, context);
2076 return;
2077 }
2078
2079 // Update the current surface and context.
2080 egl.eglMakeCurrent(display, surface, surface, context);
2081
2082 // Get the list of extensions.
2083 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
2084 if (!TextUtils.isEmpty(extensionList)) {
2085 // The list of extensions comes from the driver separated by spaces.
2086 // Split them apart and add them into a Set for deduping purposes.
2087 for (String extension : extensionList.split(" ")) {
2088 glExtensions.add(extension);
2089 }
2090 }
2091
2092 // Tear down the context and surface for this config.
2093 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
2094 egl.eglDestroySurface(display, surface);
2095 egl.eglDestroyContext(display, context);
2096 }
2097
2098
2099 Set<String> getGlExtensionsFromDriver() {
2100 Set<String> glExtensions = new HashSet<>();
2101
2102 // Get the EGL implementation.
2103 EGL10 egl = (EGL10) EGLContext.getEGL();
2104 if (egl == null) {
2105 getErrPrintWriter().println("Warning: couldn't get EGL");
2106 return glExtensions;
2107 }
2108
2109 // Get the default display and initialize it.
2110 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
2111 int[] version = new int[2];
2112 egl.eglInitialize(display, version);
2113
2114 // Call getConfigs() in order to find out how many there are.
2115 int[] numConfigs = new int[1];
2116 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
2117 getErrPrintWriter().println("Warning: couldn't get EGL config count");
2118 return glExtensions;
2119 }
2120
2121 // Allocate space for all configs and ask again.
2122 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
2123 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
2124 getErrPrintWriter().println("Warning: couldn't get EGL configs");
2125 return glExtensions;
2126 }
2127
2128 // Allocate surface size parameters outside of the main loop to cut down
2129 // on GC thrashing. 1x1 is enough since we are only using it to get at
2130 // the list of extensions.
2131 int[] surfaceSize =
2132 new int[] {
2133 EGL10.EGL_WIDTH, 1,
2134 EGL10.EGL_HEIGHT, 1,
2135 EGL10.EGL_NONE
2136 };
2137
2138 // For when we need to create a GLES2.0 context.
2139 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
2140 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
2141
2142 // For getting return values from eglGetConfigAttrib
2143 int[] attrib = new int[1];
2144
2145 for (int i = 0; i < numConfigs[0]; i++) {
2146 // Get caveat for this config in order to skip slow (i.e. software) configs.
2147 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
2148 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
2149 continue;
2150 }
2151
2152 // If the config does not support pbuffers we cannot do an eglMakeCurrent
2153 // on it in addExtensionsForConfig(), so skip it here. Attempting to make
2154 // it current with a pbuffer will result in an EGL_BAD_MATCH error
2155 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
2156 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
2157 continue;
2158 }
2159
2160 final int EGL_OPENGL_ES_BIT = 0x0001;
2161 final int EGL_OPENGL_ES2_BIT = 0x0004;
2162 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
2163 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
2164 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
2165 }
2166 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
2167 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
2168 }
2169 }
2170
2171 // Release all EGL resources.
2172 egl.eglTerminate(display);
2173
2174 return glExtensions;
2175 }
2176
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002177 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
Jeff Change9467b22018-09-28 11:40:38 +08002178 PrintWriter pw, Configuration config, DisplayMetrics displayMetrics) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002179 long token = -1;
2180 if (protoOutputStream != null) {
2181 token = protoOutputStream.start(fieldId);
Jeff Change9467b22018-09-28 11:40:38 +08002182 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX,
2183 displayMetrics.widthPixels);
2184 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX,
2185 displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002186 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI,
2187 DisplayMetrics.DENSITY_DEVICE_STABLE);
2188 }
2189 if (pw != null) {
Jeff Change9467b22018-09-28 11:40:38 +08002190 pw.print("stable-width-px: "); pw.println(displayMetrics.widthPixels);
2191 pw.print("stable-height-px: "); pw.println(displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002192 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE);
2193 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002194
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002195 MemInfoReader memreader = new MemInfoReader();
2196 memreader.readMemInfo();
2197 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class);
2198 if (protoOutputStream != null) {
2199 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize());
2200 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM,
2201 ActivityManager.isLowRamDeviceStatic());
2202 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES,
2203 Runtime.getRuntime().availableProcessors());
2204 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK,
2205 kgm.isDeviceSecure());
2206 }
2207 if (pw != null) {
2208 pw.print("total-ram: "); pw.println(memreader.getTotalSize());
2209 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic());
2210 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors());
2211 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
2212 }
2213
Yunfan Chen75157d72018-07-27 14:47:21 +09002214 ConfigurationInfo configInfo = null;
2215 try {
2216 configInfo = mTaskInterface.getDeviceConfigurationInfo();
2217 } catch (RemoteException e) {
2218 throw e.rethrowFromSystemServer();
2219 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002220 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
2221 if (protoOutputStream != null) {
2222 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
2223 configInfo.reqGlEsVersion);
2224 }
2225 if (pw != null) {
2226 pw.print("opengl-version: 0x");
2227 pw.println(Integer.toHexString(configInfo.reqGlEsVersion));
2228 }
2229 }
2230
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002231 Set<String> glExtensionsSet = getGlExtensionsFromDriver();
2232 String[] glExtensions = new String[glExtensionsSet.size()];
2233 glExtensions = glExtensionsSet.toArray(glExtensions);
2234 Arrays.sort(glExtensions);
2235 for (int i = 0; i < glExtensions.length; i++) {
2236 if (protoOutputStream != null) {
2237 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
2238 glExtensions[i]);
2239 }
2240 if (pw != null) {
2241 pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
2242 }
2243
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002244 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002245
2246 PackageManager pm = mInternal.mContext.getPackageManager();
2247 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002248 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002249 for (int i = 0; i < slibs.size(); i++) {
2250 if (protoOutputStream != null) {
2251 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
2252 slibs.get(i).getName());
2253 }
2254 if (pw != null) {
2255 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName());
2256 }
2257 }
2258
2259 FeatureInfo[] features = pm.getSystemAvailableFeatures();
weijuncheng12030002018-10-30 14:07:53 +08002260 Arrays.sort(features, (o1, o2) -> {
2261 if (o1.name == o2.name) return 0;
2262 if (o1.name == null) return -1;
2263 if (o2.name == null) return 1;
2264 return o1.name.compareTo(o2.name);
2265 });
2266
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002267 for (int i = 0; i < features.length; i++) {
2268 if (features[i].name != null) {
2269 if (protoOutputStream != null) {
2270 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name);
2271 }
2272 if (pw != null) {
2273 pw.print("features: "); pw.println(features[i].name);
2274 }
2275 }
2276 }
2277
2278 if (protoOutputStream != null) {
2279 protoOutputStream.end(token);
2280 }
2281 }
2282
2283 int runGetConfig(PrintWriter pw) throws RemoteException {
2284 int days = -1;
Jeff Change9467b22018-09-28 11:40:38 +08002285 int displayId = Display.DEFAULT_DISPLAY;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002286 boolean asProto = false;
2287 boolean inclDevice = false;
2288
2289 String opt;
Jeff Change9467b22018-09-28 11:40:38 +08002290 while ((opt = getNextOption()) != null) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002291 if (opt.equals("--days")) {
2292 days = Integer.parseInt(getNextArgRequired());
2293 if (days <= 0) {
2294 throw new IllegalArgumentException("--days must be a positive integer");
2295 }
2296 } else if (opt.equals("--proto")) {
2297 asProto = true;
2298 } else if (opt.equals("--device")) {
2299 inclDevice = true;
Jeff Change9467b22018-09-28 11:40:38 +08002300 } else if (opt.equals("--display")) {
2301 displayId = Integer.parseInt(getNextArgRequired());
2302 if (displayId < 0) {
2303 throw new IllegalArgumentException("--display must be a non-negative integer");
2304 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002305 } else {
2306 getErrPrintWriter().println("Error: Unknown option: " + opt);
2307 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -07002308 }
2309 }
2310
2311 Configuration config = mInterface.getConfiguration();
2312 if (config == null) {
2313 getErrPrintWriter().println("Activity manager has no configuration");
2314 return -1;
2315 }
2316
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002317 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class);
Jeff Change9467b22018-09-28 11:40:38 +08002318 Display display = dm.getDisplay(displayId);
2319
2320 if (display == null) {
2321 getErrPrintWriter().println("Error: Display does not exist: " + displayId);
2322 return -1;
2323 }
2324
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002325 DisplayMetrics metrics = new DisplayMetrics();
2326 display.getMetrics(metrics);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002327
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002328 if (asProto) {
2329 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor());
2330 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics);
2331 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002332 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002333 }
2334 proto.flush();
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002335 } else {
2336 pw.println("config: " + Configuration.resourceQualifierString(config, metrics));
2337 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
2338 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002339 writeDeviceConfig(null, -1, pw, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002340 }
2341
2342 if (days >= 0) {
2343 final List<Configuration> recentConfigs = getRecentConfigurations(days);
2344 final int recentConfigSize = recentConfigs.size();
2345 if (recentConfigSize > 0) {
2346 pw.println("recentConfigs:");
2347 for (int i = 0; i < recentConfigSize; i++) {
2348 pw.println(" config: " + Configuration.resourceQualifierString(
2349 recentConfigs.get(i)));
2350 }
2351 }
2352 }
2353
Dianne Hackborn331084d2016-10-07 17:57:00 -07002354 }
2355 return 0;
2356 }
2357
2358 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
2359 boolean suppress = Boolean.valueOf(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002360 mTaskInterface.suppressResizeConfigChanges(suppress);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002361 return 0;
2362 }
2363
2364 int runSetInactive(PrintWriter pw) throws RemoteException {
2365 int userId = UserHandle.USER_CURRENT;
2366
2367 String opt;
2368 while ((opt=getNextOption()) != null) {
2369 if (opt.equals("--user")) {
2370 userId = UserHandle.parseUserArg(getNextArgRequired());
2371 } else {
2372 getErrPrintWriter().println("Error: Unknown option: " + opt);
2373 return -1;
2374 }
2375 }
2376 String packageName = getNextArgRequired();
2377 String value = getNextArgRequired();
2378
2379 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2380 Context.USAGE_STATS_SERVICE));
2381 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId);
2382 return 0;
2383 }
2384
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002385 private int bucketNameToBucketValue(String name) {
2386 String lower = name.toLowerCase();
2387 if (lower.startsWith("ac")) {
2388 return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
2389 } else if (lower.startsWith("wo")) {
2390 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
2391 } else if (lower.startsWith("fr")) {
2392 return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
2393 } else if (lower.startsWith("ra")) {
2394 return UsageStatsManager.STANDBY_BUCKET_RARE;
Kweku Adamsc6a9b342020-01-08 18:37:26 -08002395 } else if (lower.startsWith("re")) {
2396 return UsageStatsManager.STANDBY_BUCKET_RESTRICTED;
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002397 } else if (lower.startsWith("ne")) {
2398 return UsageStatsManager.STANDBY_BUCKET_NEVER;
2399 } else {
2400 try {
2401 int bucket = Integer.parseInt(lower);
2402 return bucket;
2403 } catch (NumberFormatException nfe) {
2404 getErrPrintWriter().println("Error: Unknown bucket: " + name);
2405 }
2406 }
2407 return -1;
2408 }
2409
Amith Yamasani17fffee2017-09-29 13:17:43 -07002410 int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
2411 int userId = UserHandle.USER_CURRENT;
2412
2413 String opt;
2414 while ((opt=getNextOption()) != null) {
2415 if (opt.equals("--user")) {
2416 userId = UserHandle.parseUserArg(getNextArgRequired());
2417 } else {
2418 getErrPrintWriter().println("Error: Unknown option: " + opt);
2419 return -1;
2420 }
2421 }
2422 String packageName = getNextArgRequired();
2423 String value = getNextArgRequired();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002424 int bucket = bucketNameToBucketValue(value);
2425 if (bucket < 0) return -1;
Amith Yamasanie8789312017-12-10 14:34:26 -08002426 boolean multiple = peekNextArg() != null;
2427
Amith Yamasani17fffee2017-09-29 13:17:43 -07002428
2429 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2430 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002431 if (!multiple) {
2432 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
2433 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002434 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
2435 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002436 while ((packageName = getNextArg()) != null) {
2437 value = getNextArgRequired();
2438 bucket = bucketNameToBucketValue(value);
2439 if (bucket < 0) continue;
Suprabh Shukla868bde22018-02-20 20:59:52 -08002440 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002441 }
Suprabh Shukla868bde22018-02-20 20:59:52 -08002442 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
2443 usm.setAppStandbyBuckets(slice, userId);
Amith Yamasanie8789312017-12-10 14:34:26 -08002444 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002445 return 0;
2446 }
2447
2448 int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
2449 int userId = UserHandle.USER_CURRENT;
2450
2451 String opt;
2452 while ((opt=getNextOption()) != null) {
2453 if (opt.equals("--user")) {
2454 userId = UserHandle.parseUserArg(getNextArgRequired());
2455 } else {
2456 getErrPrintWriter().println("Error: Unknown option: " + opt);
2457 return -1;
2458 }
2459 }
Amith Yamasanie8789312017-12-10 14:34:26 -08002460 String packageName = getNextArg();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002461
2462 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2463 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002464 if (packageName != null) {
2465 int bucket = usm.getAppStandbyBucket(packageName, null, userId);
2466 pw.println(bucket);
2467 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002468 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -08002469 SHELL_PACKAGE_NAME, userId);
Suprabh Shukla868bde22018-02-20 20:59:52 -08002470 for (AppStandbyInfo bucketInfo : buckets.getList()) {
2471 pw.print(bucketInfo.mPackageName); pw.print(": ");
2472 pw.println(bucketInfo.mStandbyBucket);
Amith Yamasanie8789312017-12-10 14:34:26 -08002473 }
2474 }
Amith Yamasani17fffee2017-09-29 13:17:43 -07002475 return 0;
2476 }
2477
Dianne Hackborn331084d2016-10-07 17:57:00 -07002478 int runGetInactive(PrintWriter pw) throws RemoteException {
2479 int userId = UserHandle.USER_CURRENT;
2480
2481 String opt;
2482 while ((opt=getNextOption()) != null) {
2483 if (opt.equals("--user")) {
2484 userId = UserHandle.parseUserArg(getNextArgRequired());
2485 } else {
2486 getErrPrintWriter().println("Error: Unknown option: " + opt);
2487 return -1;
2488 }
2489 }
2490 String packageName = getNextArgRequired();
2491
2492 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2493 Context.USAGE_STATS_SERVICE));
2494 boolean isIdle = usm.isAppInactive(packageName, userId);
2495 pw.println("Idle=" + isIdle);
2496 return 0;
2497 }
2498
2499 int runSendTrimMemory(PrintWriter pw) throws RemoteException {
2500 int userId = UserHandle.USER_CURRENT;
2501 String opt;
2502 while ((opt = getNextOption()) != null) {
2503 if (opt.equals("--user")) {
2504 userId = UserHandle.parseUserArg(getNextArgRequired());
2505 if (userId == UserHandle.USER_ALL) {
2506 getErrPrintWriter().println("Error: Can't use user 'all'");
2507 return -1;
2508 }
2509 } else {
2510 getErrPrintWriter().println("Error: Unknown option: " + opt);
2511 return -1;
2512 }
2513 }
2514
2515 String proc = getNextArgRequired();
2516 String levelArg = getNextArgRequired();
2517 int level;
2518 switch (levelArg) {
2519 case "HIDDEN":
2520 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
2521 break;
2522 case "RUNNING_MODERATE":
2523 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
2524 break;
2525 case "BACKGROUND":
2526 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
2527 break;
2528 case "RUNNING_LOW":
2529 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
2530 break;
2531 case "MODERATE":
2532 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
2533 break;
2534 case "RUNNING_CRITICAL":
2535 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
2536 break;
2537 case "COMPLETE":
2538 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
2539 break;
2540 default:
Dianne Hackborne51505a2017-08-07 17:13:52 -07002541 try {
2542 level = Integer.parseInt(levelArg);
2543 } catch (NumberFormatException e) {
2544 getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
2545 return -1;
2546 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002547 }
2548 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
2549 getErrPrintWriter().println("Unknown error: failed to set trim level");
2550 return -1;
2551 }
2552 return 0;
2553 }
2554
Andrii Kulian839def92016-11-02 10:58:58 -07002555 int runDisplay(PrintWriter pw) throws RemoteException {
2556 String op = getNextArgRequired();
2557 switch (op) {
2558 case "move-stack":
2559 return runDisplayMoveStack(pw);
2560 default:
2561 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2562 return -1;
2563 }
2564 }
2565
Dianne Hackborn331084d2016-10-07 17:57:00 -07002566 int runStack(PrintWriter pw) throws RemoteException {
2567 String op = getNextArgRequired();
2568 switch (op) {
Andrii Kulian839def92016-11-02 10:58:58 -07002569 case "move-task":
Dianne Hackborn331084d2016-10-07 17:57:00 -07002570 return runStackMoveTask(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002571 case "resize-animated":
2572 return runStackResizeAnimated(pw);
2573 case "resize-docked-stack":
2574 return runStackResizeDocked(pw);
2575 case "positiontask":
2576 return runStackPositionTask(pw);
2577 case "list":
2578 return runStackList(pw);
2579 case "info":
2580 return runStackInfo(pw);
2581 case "move-top-activity-to-pinned-stack":
2582 return runMoveTopActivityToPinnedStack(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002583 case "remove":
2584 return runStackRemove(pw);
2585 default:
2586 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2587 return -1;
2588 }
2589 }
2590
2591
2592 private Rect getBounds() {
2593 String leftStr = getNextArgRequired();
2594 int left = Integer.parseInt(leftStr);
2595 String topStr = getNextArgRequired();
2596 int top = Integer.parseInt(topStr);
2597 String rightStr = getNextArgRequired();
2598 int right = Integer.parseInt(rightStr);
2599 String bottomStr = getNextArgRequired();
2600 int bottom = Integer.parseInt(bottomStr);
2601 if (left < 0) {
2602 getErrPrintWriter().println("Error: bad left arg: " + leftStr);
2603 return null;
2604 }
2605 if (top < 0) {
2606 getErrPrintWriter().println("Error: bad top arg: " + topStr);
2607 return null;
2608 }
2609 if (right <= 0) {
2610 getErrPrintWriter().println("Error: bad right arg: " + rightStr);
2611 return null;
2612 }
2613 if (bottom <= 0) {
2614 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr);
2615 return null;
2616 }
2617 return new Rect(left, top, right, bottom);
2618 }
2619
Andrii Kulian839def92016-11-02 10:58:58 -07002620 int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
2621 String stackIdStr = getNextArgRequired();
2622 int stackId = Integer.parseInt(stackIdStr);
2623 String displayIdStr = getNextArgRequired();
2624 int displayId = Integer.parseInt(displayIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002625 mTaskInterface.moveStackToDisplay(stackId, displayId);
Andrii Kulian839def92016-11-02 10:58:58 -07002626 return 0;
2627 }
2628
Dianne Hackborn331084d2016-10-07 17:57:00 -07002629 int runStackMoveTask(PrintWriter pw) throws RemoteException {
2630 String taskIdStr = getNextArgRequired();
2631 int taskId = Integer.parseInt(taskIdStr);
2632 String stackIdStr = getNextArgRequired();
2633 int stackId = Integer.parseInt(stackIdStr);
2634 String toTopStr = getNextArgRequired();
2635 final boolean toTop;
2636 if ("true".equals(toTopStr)) {
2637 toTop = true;
2638 } else if ("false".equals(toTopStr)) {
2639 toTop = false;
2640 } else {
2641 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr);
2642 return -1;
2643 }
2644
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002645 mTaskInterface.moveTaskToStack(taskId, stackId, toTop);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002646 return 0;
2647 }
2648
Dianne Hackborn331084d2016-10-07 17:57:00 -07002649 int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
2650 String stackIdStr = getNextArgRequired();
2651 int stackId = Integer.parseInt(stackIdStr);
2652 final Rect bounds;
2653 if ("null".equals(peekNextArg())) {
2654 bounds = null;
2655 } else {
2656 bounds = getBounds();
2657 if (bounds == null) {
2658 getErrPrintWriter().println("Error: invalid input bounds");
2659 return -1;
2660 }
2661 }
Evan Roskydbe2ce52019-07-18 11:13:17 -07002662 mTaskInterface.animateResizePinnedStack(stackId, bounds, -1);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002663 return 0;
2664 }
2665
2666 int runStackResizeDocked(PrintWriter pw) throws RemoteException {
2667 final Rect bounds = getBounds();
2668 final Rect taskBounds = getBounds();
2669 if (bounds == null || taskBounds == null) {
2670 getErrPrintWriter().println("Error: invalid input bounds");
2671 return -1;
2672 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002673 mTaskInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002674 return 0;
2675 }
2676
Dianne Hackborn331084d2016-10-07 17:57:00 -07002677 int runStackPositionTask(PrintWriter pw) throws RemoteException {
2678 String taskIdStr = getNextArgRequired();
2679 int taskId = Integer.parseInt(taskIdStr);
2680 String stackIdStr = getNextArgRequired();
2681 int stackId = Integer.parseInt(stackIdStr);
2682 String positionStr = getNextArgRequired();
2683 int position = Integer.parseInt(positionStr);
2684
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002685 mTaskInterface.positionTaskInStack(taskId, stackId, position);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002686 return 0;
2687 }
2688
2689 int runStackList(PrintWriter pw) throws RemoteException {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002690 List<ActivityManager.StackInfo> stacks = mTaskInterface.getAllStackInfos();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002691 for (ActivityManager.StackInfo info : stacks) {
2692 pw.println(info);
2693 }
2694 return 0;
2695 }
2696
2697 int runStackInfo(PrintWriter pw) throws RemoteException {
Wale Ogunwale68278562017-09-23 17:13:55 -07002698 int windowingMode = Integer.parseInt(getNextArgRequired());
2699 int activityType = Integer.parseInt(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002700 ActivityManager.StackInfo info = mTaskInterface.getStackInfo(windowingMode, activityType);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002701 pw.println(info);
2702 return 0;
2703 }
2704
2705 int runStackRemove(PrintWriter pw) throws RemoteException {
2706 String stackIdStr = getNextArgRequired();
2707 int stackId = Integer.parseInt(stackIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002708 mTaskInterface.removeStack(stackId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002709 return 0;
2710 }
2711
2712 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException {
2713 int stackId = Integer.parseInt(getNextArgRequired());
2714 final Rect bounds = getBounds();
2715 if (bounds == null) {
2716 getErrPrintWriter().println("Error: invalid input bounds");
2717 return -1;
2718 }
2719
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002720 if (!mTaskInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -07002721 getErrPrintWriter().println("Didn't move top activity to pinned stack.");
2722 return -1;
2723 }
2724 return 0;
2725 }
2726
Dianne Hackborn331084d2016-10-07 17:57:00 -07002727 void setBoundsSide(Rect bounds, String side, int value) {
2728 switch (side) {
2729 case "l":
2730 bounds.left = value;
2731 break;
2732 case "r":
2733 bounds.right = value;
2734 break;
2735 case "t":
2736 bounds.top = value;
2737 break;
2738 case "b":
2739 bounds.bottom = value;
2740 break;
2741 default:
2742 getErrPrintWriter().println("Unknown set side: " + side);
2743 break;
2744 }
2745 }
2746
2747 int runTask(PrintWriter pw) throws RemoteException {
2748 String op = getNextArgRequired();
2749 if (op.equals("lock")) {
2750 return runTaskLock(pw);
2751 } else if (op.equals("resizeable")) {
2752 return runTaskResizeable(pw);
2753 } else if (op.equals("resize")) {
2754 return runTaskResize(pw);
David Stevensee9e2772017-02-09 16:30:27 -08002755 } else if (op.equals("focus")) {
2756 return runTaskFocus(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002757 } else {
2758 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2759 return -1;
2760 }
2761 }
2762
2763 int runTaskLock(PrintWriter pw) throws RemoteException {
2764 String taskIdStr = getNextArgRequired();
2765 if (taskIdStr.equals("stop")) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002766 mTaskInterface.stopSystemLockTaskMode();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002767 } else {
2768 int taskId = Integer.parseInt(taskIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002769 mTaskInterface.startSystemLockTaskMode(taskId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002770 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002771 pw.println("Activity manager is " + (mTaskInterface.isInLockTaskMode() ? "" : "not ") +
Dianne Hackborn331084d2016-10-07 17:57:00 -07002772 "in lockTaskMode");
2773 return 0;
2774 }
2775
2776 int runTaskResizeable(PrintWriter pw) throws RemoteException {
2777 final String taskIdStr = getNextArgRequired();
2778 final int taskId = Integer.parseInt(taskIdStr);
2779 final String resizeableStr = getNextArgRequired();
2780 final int resizeableMode = Integer.parseInt(resizeableStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002781 mTaskInterface.setTaskResizeable(taskId, resizeableMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002782 return 0;
2783 }
2784
2785 int runTaskResize(PrintWriter pw) throws RemoteException {
2786 final String taskIdStr = getNextArgRequired();
2787 final int taskId = Integer.parseInt(taskIdStr);
2788 final Rect bounds = getBounds();
2789 if (bounds == null) {
2790 getErrPrintWriter().println("Error: invalid input bounds");
2791 return -1;
2792 }
2793 taskResize(taskId, bounds, 0, false);
2794 return 0;
2795 }
2796
2797 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
2798 throws RemoteException {
2799 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002800 mTaskInterface.resizeTask(taskId, bounds, resizeMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002801 try {
2802 Thread.sleep(delay_ms);
2803 } catch (InterruptedException e) {
2804 }
2805 }
2806
Dianne Hackborn331084d2016-10-07 17:57:00 -07002807 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
2808 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
2809 throws RemoteException {
2810 int maxMove;
2811 if (movingForward) {
2812 while (maxToTravel > 0
2813 && ((horizontal && taskRect.right < stackRect.right)
2814 ||(!horizontal && taskRect.bottom < stackRect.bottom))) {
2815 if (horizontal) {
2816 maxMove = Math.min(stepSize, stackRect.right - taskRect.right);
2817 maxToTravel -= maxMove;
2818 taskRect.right += maxMove;
2819 taskRect.left += maxMove;
2820 } else {
2821 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom);
2822 maxToTravel -= maxMove;
2823 taskRect.top += maxMove;
2824 taskRect.bottom += maxMove;
2825 }
2826 taskResize(taskId, taskRect, delay_ms, false);
2827 }
2828 } else {
2829 while (maxToTravel < 0
2830 && ((horizontal && taskRect.left > stackRect.left)
2831 ||(!horizontal && taskRect.top > stackRect.top))) {
2832 if (horizontal) {
2833 maxMove = Math.min(stepSize, taskRect.left - stackRect.left);
2834 maxToTravel -= maxMove;
2835 taskRect.right -= maxMove;
2836 taskRect.left -= maxMove;
2837 } else {
2838 maxMove = Math.min(stepSize, taskRect.top - stackRect.top);
2839 maxToTravel -= maxMove;
2840 taskRect.top -= maxMove;
2841 taskRect.bottom -= maxMove;
2842 }
2843 taskResize(taskId, taskRect, delay_ms, false);
2844 }
2845 }
2846 // Return the remaining distance we didn't travel because we reached the target location.
2847 return maxToTravel;
2848 }
2849
2850 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) {
2851 int stepSize = 0;
2852 if (greaterThanTarget && target < current) {
2853 current -= inStepSize;
2854 stepSize = inStepSize;
2855 if (target > current) {
2856 stepSize -= (target - current);
2857 }
2858 }
2859 if (!greaterThanTarget && target > current) {
2860 current += inStepSize;
2861 stepSize = inStepSize;
2862 if (target < current) {
2863 stepSize += (current - target);
2864 }
2865 }
2866 return stepSize;
2867 }
2868
David Stevensee9e2772017-02-09 16:30:27 -08002869 int runTaskFocus(PrintWriter pw) throws RemoteException {
2870 final int taskId = Integer.parseInt(getNextArgRequired());
2871 pw.println("Setting focus to task " + taskId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002872 mTaskInterface.setFocusedTask(taskId);
David Stevensee9e2772017-02-09 16:30:27 -08002873 return 0;
2874 }
2875
Dianne Hackborn331084d2016-10-07 17:57:00 -07002876 int runWrite(PrintWriter pw) {
2877 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2878 "registerUidObserver()");
Wale Ogunwaled7889f52018-10-25 11:03:20 -07002879 mInternal.mAtmInternal.flushRecentTasks();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002880 pw.println("All tasks persisted.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002881 return 0;
2882 }
2883
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002884 int runAttachAgent(PrintWriter pw) {
2885 // TODO: revisit the permissions required for attaching agents
2886 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2887 "attach-agent");
2888 String process = getNextArgRequired();
2889 String agent = getNextArgRequired();
2890 String opt;
2891 if ((opt = getNextArg()) != null) {
2892 pw.println("Error: Unknown option: " + opt);
2893 return -1;
2894 }
2895 mInternal.attachAgent(process, agent);
2896 return 0;
2897 }
2898
Michael Kwan94438b72016-11-03 15:30:34 -07002899 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
Matthew Ng626e0cc2016-12-07 17:25:53 -08002900 final Resources res = getResources(pw);
2901 if (res == null) {
2902 return -1;
2903 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002904 pw.println(ActivityTaskManager.supportsMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002905 return 0;
2906 }
2907
2908 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException {
2909 final Resources res = getResources(pw);
2910 if (res == null) {
2911 return -1;
2912 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002913 pw.println(ActivityTaskManager.supportsSplitScreenMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002914 return 0;
2915 }
2916
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002917 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
2918 int userid = UserHandle.parseUserArg(getNextArgRequired());
2919 ArrayList<String> packages = new ArrayList<>();
2920 packages.add(getNextArgRequired());
2921 String packageName;
2922 while ((packageName = getNextArg()) != null) {
2923 packages.add(packageName);
2924 }
2925 mInternal.scheduleApplicationInfoChanged(packages, userid);
2926 pw.println("Packages updated with most recent ApplicationInfos.");
2927 return 0;
2928 }
2929
Arthur Hsuf3f3a602017-02-21 14:01:53 -08002930 int runNoHomeScreen(PrintWriter pw) throws RemoteException {
2931 final Resources res = getResources(pw);
2932 if (res == null) {
2933 return -1;
2934 }
2935 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen));
2936 return 0;
2937 }
2938
Jeff Sharkeyfd658132017-05-03 11:38:01 -06002939 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
2940 mInternal.waitForBroadcastIdle(pw);
2941 return 0;
2942 }
2943
atrost8851c3c2019-08-29 16:17:52 +01002944 private int runCompat(PrintWriter pw) throws RemoteException {
atrostf69bbe12019-11-06 16:00:38 +00002945 final PlatformCompat platformCompat = (PlatformCompat)
2946 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
Andrei Oneaa2055012019-06-28 18:42:22 +01002947 String toggleValue = getNextArgRequired();
atrosta2498082019-12-04 11:07:39 +00002948 if (toggleValue.equals("reset-all")) {
2949 final String packageName = getNextArgRequired();
2950 pw.println("Reset all changes for " + packageName + " to default value.");
2951 platformCompat.clearOverrides(packageName);
2952 return 0;
2953 }
Andrei Oneaa2055012019-06-28 18:42:22 +01002954 long changeId;
2955 String changeIdString = getNextArgRequired();
2956 try {
2957 changeId = Long.parseLong(changeIdString);
2958 } catch (NumberFormatException e) {
atrostf69bbe12019-11-06 16:00:38 +00002959 changeId = platformCompat.lookupChangeId(changeIdString);
Andrei Oneaa2055012019-06-28 18:42:22 +01002960 }
2961 if (changeId == -1) {
2962 pw.println("Unknown or invalid change: '" + changeIdString + "'.");
atrostf69bbe12019-11-06 16:00:38 +00002963 return -1;
Andrei Oneaa2055012019-06-28 18:42:22 +01002964 }
2965 String packageName = getNextArgRequired();
atrostf69bbe12019-11-06 16:00:38 +00002966 if (!platformCompat.isKnownChangeId(changeId)) {
2967 pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it"
2968 + " could have no effect.");
2969 }
2970 ArraySet<Long> enabled = new ArraySet<>();
2971 ArraySet<Long> disabled = new ArraySet<>();
Andrei Onea465b2142019-11-28 16:55:27 +00002972 try {
2973 switch (toggleValue) {
2974 case "enable":
2975 enabled.add(changeId);
2976 CompatibilityChangeConfig overrides =
2977 new CompatibilityChangeConfig(
2978 new Compatibility.ChangeConfig(enabled, disabled));
2979 platformCompat.setOverrides(overrides, packageName);
2980 pw.println("Enabled change " + changeId + " for " + packageName + ".");
2981 return 0;
2982 case "disable":
2983 disabled.add(changeId);
2984 overrides =
2985 new CompatibilityChangeConfig(
2986 new Compatibility.ChangeConfig(enabled, disabled));
2987 platformCompat.setOverrides(overrides, packageName);
2988 pw.println("Disabled change " + changeId + " for " + packageName + ".");
2989 return 0;
2990 case "reset":
2991 if (platformCompat.clearOverride(changeId, packageName)) {
2992 pw.println("Reset change " + changeId + " for " + packageName
2993 + " to default value.");
2994 } else {
2995 pw.println("No override exists for changeId " + changeId + ".");
2996 }
2997 return 0;
2998 default:
2999 pw.println("Invalid toggle value: '" + toggleValue + "'.");
3000 }
3001 } catch (SecurityException e) {
3002 pw.println(e.getMessage());
Andrei Oneaa2055012019-06-28 18:42:22 +01003003 }
3004 return -1;
3005 }
3006
3007
Matthew Ng626e0cc2016-12-07 17:25:53 -08003008 private Resources getResources(PrintWriter pw) throws RemoteException {
Michael Kwan94438b72016-11-03 15:30:34 -07003009 // system resources does not contain all the device configuration, construct it manually.
3010 Configuration config = mInterface.getConfiguration();
3011 if (config == null) {
3012 pw.println("Error: Activity manager has no configuration");
Matthew Ng626e0cc2016-12-07 17:25:53 -08003013 return null;
Michael Kwan94438b72016-11-03 15:30:34 -07003014 }
3015
3016 final DisplayMetrics metrics = new DisplayMetrics();
3017 metrics.setToDefaults();
3018
Matthew Ng626e0cc2016-12-07 17:25:53 -08003019 return new Resources(AssetManager.getSystem(), metrics, config);
Michael Kwan94438b72016-11-03 15:30:34 -07003020 }
3021
Dianne Hackborn2e441072015-10-28 18:00:57 -07003022 @Override
3023 public void onHelp() {
3024 PrintWriter pw = getOutPrintWriter();
3025 dumpHelp(pw, mDumping);
3026 }
3027
3028 static void dumpHelp(PrintWriter pw, boolean dumping) {
3029 if (dumping) {
3030 pw.println("Activity manager dump options:");
3031 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
3032 pw.println(" WHAT may be one of:");
3033 pw.println(" a[ctivities]: activity stack state");
3034 pw.println(" r[recents]: recent activities state");
3035 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07003036 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003037 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
3038 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
3039 pw.println(" o[om]: out of memory management");
3040 pw.println(" perm[issions]: URI permission grant state");
3041 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
3042 pw.println(" provider [COMP_SPEC]: provider client-side state");
3043 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborn769b2e72018-12-05 08:51:20 -08003044 pw.println(" allowed-associations: current package association restrictions");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003045 pw.println(" as[sociations]: tracked app associations");
Jing Ji8055a3a2019-12-17 15:55:33 -08003046 pw.println(" exit-info [PACKAGE_NAME]: historical process exit information");
Dianne Hackborna631d562018-11-20 15:58:15 -08003047 pw.println(" lmk: stats on low memory killer");
3048 pw.println(" lru: raw LRU process list");
3049 pw.println(" binder-proxies: stats on binder objects and IPCs");
Dianne Hackborn0ef403e2017-01-24 18:22:15 -08003050 pw.println(" settings: currently applied config settings");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003051 pw.println(" service [COMP_SPEC]: service client-side state");
3052 pw.println(" package [PACKAGE_NAME]: all state related to given package");
3053 pw.println(" all: dump all activities");
3054 pw.println(" top: dump the top activity");
3055 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
3056 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
3057 pw.println(" a partial substring in a component name, a");
3058 pw.println(" hex object identifier.");
3059 pw.println(" -a: include all available server state.");
3060 pw.println(" -c: include client state.");
3061 pw.println(" -p: limit output to given package.");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07003062 pw.println(" --checkin: output checkin format, resetting data.");
3063 pw.println(" --C: output checkin format, not resetting data.");
Steven Timotius4346f0a2017-09-12 11:07:21 -07003064 pw.println(" --proto: output dump in protocol buffer format.");
Felipe Lemeb546ca72018-08-15 08:44:12 -07003065 pw.println(" --autofill: dump just the autofill-related state of an activity");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003066 } else {
3067 pw.println("Activity manager (activity) commands:");
3068 pw.println(" help");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003069 pw.println(" Print this help text.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003070 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08003071 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003072 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003073 pw.println(" Start an Activity. Options are:");
3074 pw.println(" -D: enable debugging");
3075 pw.println(" -N: enable native debugging");
3076 pw.println(" -W: wait for launch to complete");
3077 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>");
3078 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
3079 pw.println(" between samples (use with --start-profiler)");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08003080 pw.println(" --streaming: stream the profiling output to the specified file");
3081 pw.println(" (use with --start-profiler)");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003082 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
Andreas Gampe83085bb2017-06-26 17:54:11 -07003083 pw.println(" --attach-agent <agent>: attach the given agent before binding");
Andreas Gampeab8a63b2018-01-05 13:55:15 -08003084 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003085 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
3086 pw.println(" the top activity will be finished.");
3087 pw.println(" -S: force stop the target app before starting the activity");
3088 pw.println(" --track-allocation: enable tracking of object allocations");
3089 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
3090 pw.println(" specified then run as the current user.");
Wale Ogunwale0568aed2017-09-08 13:29:37 -07003091 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into.");
3092 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
Louis Changf379f802018-07-13 09:41:28 +08003093 pw.println(" --display <DISPLAY_ID>: The display to launch the activity into.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003094 pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
3095 pw.println(" Start a Service. Options are:");
3096 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
3097 pw.println(" specified then run as the current user.");
Jaewan Kim329b35f2017-04-11 11:19:49 +09003098 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
3099 pw.println(" Start a foreground Service. Options are:");
3100 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
3101 pw.println(" specified then run as the current user.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003102 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
3103 pw.println(" Stop a Service. Options are:");
3104 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
3105 pw.println(" specified then run as the current user.");
3106 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>");
3107 pw.println(" Send a broadcast Intent. Options are:");
3108 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not");
3109 pw.println(" specified then send to all users.");
3110 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
Alan Stokesc76767c2019-05-30 09:33:47 +01003111 pw.println(" --allow-background-activity-starts: The receiver may start activities");
3112 pw.println(" even if in the background.");
Dianne Hackborn28824062016-10-18 13:19:20 -07003113 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
Artur Satayevab4d5af2019-10-31 12:07:55 +00003114 pw.println(" [--user <USER_ID> | current]");
Artur Satayevfdc9fe82019-11-27 15:17:25 +00003115 pw.println(" [--no-hidden-api-checks [--no-test-api-access]]");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07003116 pw.println(" [--no-isolated-storage]");
Dianne Hackborn28824062016-10-18 13:19:20 -07003117 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
3118 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
3119 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
3120 pw.println(" is only one instrumentation. Options are:");
3121 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with");
3122 pw.println(" [-e perf true] to generate raw output for performance measurements.");
3123 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a");
3124 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]].");
3125 pw.println(" -p <FILE>: write profiling data to <FILE>");
Mike Mad2239822017-10-31 12:30:42 -07003126 pw.println(" -m: Write output as protobuf to stdout (machine readable)");
3127 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine");
3128 pw.println(" readable). If path is not specified, default directory and file name will");
3129 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto");
Dianne Hackborn28824062016-10-18 13:19:20 -07003130 pw.println(" -w: wait for instrumentation to finish before returning. Required for");
3131 pw.println(" test runners.");
3132 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
3133 pw.println(" current user if not specified.");
David Brazdild5d42172018-02-14 19:39:03 +00003134 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
Artur Satayevfdc9fe82019-11-27 15:17:25 +00003135 pw.println(" --no-test-api-access: do not allow access to test APIs, if hidden");
Artur Satayevab4d5af2019-10-31 12:07:55 +00003136 pw.println(" API checks are enabled.");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07003137 pw.println(" --no-isolated-storage: don't use isolated storage sandbox and ");
3138 pw.println(" mount full external storage");
Dianne Hackborn28824062016-10-18 13:19:20 -07003139 pw.println(" --no-window-animation: turn off window animations while running.");
3140 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
3141 pw.println(" This assumes that the process supports the selected ABI.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003142 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]");
3143 pw.println(" Trace IPC transactions.");
3144 pw.println(" start: start tracing IPC transactions.");
3145 pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
3146 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
Orion Hodson4e6a3142019-04-08 10:12:02 +01003147 pw.println(" profile start [--user <USER_ID> current]");
3148 pw.println(" [--sampling INTERVAL | --streaming] <PROCESS> <FILE>");
3149 pw.println(" Start profiler on a process. The given <PROCESS> argument");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003150 pw.println(" may be either a process name or pid. Options are:");
3151 pw.println(" --user <USER_ID> | current: When supplying a process name,");
Orion Hodson4e6a3142019-04-08 10:12:02 +01003152 pw.println(" specify user of process to profile; uses current user if not");
3153 pw.println(" specified.");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08003154 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
Orion Hodson4e6a3142019-04-08 10:12:02 +01003155 pw.println(" between samples.");
3156 pw.println(" --streaming: stream the profiling output to the specified file.");
3157 pw.println(" profile stop [--user <USER_ID> current] <PROCESS>");
3158 pw.println(" Stop profiler on a process. The given <PROCESS> argument");
3159 pw.println(" may be either a process name or pid. Options are:");
3160 pw.println(" --user <USER_ID> | current: When supplying a process name,");
3161 pw.println(" specify user of process to profile; uses current user if not");
3162 pw.println(" specified.");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07003163 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003164 pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
3165 pw.println(" be either a process name or pid. Options are:");
3166 pw.println(" -n: dump native heap instead of managed heap");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07003167 pw.println(" -g: force GC before dumping the heap");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003168 pw.println(" --user <USER_ID> | current: When supplying a process name,");
3169 pw.println(" specify user of process to dump; uses current user if not specified.");
3170 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>");
3171 pw.println(" Set application <PACKAGE> to debug. Options are:");
3172 pw.println(" -w: wait for debugger when application starts");
3173 pw.println(" --persistent: retain this value");
3174 pw.println(" clear-debug-app");
3175 pw.println(" Clear the previously set-debug-app.");
3176 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>");
3177 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or");
3178 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
3179 pw.println(" clear-watch-heap");
3180 pw.println(" Clear the previously set-watch-heap.");
Jing Ji8055a3a2019-12-17 15:55:33 -08003181 pw.println(" clear-exit-info [--user <USER_ID> | all | current] [package]");
3182 pw.println(" Clear the process exit-info for given package");
Felipe Leme9606c3b2017-01-05 14:57:12 -08003183 pw.println(" bug-report [--progress | --telephony]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003184 pw.println(" Request bug report generation; will launch a notification");
3185 pw.println(" when done to select where it should be delivered. Options are:");
3186 pw.println(" --progress: will launch a notification right away to show its progress.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08003187 pw.println(" --telephony: will dump only telephony sections.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003188 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003189 pw.println(" Completely stop the given application package.");
Christopher Tate8aa8fe12017-01-20 17:50:32 -08003190 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>");
3191 pw.println(" Induce a VM crash in the specified package or process");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003192 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
Makoto Onuki6569c362018-02-27 15:52:01 -08003193 pw.println(" Kill all background processes associated with the given application.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003194 pw.println(" kill-all");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003195 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn85e35642017-01-12 15:10:57 -08003196 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
3197 pw.println(" If the given application's uid is in the background and waiting to");
3198 pw.println(" become idle (not allowing background services), do that now.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003199 pw.println(" monitor [--gdb <port>]");
3200 pw.println(" Start monitoring for crashes or ANRs.");
3201 pw.println(" --gdb: start gdbserv on the given port at crash/ANR");
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07003202 pw.println(" watch-uids [--oom <uid>]");
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01003203 pw.println(" Start watching for and reporting uid state changes.");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003204 pw.println(" --oom: specify a uid for which to report detailed change messages.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003205 pw.println(" hang [--allow-restart]");
3206 pw.println(" Hang the system.");
3207 pw.println(" --allow-restart: allow watchdog to perform normal system restart");
3208 pw.println(" restart");
3209 pw.println(" Restart the user-space system.");
3210 pw.println(" idle-maintenance");
3211 pw.println(" Perform idle maintenance now.");
3212 pw.println(" screen-compat [on|off] <PACKAGE>");
3213 pw.println(" Control screen compatibility mode of <PACKAGE>.");
3214 pw.println(" package-importance <PACKAGE>");
3215 pw.println(" Print current importance of <PACKAGE>.");
3216 pw.println(" to-uri [INTENT]");
3217 pw.println(" Print the given Intent specification as a URI.");
3218 pw.println(" to-intent-uri [INTENT]");
3219 pw.println(" Print the given Intent specification as an intent: URI.");
3220 pw.println(" to-app-uri [INTENT]");
3221 pw.println(" Print the given Intent specification as an android-app: URI.");
3222 pw.println(" switch-user <USER_ID>");
3223 pw.println(" Switch to put USER_ID in the foreground, starting");
3224 pw.println(" execution of that user if it is currently stopped.");
3225 pw.println(" get-current-user");
3226 pw.println(" Returns id of the current foreground user.");
Bookatz03bfe6f2019-03-01 15:46:04 -08003227 pw.println(" start-user [-w] <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003228 pw.println(" Start USER_ID in background if it is currently stopped;");
Bookatz03bfe6f2019-03-01 15:46:04 -08003229 pw.println(" use switch-user if you want to start the user in foreground.");
3230 pw.println(" -w: wait for start-user to complete and the user to be unlocked.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003231 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]");
3232 pw.println(" Attempt to unlock the given user using the given authorization token.");
3233 pw.println(" stop-user [-w] [-f] <USER_ID>");
3234 pw.println(" Stop execution of USER_ID, not allowing it to run any");
3235 pw.println(" code until a later explicit start or switch to it.");
3236 pw.println(" -w: wait for stop-user to complete.");
3237 pw.println(" -f: force stop even if there are related users that cannot be stopped.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003238 pw.println(" is-user-stopped <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003239 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07003240 pw.println(" get-started-user-state <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003241 pw.println(" Gets the current state of the given started user.");
3242 pw.println(" track-associations");
3243 pw.println(" Enable association tracking.");
3244 pw.println(" untrack-associations");
3245 pw.println(" Disable and clear association tracking.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003246 pw.println(" get-uid-state <UID>");
3247 pw.println(" Gets the process state of an app given its <UID>.");
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07003248 pw.println(" attach-agent <PROCESS> <FILE>");
3249 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 +08003250 pw.println(" get-config [--days N] [--device] [--proto] [--display <DISPLAY_ID>]");
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08003251 pw.println(" Retrieve the configuration and any recent configurations of the device.");
3252 pw.println(" --days: also return last N days of configurations that have been seen.");
3253 pw.println(" --device: also output global device configuration info.");
3254 pw.println(" --proto: return result as a proto; does not include --days info.");
Jeff Change9467b22018-09-28 11:40:38 +08003255 pw.println(" --display: Specify for which display to run the command; if not ");
3256 pw.println(" specified then run for the default display.");
Michael Kwan94438b72016-11-03 15:30:34 -07003257 pw.println(" supports-multiwindow");
3258 pw.println(" Returns true if the device supports multiwindow.");
Matthew Ng626e0cc2016-12-07 17:25:53 -08003259 pw.println(" supports-split-screen-multi-window");
3260 pw.println(" Returns true if the device supports split screen multiwindow.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003261 pw.println(" suppress-resize-config-changes <true|false>");
3262 pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
3263 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
3264 pw.println(" Sets the inactive state of an app.");
3265 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
3266 pw.println(" Returns the inactive state of an app.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003267 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
Amith Yamasani17fffee2017-09-29 13:17:43 -07003268 pw.println(" Puts an app in the standby bucket.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003269 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
3270 pw.println(" Returns the standby bucket of an app.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003271 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
3272 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003273 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 -07003274 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays.");
3275 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>");
3276 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003277 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
Andrii Kulian839def92016-11-02 10:58:58 -07003278 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003279 pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
3280 pw.println(" bottom (false) of <STACK_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003281 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3282 pw.println(" Same as resize, but allow animation.");
3283 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
3284 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
3285 pw.println(" and supplying temporary different task bounds indicated by");
3286 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003287 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3288 pw.println(" Moves the top activity from");
3289 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
3290 pw.println(" bounds of the pinned stack.");
3291 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>");
3292 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
3293 pw.println(" list");
3294 pw.println(" List all of the activity stacks and their sizes.");
Wale Ogunwale68278562017-09-23 17:13:55 -07003295 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
3296 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003297 pw.println(" remove <STACK_ID>");
3298 pw.println(" Remove stack <STACK_ID>.");
3299 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
3300 pw.println(" lock <TASK_ID>");
3301 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run.");
3302 pw.println(" lock stop");
3303 pw.println(" End the current task lock.");
3304 pw.println(" resizeable <TASK_ID> [0|1|2|3]");
3305 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:");
3306 pw.println(" 0: unresizeable");
3307 pw.println(" 1: crop_windows");
3308 pw.println(" 2: resizeable");
3309 pw.println(" 3: resizeable_and_pipable");
3310 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3311 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
3312 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
3313 pw.println(" has the specified bounds.");
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01003314 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
3315 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
3316 pw.println(" without restarting any processes.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003317 pw.println(" write");
3318 pw.println(" Write all pending state to storage.");
atrosta2498082019-12-04 11:07:39 +00003319 pw.println(" compat [COMMAND] [...]: sub-commands for toggling app-compat changes.");
3320 pw.println(" enable|disable|reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>");
3321 pw.println(" Toggles a change either by id or by name for <PACKAGE_NAME>.");
3322 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect).");
3323 pw.println(" reset-all <PACKAGE_NAME>");
3324 pw.println(" Removes all existing overrides for all changes for ");
3325 pw.println(" <PACKAGE_NAME> (back to default behaviour).");
3326 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect).");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003327 pw.println();
3328 Intent.printIntentArgsHelp(pw, "");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003329 }
3330 }
3331}