blob: d9e4844209d0734826d42c49446f37d3a997405a [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;
Dianne Hackborn331084d2016-10-07 17:57:00 -070032import android.app.IActivityController;
Dianne Hackborn2e441072015-10-28 18:00:57 -070033import android.app.IActivityManager;
Wale Ogunwale65ebd952018-04-25 15:41:44 -070034import android.app.IActivityTaskManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070035import android.app.IStopUserCallback;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +010036import android.app.IUidObserver;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080037import android.app.KeyguardManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070038import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070039import android.app.WaitResult;
Suprabh Shukla868bde22018-02-20 20:59:52 -080040import android.app.usage.AppStandbyInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070041import android.app.usage.ConfigurationStats;
42import android.app.usage.IUsageStatsManager;
43import android.app.usage.UsageStatsManager;
atrostf69bbe12019-11-06 16:00:38 +000044import android.compat.Compatibility;
Dianne Hackborn331084d2016-10-07 17:57:00 -070045import android.content.ComponentCallbacks2;
46import android.content.ComponentName;
47import android.content.Context;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080048import android.content.DeviceConfigurationProto;
49import android.content.GlobalConfigurationProto;
Dianne Hackborn331084d2016-10-07 17:57:00 -070050import android.content.IIntentReceiver;
Dianne Hackborn354736e2016-08-22 17:00:05 -070051import android.content.Intent;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080052import android.content.pm.ConfigurationInfo;
53import android.content.pm.FeatureInfo;
Dianne Hackborn354736e2016-08-22 17:00:05 -070054import android.content.pm.IPackageManager;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080055import android.content.pm.PackageManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070056import android.content.pm.ParceledListSlice;
Dianne Hackborn354736e2016-08-22 17:00:05 -070057import android.content.pm.ResolveInfo;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080058import android.content.pm.SharedLibraryInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070059import android.content.pm.UserInfo;
Michael Kwan94438b72016-11-03 15:30:34 -070060import android.content.res.AssetManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070061import android.content.res.Configuration;
Michael Kwan94438b72016-11-03 15:30:34 -070062import android.content.res.Resources;
Dianne Hackborn331084d2016-10-07 17:57:00 -070063import android.graphics.Rect;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080064import android.hardware.display.DisplayManager;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080065import android.opengl.GLES10;
Dianne Hackborn331084d2016-10-07 17:57:00 -070066import android.os.Binder;
67import android.os.Build;
68import android.os.Bundle;
Bookatz03bfe6f2019-03-01 15:46:04 -080069import android.os.IProgressListener;
Dianne Hackborn354736e2016-08-22 17:00:05 -070070import android.os.ParcelFileDescriptor;
Makoto Onuki2c6657f2018-06-06 15:24:02 -070071import android.os.RemoteCallback;
72import android.os.RemoteCallback.OnResultListener;
Dianne Hackborn2e441072015-10-28 18:00:57 -070073import android.os.RemoteException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070074import android.os.ServiceManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -070075import android.os.ShellCommand;
Dianne Hackborn5c3296a2017-12-13 17:52:26 -080076import android.os.StrictMode;
Dianne Hackborn354736e2016-08-22 17:00:05 -070077import android.os.SystemClock;
Dianne Hackborn331084d2016-10-07 17:57:00 -070078import android.os.SystemProperties;
Dianne Hackborn2e441072015-10-28 18:00:57 -070079import android.os.UserHandle;
Alex Chau5c0df232018-02-22 15:57:17 +080080import android.os.UserManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070081import android.text.TextUtils;
Makoto Onuki2c6657f2018-06-06 15:24:02 -070082import android.text.format.Time;
Dianne Hackborn331084d2016-10-07 17:57:00 -070083import android.util.ArrayMap;
atrostf69bbe12019-11-06 16:00:38 +000084import android.util.ArraySet;
Felipe Leme2f1b2272016-03-25 16:15:02 -070085import android.util.DebugUtils;
Michael Kwan94438b72016-11-03 15:30:34 -070086import android.util.DisplayMetrics;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080087import android.util.proto.ProtoOutputStream;
88import android.view.Display;
Dianne Hackborn2e441072015-10-28 18:00:57 -070089
atrostf69bbe12019-11-06 16:00:38 +000090import com.android.internal.compat.CompatibilityChangeConfig;
Dianne Hackborn331084d2016-10-07 17:57:00 -070091import com.android.internal.util.HexDump;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080092import com.android.internal.util.MemInfoReader;
Dianne Hackborn331084d2016-10-07 17:57:00 -070093import com.android.internal.util.Preconditions;
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;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700103import java.util.ArrayList;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800104import java.util.Arrays;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700105import java.util.Collections;
106import java.util.Comparator;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800107import java.util.HashSet;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700108import java.util.List;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800109import java.util.Set;
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700110import java.util.concurrent.CountDownLatch;
Bookatz03bfe6f2019-03-01 15:46:04 -0800111import java.util.concurrent.TimeUnit;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700112
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800113import javax.microedition.khronos.egl.EGL10;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800114import javax.microedition.khronos.egl.EGLConfig;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800115import javax.microedition.khronos.egl.EGLContext;
Dianne Hackborn337e01a2018-02-27 17:16:37 -0800116import javax.microedition.khronos.egl.EGLDisplay;
117import javax.microedition.khronos.egl.EGLSurface;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -0800118
Dianne Hackborn331084d2016-10-07 17:57:00 -0700119final class ActivityManagerShellCommand extends ShellCommand {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700120 public static final String NO_CLASS_ERROR_CODE = "Error type 3";
Dianne Hackborn331084d2016-10-07 17:57:00 -0700121 private static final String SHELL_PACKAGE_NAME = "com.android.shell";
122
Bookatz03bfe6f2019-03-01 15:46:04 -0800123 private static final int USER_OPERATION_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes
124
Dianne Hackborn2e441072015-10-28 18:00:57 -0700125 // IPC interface to activity manager -- don't need to do additional security checks.
126 final IActivityManager mInterface;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700127 final IActivityTaskManager mTaskInterface;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700128
129 // Internal service impl -- must perform security checks before touching.
130 final ActivityManagerService mInternal;
131
Dianne Hackborn354736e2016-08-22 17:00:05 -0700132 // Convenience for interacting with package manager.
133 final IPackageManager mPm;
134
135 private int mStartFlags = 0;
136 private boolean mWaitOption = false;
137 private boolean mStopOption = false;
138
139 private int mRepeat = 0;
140 private int mUserId;
141 private String mReceiverPermission;
142
143 private String mProfileFile;
144 private int mSamplingInterval;
145 private boolean mAutoStop;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800146 private boolean mStreaming; // Streaming the profiling output to a file.
Andreas Gampe83085bb2017-06-26 17:54:11 -0700147 private String mAgent; // Agent to attach on startup.
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800148 private boolean mAttachAgentDuringBind; // Whether agent should be attached late.
Andrii Kulian16802aa2016-11-02 12:21:33 -0700149 private int mDisplayId;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700150 private int mWindowingMode;
151 private int mActivityType;
Winson Chung6954fc92017-03-24 16:22:12 -0700152 private int mTaskId;
153 private boolean mIsTaskOverlay;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000154 private boolean mIsLockTask;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700155
Dianne Hackborn2e441072015-10-28 18:00:57 -0700156 final boolean mDumping;
157
158 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
159 mInterface = service;
Wale Ogunwale65ebd952018-04-25 15:41:44 -0700160 mTaskInterface = service.mActivityTaskManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700161 mInternal = service;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700162 mPm = AppGlobals.getPackageManager();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700163 mDumping = dumping;
164 }
165
166 @Override
167 public int onCommand(String cmd) {
168 if (cmd == null) {
169 return handleDefaultCommands(cmd);
170 }
Dianne Hackborn5c3296a2017-12-13 17:52:26 -0800171 final PrintWriter pw = getOutPrintWriter();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700172 try {
173 switch (cmd) {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700174 case "start":
175 case "start-activity":
176 return runStartActivity(pw);
177 case "startservice":
178 case "start-service":
Christopher Tate7e1368d2017-03-30 17:20:12 -0700179 return runStartService(pw, false);
180 case "startforegroundservice":
181 case "startfgservice":
182 case "start-foreground-service":
183 case "start-fg-service":
184 return runStartService(pw, true);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700185 case "stopservice":
186 case "stop-service":
Dianne Hackborn331084d2016-10-07 17:57:00 -0700187 return runStopService(pw);
188 case "broadcast":
189 return runSendBroadcast(pw);
190 case "instrument":
Dianne Hackborn28824062016-10-18 13:19:20 -0700191 getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");
192 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700193 case "trace-ipc":
194 return runTraceIpc(pw);
195 case "profile":
196 return runProfile(pw);
197 case "dumpheap":
198 return runDumpHeap(pw);
199 case "set-debug-app":
200 return runSetDebugApp(pw);
Andreas Gampe5b495d52018-01-22 15:15:54 -0800201 case "set-agent-app":
202 return runSetAgentApp(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700203 case "clear-debug-app":
204 return runClearDebugApp(pw);
205 case "set-watch-heap":
206 return runSetWatchHeap(pw);
207 case "clear-watch-heap":
208 return runClearWatchHeap(pw);
209 case "bug-report":
210 return runBugReport(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700211 case "force-stop":
212 return runForceStop(pw);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800213 case "crash":
214 return runCrash(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700215 case "kill":
216 return runKill(pw);
217 case "kill-all":
218 return runKillAll(pw);
Dianne Hackborn85e35642017-01-12 15:10:57 -0800219 case "make-uid-idle":
Dianne Hackborne07641d2016-11-09 15:07:23 -0800220 return runMakeIdle(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700221 case "monitor":
222 return runMonitor(pw);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +0100223 case "watch-uids":
224 return runWatchUids(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700225 case "hang":
226 return runHang(pw);
227 case "restart":
228 return runRestart(pw);
229 case "idle-maintenance":
230 return runIdleMaintenance(pw);
231 case "screen-compat":
232 return runScreenCompat(pw);
233 case "package-importance":
234 return runPackageImportance(pw);
235 case "to-uri":
236 return runToUri(pw, 0);
237 case "to-intent-uri":
238 return runToUri(pw, Intent.URI_INTENT_SCHEME);
239 case "to-app-uri":
240 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME);
241 case "switch-user":
242 return runSwitchUser(pw);
243 case "get-current-user":
244 return runGetCurrentUser(pw);
245 case "start-user":
246 return runStartUser(pw);
247 case "unlock-user":
248 return runUnlockUser(pw);
249 case "stop-user":
250 return runStopUser(pw);
251 case "is-user-stopped":
252 return runIsUserStopped(pw);
253 case "get-started-user-state":
254 return runGetStartedUserState(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700255 case "track-associations":
256 return runTrackAssociations(pw);
257 case "untrack-associations":
258 return runUntrackAssociations(pw);
Felipe Leme2f1b2272016-03-25 16:15:02 -0700259 case "get-uid-state":
260 return getUidState(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700261 case "get-config":
262 return runGetConfig(pw);
263 case "suppress-resize-config-changes":
264 return runSuppressResizeConfigChanges(pw);
265 case "set-inactive":
266 return runSetInactive(pw);
267 case "get-inactive":
268 return runGetInactive(pw);
Amith Yamasani17fffee2017-09-29 13:17:43 -0700269 case "set-standby-bucket":
270 return runSetStandbyBucket(pw);
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800271 case "get-standby-bucket":
272 return runGetStandbyBucket(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700273 case "send-trim-memory":
274 return runSendTrimMemory(pw);
Andrii Kulian839def92016-11-02 10:58:58 -0700275 case "display":
276 return runDisplay(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700277 case "stack":
278 return runStack(pw);
279 case "task":
280 return runTask(pw);
281 case "write":
282 return runWrite(pw);
Leonard Mosescuf3409ce2016-10-06 17:32:05 -0700283 case "attach-agent":
284 return runAttachAgent(pw);
Michael Kwan94438b72016-11-03 15:30:34 -0700285 case "supports-multiwindow":
286 return runSupportsMultiwindow(pw);
Matthew Ng626e0cc2016-12-07 17:25:53 -0800287 case "supports-split-screen-multi-window":
288 return runSupportsSplitScreenMultiwindow(pw);
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +0100289 case "update-appinfo":
290 return runUpdateApplicationInfo(pw);
Arthur Hsuf3f3a602017-02-21 14:01:53 -0800291 case "no-home-screen":
292 return runNoHomeScreen(pw);
Jeff Sharkeyfd658132017-05-03 11:38:01 -0600293 case "wait-for-broadcast-idle":
294 return runWaitForBroadcastIdle(pw);
Andrei Oneac014fb5c2019-06-28 18:42:22 +0100295 case "compat":
296 return runCompat(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700297 default:
298 return handleDefaultCommands(cmd);
299 }
300 } catch (RemoteException e) {
301 pw.println("Remote exception: " + e);
302 }
303 return -1;
304 }
305
Dianne Hackborn354736e2016-08-22 17:00:05 -0700306 private Intent makeIntent(int defUser) throws URISyntaxException {
307 mStartFlags = 0;
308 mWaitOption = false;
309 mStopOption = false;
310 mRepeat = 0;
311 mProfileFile = null;
312 mSamplingInterval = 0;
313 mAutoStop = false;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800314 mStreaming = false;
Zhi An Ng6aab6f92019-03-29 22:33:25 +0000315 mUserId = defUser;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700316 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700317 mWindowingMode = WINDOWING_MODE_UNDEFINED;
318 mActivityType = ACTIVITY_TYPE_UNDEFINED;
Winson Chung6954fc92017-03-24 16:22:12 -0700319 mTaskId = INVALID_TASK_ID;
320 mIsTaskOverlay = false;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000321 mIsLockTask = false;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700322
323 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
324 @Override
325 public boolean handleOption(String opt, ShellCommand cmd) {
326 if (opt.equals("-D")) {
327 mStartFlags |= ActivityManager.START_FLAG_DEBUG;
328 } else if (opt.equals("-N")) {
329 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING;
330 } else if (opt.equals("-W")) {
331 mWaitOption = true;
332 } else if (opt.equals("-P")) {
333 mProfileFile = getNextArgRequired();
334 mAutoStop = true;
335 } else if (opt.equals("--start-profiler")) {
336 mProfileFile = getNextArgRequired();
337 mAutoStop = false;
338 } else if (opt.equals("--sampling")) {
339 mSamplingInterval = Integer.parseInt(getNextArgRequired());
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800340 } else if (opt.equals("--streaming")) {
341 mStreaming = true;
Andreas Gampe83085bb2017-06-26 17:54:11 -0700342 } else if (opt.equals("--attach-agent")) {
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800343 if (mAgent != null) {
344 cmd.getErrPrintWriter().println(
345 "Multiple --attach-agent(-bind) not supported");
346 return false;
347 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700348 mAgent = getNextArgRequired();
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800349 mAttachAgentDuringBind = false;
350 } else if (opt.equals("--attach-agent-bind")) {
351 if (mAgent != null) {
352 cmd.getErrPrintWriter().println(
353 "Multiple --attach-agent(-bind) not supported");
354 return false;
355 }
356 mAgent = getNextArgRequired();
357 mAttachAgentDuringBind = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700358 } else if (opt.equals("-R")) {
359 mRepeat = Integer.parseInt(getNextArgRequired());
360 } else if (opt.equals("-S")) {
361 mStopOption = true;
362 } else if (opt.equals("--track-allocation")) {
363 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
364 } else if (opt.equals("--user")) {
365 mUserId = UserHandle.parseUserArg(getNextArgRequired());
366 } else if (opt.equals("--receiver-permission")) {
367 mReceiverPermission = getNextArgRequired();
Andrii Kulian16802aa2016-11-02 12:21:33 -0700368 } else if (opt.equals("--display")) {
369 mDisplayId = Integer.parseInt(getNextArgRequired());
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700370 } else if (opt.equals("--windowingMode")) {
371 mWindowingMode = Integer.parseInt(getNextArgRequired());
372 } else if (opt.equals("--activityType")) {
373 mActivityType = Integer.parseInt(getNextArgRequired());
Winson Chung6954fc92017-03-24 16:22:12 -0700374 } else if (opt.equals("--task")) {
375 mTaskId = Integer.parseInt(getNextArgRequired());
376 } else if (opt.equals("--task-overlay")) {
377 mIsTaskOverlay = true;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000378 } else if (opt.equals("--lock-task")) {
379 mIsLockTask = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700380 } else {
381 return false;
382 }
383 return true;
384 }
385 });
386 }
387
Bookatz03bfe6f2019-03-01 15:46:04 -0800388 private class ProgressWaiter extends IProgressListener.Stub {
389 private final CountDownLatch mFinishedLatch = new CountDownLatch(1);
390
391 @Override
392 public void onStarted(int id, Bundle extras) {}
393
394 @Override
395 public void onProgress(int id, int progress, Bundle extras) {}
396
397 @Override
398 public void onFinished(int id, Bundle extras) {
399 mFinishedLatch.countDown();
400 }
401
402 public boolean waitForFinish(long timeoutMillis) {
403 try {
404 return mFinishedLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
405 } catch (InterruptedException e) {
406 System.err.println("Thread interrupted unexpectedly.");
407 return false;
408 }
409 }
410 }
411
Dianne Hackborn354736e2016-08-22 17:00:05 -0700412 int runStartActivity(PrintWriter pw) throws RemoteException {
413 Intent intent;
414 try {
415 intent = makeIntent(UserHandle.USER_CURRENT);
416 } catch (URISyntaxException e) {
417 throw new RuntimeException(e.getMessage(), e);
418 }
419
420 if (mUserId == UserHandle.USER_ALL) {
421 getErrPrintWriter().println("Error: Can't start service with user 'all'");
422 return 1;
423 }
424
425 String mimeType = intent.getType();
426 if (mimeType == null && intent.getData() != null
427 && "content".equals(intent.getData().getScheme())) {
428 mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId);
429 }
430
431 do {
432 if (mStopOption) {
433 String packageName;
434 if (intent.getComponent() != null) {
435 packageName = intent.getComponent().getPackageName();
436 } else {
Ng Zhi An494d4fe2019-04-02 09:00:22 -0700437 // queryIntentActivities does not convert user id, so we convert it here first
438 int userIdForQuery = mInternal.mUserController.handleIncomingUser(
439 Binder.getCallingPid(), Binder.getCallingUid(), mUserId, false,
440 ALLOW_NON_FULL, "ActivityManagerShellCommand", null);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700441 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0,
Ng Zhi An494d4fe2019-04-02 09:00:22 -0700442 userIdForQuery).getList();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700443 if (activities == null || activities.size() <= 0) {
444 getErrPrintWriter().println("Error: Intent does not match any activities: "
445 + intent);
446 return 1;
447 } else if (activities.size() > 1) {
448 getErrPrintWriter().println(
449 "Error: Intent matches multiple activities; can't stop: "
450 + intent);
451 return 1;
452 }
453 packageName = activities.get(0).activityInfo.packageName;
454 }
455 pw.println("Stopping: " + packageName);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700456 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700457 mInterface.forceStopPackage(packageName, mUserId);
458 try {
459 Thread.sleep(250);
460 } catch (InterruptedException e) {
461 }
462 }
463
464 ProfilerInfo profilerInfo = null;
465
Andreas Gampe83085bb2017-06-26 17:54:11 -0700466 if (mProfileFile != null || mAgent != null) {
467 ParcelFileDescriptor fd = null;
468 if (mProfileFile != null) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700469 fd = openFileForSystem(mProfileFile, "w");
Andreas Gampe83085bb2017-06-26 17:54:11 -0700470 if (fd == null) {
471 return 1;
472 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700473 }
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800474 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800475 mStreaming, mAgent, mAttachAgentDuringBind);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700476 }
477
478 pw.println("Starting: " + intent);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700479 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700480 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
481
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700482 WaitResult result = null;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700483 int res;
484 final long startTime = SystemClock.uptimeMillis();
485 ActivityOptions options = null;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700486 if (mDisplayId != INVALID_DISPLAY) {
487 options = ActivityOptions.makeBasic();
488 options.setLaunchDisplayId(mDisplayId);
489 }
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700490 if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
491 if (options == null) {
492 options = ActivityOptions.makeBasic();
493 }
494 options.setLaunchWindowingMode(mWindowingMode);
495 }
496 if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
497 if (options == null) {
498 options = ActivityOptions.makeBasic();
499 }
500 options.setLaunchActivityType(mActivityType);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700501 }
Winson Chung6954fc92017-03-24 16:22:12 -0700502 if (mTaskId != INVALID_TASK_ID) {
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000503 if (options == null) {
504 options = ActivityOptions.makeBasic();
505 }
Winson Chung6954fc92017-03-24 16:22:12 -0700506 options.setLaunchTaskId(mTaskId);
507
508 if (mIsTaskOverlay) {
509 options.setTaskOverlay(true, true /* canResume */);
510 }
511 }
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000512 if (mIsLockTask) {
513 if (options == null) {
514 options = ActivityOptions.makeBasic();
515 }
Benjamin Franzcaffa772018-02-05 16:36:10 +0000516 options.setLockTaskEnabled(true);
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000517 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700518 if (mWaitOption) {
Andrii Kulianeab3c902019-07-23 19:32:39 -0700519 result = mInternal.startActivityAndWait(null, SHELL_PACKAGE_NAME, intent, mimeType,
Dianne Hackborn354736e2016-08-22 17:00:05 -0700520 null, null, 0, mStartFlags, profilerInfo,
521 options != null ? options.toBundle() : null, mUserId);
522 res = result.result;
523 } else {
Andrii Kulianeab3c902019-07-23 19:32:39 -0700524 res = mInternal.startActivityAsUser(null, SHELL_PACKAGE_NAME, intent, mimeType,
Dianne Hackborn354736e2016-08-22 17:00:05 -0700525 null, null, 0, mStartFlags, profilerInfo,
526 options != null ? options.toBundle() : null, mUserId);
527 }
528 final long endTime = SystemClock.uptimeMillis();
529 PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
530 boolean launched = false;
531 switch (res) {
532 case ActivityManager.START_SUCCESS:
533 launched = true;
534 break;
535 case ActivityManager.START_SWITCHES_CANCELED:
536 launched = true;
537 out.println(
538 "Warning: Activity not started because the "
539 + " current activity is being kept for the user.");
540 break;
541 case ActivityManager.START_DELIVERED_TO_TOP:
542 launched = true;
543 out.println(
544 "Warning: Activity not started, intent has "
545 + "been delivered to currently running "
546 + "top-most instance.");
547 break;
548 case ActivityManager.START_RETURN_INTENT_TO_CALLER:
549 launched = true;
550 out.println(
551 "Warning: Activity not started because intent "
552 + "should be handled by the caller");
553 break;
554 case ActivityManager.START_TASK_TO_FRONT:
555 launched = true;
556 out.println(
557 "Warning: Activity not started, its current "
558 + "task has been brought to the front");
559 break;
560 case ActivityManager.START_INTENT_NOT_RESOLVED:
561 out.println(
562 "Error: Activity not started, unable to "
563 + "resolve " + intent.toString());
564 break;
565 case ActivityManager.START_CLASS_NOT_FOUND:
566 out.println(NO_CLASS_ERROR_CODE);
567 out.println("Error: Activity class " +
568 intent.getComponent().toShortString()
569 + " does not exist.");
570 break;
571 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
572 out.println(
573 "Error: Activity not started, you requested to "
574 + "both forward and receive its result");
575 break;
576 case ActivityManager.START_PERMISSION_DENIED:
577 out.println(
578 "Error: Activity not started, you do not "
579 + "have permission to access it.");
580 break;
581 case ActivityManager.START_NOT_VOICE_COMPATIBLE:
582 out.println(
583 "Error: Activity not started, voice control not allowed for: "
584 + intent);
585 break;
586 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
587 out.println(
588 "Error: Not allowed to start background user activity"
589 + " that shouldn't be displayed for all users.");
590 break;
591 default:
592 out.println(
593 "Error: Activity not started, unknown error code " + res);
594 break;
595 }
Dianne Hackborn331084d2016-10-07 17:57:00 -0700596 out.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700597 if (mWaitOption && launched) {
598 if (result == null) {
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700599 result = new WaitResult();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700600 result.who = intent.getComponent();
601 }
602 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
Louis Chang0513a942019-03-06 12:38:13 +0800603 pw.println("LaunchState: " + launchStateToString(result.launchState));
Dianne Hackborn354736e2016-08-22 17:00:05 -0700604 if (result.who != null) {
605 pw.println("Activity: " + result.who.flattenToShortString());
606 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700607 if (result.totalTime >= 0) {
608 pw.println("TotalTime: " + result.totalTime);
609 }
610 pw.println("WaitTime: " + (endTime-startTime));
611 pw.println("Complete");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700612 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700613 }
614 mRepeat--;
615 if (mRepeat > 0) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700616 mTaskInterface.unhandledBack();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700617 }
618 } while (mRepeat > 0);
619 return 0;
620 }
621
Christopher Tate7e1368d2017-03-30 17:20:12 -0700622 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700623 final PrintWriter err = getErrPrintWriter();
624 Intent intent;
625 try {
626 intent = makeIntent(UserHandle.USER_CURRENT);
627 } catch (URISyntaxException e) {
628 throw new RuntimeException(e.getMessage(), e);
629 }
630 if (mUserId == UserHandle.USER_ALL) {
631 err.println("Error: Can't start activity with user 'all'");
632 return -1;
633 }
634 pw.println("Starting service: " + intent);
635 pw.flush();
636 ComponentName cn = mInterface.startService(null, intent, intent.getType(),
Christopher Tate242ba3e92017-04-14 15:07:06 -0700637 asForeground, SHELL_PACKAGE_NAME, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700638 if (cn == null) {
639 err.println("Error: Not found; no service started.");
640 return -1;
641 } else if (cn.getPackageName().equals("!")) {
642 err.println("Error: Requires permission " + cn.getClassName());
643 return -1;
644 } else if (cn.getPackageName().equals("!!")) {
645 err.println("Error: " + cn.getClassName());
646 return -1;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800647 } else if (cn.getPackageName().equals("?")) {
648 err.println("Error: " + cn.getClassName());
649 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700650 }
651 return 0;
652 }
653
654 int runStopService(PrintWriter pw) throws RemoteException {
655 final PrintWriter err = getErrPrintWriter();
656 Intent intent;
657 try {
658 intent = makeIntent(UserHandle.USER_CURRENT);
659 } catch (URISyntaxException e) {
660 throw new RuntimeException(e.getMessage(), e);
661 }
662 if (mUserId == UserHandle.USER_ALL) {
663 err.println("Error: Can't stop activity with user 'all'");
664 return -1;
665 }
666 pw.println("Stopping service: " + intent);
667 pw.flush();
668 int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
669 if (result == 0) {
670 err.println("Service not stopped: was not running.");
671 return -1;
672 } else if (result == 1) {
673 err.println("Service stopped");
674 return -1;
675 } else if (result == -1) {
676 err.println("Error stopping service");
677 return -1;
678 }
679 return 0;
680 }
681
682 final static class IntentReceiver extends IIntentReceiver.Stub {
683 private final PrintWriter mPw;
684 private boolean mFinished = false;
685
686 IntentReceiver(PrintWriter pw) {
687 mPw = pw;
688 }
689
690 @Override
691 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
692 boolean ordered, boolean sticky, int sendingUser) {
693 String line = "Broadcast completed: result=" + resultCode;
694 if (data != null) line = line + ", data=\"" + data + "\"";
695 if (extras != null) line = line + ", extras: " + extras;
696 mPw.println(line);
697 mPw.flush();
698 synchronized (this) {
699 mFinished = true;
700 notifyAll();
701 }
702 }
703
704 public synchronized void waitForFinish() {
705 try {
706 while (!mFinished) wait();
707 } catch (InterruptedException e) {
708 throw new IllegalStateException(e);
709 }
710 }
711 }
712
713 int runSendBroadcast(PrintWriter pw) throws RemoteException {
714 Intent intent;
715 try {
716 intent = makeIntent(UserHandle.USER_CURRENT);
717 } catch (URISyntaxException e) {
718 throw new RuntimeException(e.getMessage(), e);
719 }
Jeff Sharkey6a34e562016-12-21 09:56:00 -0700720 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700721 IntentReceiver receiver = new IntentReceiver(pw);
722 String[] requiredPermissions = mReceiverPermission == null ? null
723 : new String[] {mReceiverPermission};
724 pw.println("Broadcasting: " + intent);
725 pw.flush();
726 mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
727 android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
728 receiver.waitForFinish();
729 return 0;
730 }
731
Dianne Hackborn331084d2016-10-07 17:57:00 -0700732 int runTraceIpc(PrintWriter pw) throws RemoteException {
733 String op = getNextArgRequired();
734 if (op.equals("start")) {
735 return runTraceIpcStart(pw);
736 } else if (op.equals("stop")) {
737 return runTraceIpcStop(pw);
738 } else {
739 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'");
740 return -1;
741 }
742 }
743
744 int runTraceIpcStart(PrintWriter pw) throws RemoteException {
745 pw.println("Starting IPC tracing.");
746 pw.flush();
747 mInterface.startBinderTracking();
748 return 0;
749 }
750
751 int runTraceIpcStop(PrintWriter pw) throws RemoteException {
752 final PrintWriter err = getErrPrintWriter();
753 String opt;
754 String filename = null;
755 while ((opt=getNextOption()) != null) {
756 if (opt.equals("--dump-file")) {
757 filename = getNextArgRequired();
758 } else {
759 err.println("Error: Unknown option: " + opt);
760 return -1;
761 }
762 }
763 if (filename == null) {
764 err.println("Error: Specify filename to dump logs to.");
765 return -1;
766 }
767
768 File file = new File(filename);
769 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700770 ParcelFileDescriptor fd = openFileForSystem(filename, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700771 if (fd == null) {
772 return -1;
773 }
774
Dianne Hackborn331084d2016-10-07 17:57:00 -0700775 if (!mInterface.stopBinderTrackingAndDump(fd)) {
776 err.println("STOP TRACE FAILED.");
777 return -1;
778 }
779
780 pw.println("Stopped IPC tracing. Dumping logs to: " + filename);
781 return 0;
782 }
783
784 static void removeWallOption() {
785 String props = SystemProperties.get("dalvik.vm.extra-opts");
786 if (props != null && props.contains("-Xprofile:wallclock")) {
787 props = props.replace("-Xprofile:wallclock", "");
788 props = props.trim();
789 SystemProperties.set("dalvik.vm.extra-opts", props);
790 }
791 }
792
793 private int runProfile(PrintWriter pw) throws RemoteException {
794 final PrintWriter err = getErrPrintWriter();
795 String profileFile = null;
796 boolean start = false;
797 boolean wall = false;
798 int userId = UserHandle.USER_CURRENT;
799 int profileType = 0;
800 mSamplingInterval = 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800801 mStreaming = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700802
803 String process = null;
804
805 String cmd = getNextArgRequired();
806
807 if ("start".equals(cmd)) {
808 start = true;
809 String opt;
810 while ((opt=getNextOption()) != null) {
811 if (opt.equals("--user")) {
812 userId = UserHandle.parseUserArg(getNextArgRequired());
813 } else if (opt.equals("--wall")) {
814 wall = true;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800815 } else if (opt.equals("--streaming")) {
816 mStreaming = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700817 } else if (opt.equals("--sampling")) {
818 mSamplingInterval = Integer.parseInt(getNextArgRequired());
819 } else {
820 err.println("Error: Unknown option: " + opt);
821 return -1;
822 }
823 }
824 process = getNextArgRequired();
825 } else if ("stop".equals(cmd)) {
826 String opt;
827 while ((opt=getNextOption()) != null) {
828 if (opt.equals("--user")) {
829 userId = UserHandle.parseUserArg(getNextArgRequired());
830 } else {
831 err.println("Error: Unknown option: " + opt);
832 return -1;
833 }
834 }
Orion Hodson4e6a3142019-04-08 10:12:02 +0100835 process = getNextArgRequired();
Dianne Hackborn331084d2016-10-07 17:57:00 -0700836 } else {
837 // Compatibility with old syntax: process is specified first.
838 process = cmd;
839 cmd = getNextArgRequired();
840 if ("start".equals(cmd)) {
841 start = true;
842 } else if (!"stop".equals(cmd)) {
843 throw new IllegalArgumentException("Profile command " + process + " not valid");
844 }
845 }
846
847 if (userId == UserHandle.USER_ALL) {
848 err.println("Error: Can't profile with user 'all'");
849 return -1;
850 }
851
852 ParcelFileDescriptor fd = null;
853 ProfilerInfo profilerInfo = null;
854
855 if (start) {
856 profileFile = getNextArgRequired();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700857 fd = openFileForSystem(profileFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700858 if (fd == null) {
859 return -1;
860 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700861 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800862 null, false);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700863 }
864
865 try {
866 if (wall) {
867 // XXX doesn't work -- this needs to be set before booting.
868 String props = SystemProperties.get("dalvik.vm.extra-opts");
869 if (props == null || !props.contains("-Xprofile:wallclock")) {
870 props = props + " -Xprofile:wallclock";
871 //SystemProperties.set("dalvik.vm.extra-opts", props);
872 }
873 } else if (start) {
874 //removeWallOption();
875 }
876 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
877 wall = false;
878 err.println("PROFILE FAILED on process " + process);
879 return -1;
880 }
881 } finally {
882 if (!wall) {
883 //removeWallOption();
884 }
885 }
886 return 0;
887 }
888
889 int runDumpHeap(PrintWriter pw) throws RemoteException {
890 final PrintWriter err = getErrPrintWriter();
891 boolean managed = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700892 boolean mallocInfo = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700893 int userId = UserHandle.USER_CURRENT;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700894 boolean runGc = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700895
896 String opt;
897 while ((opt=getNextOption()) != null) {
898 if (opt.equals("--user")) {
899 userId = UserHandle.parseUserArg(getNextArgRequired());
900 if (userId == UserHandle.USER_ALL) {
901 err.println("Error: Can't dump heap with user 'all'");
902 return -1;
903 }
904 } else if (opt.equals("-n")) {
905 managed = false;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700906 } else if (opt.equals("-g")) {
907 runGc = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700908 } else if (opt.equals("-m")) {
909 managed = false;
910 mallocInfo = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700911 } else {
912 err.println("Error: Unknown option: " + opt);
913 return -1;
914 }
915 }
916 String process = getNextArgRequired();
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700917 String heapFile = getNextArg();
918 if (heapFile == null) {
919 final Time t = new Time();
920 t.set(System.currentTimeMillis());
921 heapFile = "/data/local/tmp/heapdump-" + t.format("%Y%m%d-%H%M%S") + ".prof";
922 }
923 pw.println("File: " + heapFile);
924 pw.flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -0700925
926 File file = new File(heapFile);
927 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700928 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700929 if (fd == null) {
930 return -1;
931 }
932
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700933 final CountDownLatch latch = new CountDownLatch(1);
934
935 final RemoteCallback finishCallback = new RemoteCallback(new OnResultListener() {
936 @Override
937 public void onResult(Bundle result) {
938 latch.countDown();
939 }
940 }, null);
941
942 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd,
943 finishCallback)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700944 err.println("HEAP DUMP FAILED on process " + process);
945 return -1;
946 }
Makoto Onuki2c6657f2018-06-06 15:24:02 -0700947 pw.println("Waiting for dump to finish...");
948 pw.flush();
949 try {
950 latch.await();
951 } catch (InterruptedException e) {
952 err.println("Caught InterruptedException");
953 }
954
Dianne Hackborn331084d2016-10-07 17:57:00 -0700955 return 0;
956 }
957
958 int runSetDebugApp(PrintWriter pw) throws RemoteException {
959 boolean wait = false;
960 boolean persistent = false;
961
962 String opt;
963 while ((opt=getNextOption()) != null) {
964 if (opt.equals("-w")) {
965 wait = true;
966 } else if (opt.equals("--persistent")) {
967 persistent = true;
968 } else {
969 getErrPrintWriter().println("Error: Unknown option: " + opt);
970 return -1;
971 }
972 }
973
974 String pkg = getNextArgRequired();
975 mInterface.setDebugApp(pkg, wait, persistent);
976 return 0;
977 }
978
Andreas Gampe5b495d52018-01-22 15:15:54 -0800979 int runSetAgentApp(PrintWriter pw) throws RemoteException {
980 String pkg = getNextArgRequired();
981 String agent = getNextArg();
982 mInterface.setAgentApp(pkg, agent);
983 return 0;
984 }
985
Dianne Hackborn331084d2016-10-07 17:57:00 -0700986 int runClearDebugApp(PrintWriter pw) throws RemoteException {
987 mInterface.setDebugApp(null, false, true);
988 return 0;
989 }
990
991 int runSetWatchHeap(PrintWriter pw) throws RemoteException {
992 String proc = getNextArgRequired();
993 String limit = getNextArgRequired();
994 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
995 return 0;
996 }
997
998 int runClearWatchHeap(PrintWriter pw) throws RemoteException {
999 String proc = getNextArgRequired();
1000 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null);
1001 return 0;
1002 }
1003
1004 int runBugReport(PrintWriter pw) throws RemoteException {
1005 String opt;
1006 int bugreportType = ActivityManager.BUGREPORT_OPTION_FULL;
1007 while ((opt=getNextOption()) != null) {
1008 if (opt.equals("--progress")) {
1009 bugreportType = ActivityManager.BUGREPORT_OPTION_INTERACTIVE;
Felipe Leme9606c3b2017-01-05 14:57:12 -08001010 } else if (opt.equals("--telephony")) {
1011 bugreportType = ActivityManager.BUGREPORT_OPTION_TELEPHONY;
Dianne Hackborn331084d2016-10-07 17:57:00 -07001012 } else {
1013 getErrPrintWriter().println("Error: Unknown option: " + opt);
1014 return -1;
1015 }
1016 }
1017 mInterface.requestBugReport(bugreportType);
1018 pw.println("Your lovely bug report is being created; please be patient.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08001019 return 0;
1020 }
1021
Dianne Hackborn2e441072015-10-28 18:00:57 -07001022 int runForceStop(PrintWriter pw) throws RemoteException {
1023 int userId = UserHandle.USER_ALL;
1024
1025 String opt;
1026 while ((opt = getNextOption()) != null) {
1027 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001028 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001029 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001030 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001031 return -1;
1032 }
1033 }
1034 mInterface.forceStopPackage(getNextArgRequired(), userId);
1035 return 0;
1036 }
1037
Christopher Tate8aa8fe12017-01-20 17:50:32 -08001038 int runCrash(PrintWriter pw) throws RemoteException {
1039 int userId = UserHandle.USER_ALL;
1040
1041 String opt;
1042 while ((opt=getNextOption()) != null) {
1043 if (opt.equals("--user")) {
1044 userId = UserHandle.parseUserArg(getNextArgRequired());
1045 } else {
1046 getErrPrintWriter().println("Error: Unknown option: " + opt);
1047 return -1;
1048 }
1049 }
1050
1051 int pid = -1;
1052 String packageName = null;
1053 final String arg = getNextArgRequired();
1054 // The argument is either a pid or a package name
1055 try {
1056 pid = Integer.parseInt(arg);
1057 } catch (NumberFormatException e) {
1058 packageName = arg;
1059 }
1060 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
1061 return 0;
1062 }
1063
Dianne Hackborn2e441072015-10-28 18:00:57 -07001064 int runKill(PrintWriter pw) throws RemoteException {
1065 int userId = UserHandle.USER_ALL;
1066
1067 String opt;
1068 while ((opt=getNextOption()) != null) {
1069 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001070 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001071 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001072 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001073 return -1;
1074 }
1075 }
1076 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
1077 return 0;
1078 }
1079
1080 int runKillAll(PrintWriter pw) throws RemoteException {
1081 mInterface.killAllBackgroundProcesses();
1082 return 0;
1083 }
1084
Dianne Hackborne07641d2016-11-09 15:07:23 -08001085 int runMakeIdle(PrintWriter pw) throws RemoteException {
1086 int userId = UserHandle.USER_ALL;
1087
1088 String opt;
1089 while ((opt = getNextOption()) != null) {
1090 if (opt.equals("--user")) {
1091 userId = UserHandle.parseUserArg(getNextArgRequired());
1092 } else {
1093 getErrPrintWriter().println("Error: Unknown option: " + opt);
1094 return -1;
1095 }
1096 }
1097 mInterface.makePackageIdle(getNextArgRequired(), userId);
1098 return 0;
1099 }
1100
Dianne Hackborn331084d2016-10-07 17:57:00 -07001101 static final class MyActivityController extends IActivityController.Stub {
1102 final IActivityManager mInterface;
1103 final PrintWriter mPw;
1104 final InputStream mInput;
1105 final String mGdbPort;
1106 final boolean mMonkey;
1107
1108 static final int STATE_NORMAL = 0;
1109 static final int STATE_CRASHED = 1;
1110 static final int STATE_EARLY_ANR = 2;
1111 static final int STATE_ANR = 3;
1112
1113 int mState;
1114
1115 static final int RESULT_DEFAULT = 0;
1116
1117 static final int RESULT_CRASH_DIALOG = 0;
1118 static final int RESULT_CRASH_KILL = 1;
1119
1120 static final int RESULT_EARLY_ANR_CONTINUE = 0;
1121 static final int RESULT_EARLY_ANR_KILL = 1;
1122
1123 static final int RESULT_ANR_DIALOG = 0;
1124 static final int RESULT_ANR_KILL = 1;
1125 static final int RESULT_ANR_WAIT = 1;
1126
1127 int mResult;
1128
1129 Process mGdbProcess;
1130 Thread mGdbThread;
1131 boolean mGotGdbPrint;
1132
1133 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
1134 String gdbPort, boolean monkey) {
1135 mInterface = iam;
1136 mPw = pw;
1137 mInput = input;
1138 mGdbPort = gdbPort;
1139 mMonkey = monkey;
1140 }
1141
1142 @Override
1143 public boolean activityResuming(String pkg) {
1144 synchronized (this) {
1145 mPw.println("** Activity resuming: " + pkg);
1146 mPw.flush();
1147 }
1148 return true;
1149 }
1150
1151 @Override
1152 public boolean activityStarting(Intent intent, String pkg) {
1153 synchronized (this) {
1154 mPw.println("** Activity starting: " + pkg);
1155 mPw.flush();
1156 }
1157 return true;
1158 }
1159
1160 @Override
1161 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
1162 long timeMillis, String stackTrace) {
1163 synchronized (this) {
1164 mPw.println("** ERROR: PROCESS CRASHED");
1165 mPw.println("processName: " + processName);
1166 mPw.println("processPid: " + pid);
1167 mPw.println("shortMsg: " + shortMsg);
1168 mPw.println("longMsg: " + longMsg);
1169 mPw.println("timeMillis: " + timeMillis);
1170 mPw.println("stack:");
1171 mPw.print(stackTrace);
1172 mPw.println("#");
1173 mPw.flush();
1174 int result = waitControllerLocked(pid, STATE_CRASHED);
1175 return result == RESULT_CRASH_KILL ? false : true;
1176 }
1177 }
1178
1179 @Override
1180 public int appEarlyNotResponding(String processName, int pid, String annotation) {
1181 synchronized (this) {
1182 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING");
1183 mPw.println("processName: " + processName);
1184 mPw.println("processPid: " + pid);
1185 mPw.println("annotation: " + annotation);
1186 mPw.flush();
1187 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
1188 if (result == RESULT_EARLY_ANR_KILL) return -1;
1189 return 0;
1190 }
1191 }
1192
1193 @Override
1194 public int appNotResponding(String processName, int pid, String processStats) {
1195 synchronized (this) {
1196 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1197 mPw.println("processName: " + processName);
1198 mPw.println("processPid: " + pid);
1199 mPw.println("processStats:");
1200 mPw.print(processStats);
1201 mPw.println("#");
1202 mPw.flush();
1203 int result = waitControllerLocked(pid, STATE_ANR);
1204 if (result == RESULT_ANR_KILL) return -1;
1205 if (result == RESULT_ANR_WAIT) return 1;
1206 return 0;
1207 }
1208 }
1209
1210 @Override
1211 public int systemNotResponding(String message) {
1212 synchronized (this) {
1213 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1214 mPw.println("message: " + message);
1215 mPw.println("#");
1216 mPw.println("Allowing system to die.");
1217 mPw.flush();
1218 return -1;
1219 }
1220 }
1221
1222 void killGdbLocked() {
1223 mGotGdbPrint = false;
1224 if (mGdbProcess != null) {
1225 mPw.println("Stopping gdbserver");
1226 mPw.flush();
1227 mGdbProcess.destroy();
1228 mGdbProcess = null;
1229 }
1230 if (mGdbThread != null) {
1231 mGdbThread.interrupt();
1232 mGdbThread = null;
1233 }
1234 }
1235
1236 int waitControllerLocked(int pid, int state) {
1237 if (mGdbPort != null) {
1238 killGdbLocked();
1239
1240 try {
1241 mPw.println("Starting gdbserver on port " + mGdbPort);
1242 mPw.println("Do the following:");
1243 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
1244 mPw.println(" gdbclient app_process :" + mGdbPort);
1245 mPw.flush();
1246
1247 mGdbProcess = Runtime.getRuntime().exec(new String[] {
1248 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
1249 });
1250 final InputStreamReader converter = new InputStreamReader(
1251 mGdbProcess.getInputStream());
1252 mGdbThread = new Thread() {
1253 @Override
1254 public void run() {
1255 BufferedReader in = new BufferedReader(converter);
1256 String line;
1257 int count = 0;
1258 while (true) {
1259 synchronized (MyActivityController.this) {
1260 if (mGdbThread == null) {
1261 return;
1262 }
1263 if (count == 2) {
1264 mGotGdbPrint = true;
1265 MyActivityController.this.notifyAll();
1266 }
1267 }
1268 try {
1269 line = in.readLine();
1270 if (line == null) {
1271 return;
1272 }
1273 mPw.println("GDB: " + line);
1274 mPw.flush();
1275 count++;
1276 } catch (IOException e) {
1277 return;
1278 }
1279 }
1280 }
1281 };
1282 mGdbThread.start();
1283
1284 // Stupid waiting for .5s. Doesn't matter if we end early.
1285 try {
1286 this.wait(500);
1287 } catch (InterruptedException e) {
1288 }
1289
1290 } catch (IOException e) {
1291 mPw.println("Failure starting gdbserver: " + e);
1292 mPw.flush();
1293 killGdbLocked();
1294 }
1295 }
1296 mState = state;
1297 mPw.println("");
1298 printMessageForState();
1299 mPw.flush();
1300
1301 while (mState != STATE_NORMAL) {
1302 try {
1303 wait();
1304 } catch (InterruptedException e) {
1305 }
1306 }
1307
1308 killGdbLocked();
1309
1310 return mResult;
1311 }
1312
1313 void resumeController(int result) {
1314 synchronized (this) {
1315 mState = STATE_NORMAL;
1316 mResult = result;
1317 notifyAll();
1318 }
1319 }
1320
1321 void printMessageForState() {
1322 switch (mState) {
1323 case STATE_NORMAL:
1324 mPw.println("Monitoring activity manager... available commands:");
1325 break;
1326 case STATE_CRASHED:
1327 mPw.println("Waiting after crash... available commands:");
1328 mPw.println("(c)ontinue: show crash dialog");
1329 mPw.println("(k)ill: immediately kill app");
1330 break;
1331 case STATE_EARLY_ANR:
1332 mPw.println("Waiting after early ANR... available commands:");
1333 mPw.println("(c)ontinue: standard ANR processing");
1334 mPw.println("(k)ill: immediately kill app");
1335 break;
1336 case STATE_ANR:
1337 mPw.println("Waiting after ANR... available commands:");
1338 mPw.println("(c)ontinue: show ANR dialog");
1339 mPw.println("(k)ill: immediately kill app");
1340 mPw.println("(w)ait: wait some more");
1341 break;
1342 }
1343 mPw.println("(q)uit: finish monitoring");
1344 }
1345
1346 void run() throws RemoteException {
1347 try {
1348 printMessageForState();
1349 mPw.flush();
1350
1351 mInterface.setActivityController(this, mMonkey);
1352 mState = STATE_NORMAL;
1353
1354 InputStreamReader converter = new InputStreamReader(mInput);
1355 BufferedReader in = new BufferedReader(converter);
1356 String line;
1357
1358 while ((line = in.readLine()) != null) {
1359 boolean addNewline = true;
1360 if (line.length() <= 0) {
1361 addNewline = false;
1362 } else if ("q".equals(line) || "quit".equals(line)) {
1363 resumeController(RESULT_DEFAULT);
1364 break;
1365 } else if (mState == STATE_CRASHED) {
1366 if ("c".equals(line) || "continue".equals(line)) {
1367 resumeController(RESULT_CRASH_DIALOG);
1368 } else if ("k".equals(line) || "kill".equals(line)) {
1369 resumeController(RESULT_CRASH_KILL);
1370 } else {
1371 mPw.println("Invalid command: " + line);
1372 }
1373 } else if (mState == STATE_ANR) {
1374 if ("c".equals(line) || "continue".equals(line)) {
1375 resumeController(RESULT_ANR_DIALOG);
1376 } else if ("k".equals(line) || "kill".equals(line)) {
1377 resumeController(RESULT_ANR_KILL);
1378 } else if ("w".equals(line) || "wait".equals(line)) {
1379 resumeController(RESULT_ANR_WAIT);
1380 } else {
1381 mPw.println("Invalid command: " + line);
1382 }
1383 } else if (mState == STATE_EARLY_ANR) {
1384 if ("c".equals(line) || "continue".equals(line)) {
1385 resumeController(RESULT_EARLY_ANR_CONTINUE);
1386 } else if ("k".equals(line) || "kill".equals(line)) {
1387 resumeController(RESULT_EARLY_ANR_KILL);
1388 } else {
1389 mPw.println("Invalid command: " + line);
1390 }
1391 } else {
1392 mPw.println("Invalid command: " + line);
1393 }
1394
1395 synchronized (this) {
1396 if (addNewline) {
1397 mPw.println("");
1398 }
1399 printMessageForState();
1400 mPw.flush();
1401 }
1402 }
1403
1404 } catch (IOException e) {
1405 e.printStackTrace(mPw);
1406 mPw.flush();
1407 } finally {
1408 mInterface.setActivityController(null, mMonkey);
1409 }
1410 }
1411 }
1412
1413 int runMonitor(PrintWriter pw) throws RemoteException {
1414 String opt;
1415 String gdbPort = null;
1416 boolean monkey = false;
1417 while ((opt=getNextOption()) != null) {
1418 if (opt.equals("--gdb")) {
1419 gdbPort = getNextArgRequired();
1420 } else if (opt.equals("-m")) {
1421 monkey = true;
1422 } else {
1423 getErrPrintWriter().println("Error: Unknown option: " + opt);
1424 return -1;
1425 }
1426 }
1427
1428 MyActivityController controller = new MyActivityController(mInterface, pw,
1429 getRawInputStream(), gdbPort, monkey);
1430 controller.run();
1431 return 0;
1432 }
1433
Dianne Hackborne51505a2017-08-07 17:13:52 -07001434 static final class MyUidObserver extends IUidObserver.Stub
1435 implements ActivityManagerService.OomAdjObserver {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001436 final IActivityManager mInterface;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001437 final ActivityManagerService mInternal;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001438 final PrintWriter mPw;
1439 final InputStream mInput;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001440 final int mUid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001441
1442 static final int STATE_NORMAL = 0;
1443
1444 int mState;
1445
Dianne Hackborne51505a2017-08-07 17:13:52 -07001446 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
1447 mInterface = service;
1448 mInternal = service;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001449 mPw = pw;
1450 mInput = input;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001451 mUid = uid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001452 }
1453
1454 @Override
1455 public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException {
1456 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001457 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1458 try {
1459 mPw.print(uid);
1460 mPw.print(" procstate ");
1461 mPw.print(ProcessList.makeProcStateString(procState));
1462 mPw.print(" seq ");
1463 mPw.println(procStateSeq);
1464 mPw.flush();
1465 } finally {
1466 StrictMode.setThreadPolicy(oldPolicy);
1467 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001468 }
1469 }
1470
1471 @Override
1472 public void onUidGone(int uid, boolean disabled) throws RemoteException {
1473 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001474 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1475 try {
1476 mPw.print(uid);
1477 mPw.print(" gone");
1478 if (disabled) {
1479 mPw.print(" disabled");
1480 }
1481 mPw.println();
1482 mPw.flush();
1483 } finally {
1484 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001485 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001486 }
1487 }
1488
1489 @Override
1490 public void onUidActive(int uid) throws RemoteException {
1491 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001492 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1493 try {
1494 mPw.print(uid);
1495 mPw.println(" active");
1496 mPw.flush();
1497 } finally {
1498 StrictMode.setThreadPolicy(oldPolicy);
1499 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001500 }
1501 }
1502
1503 @Override
1504 public void onUidIdle(int uid, boolean disabled) throws RemoteException {
1505 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001506 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1507 try {
1508 mPw.print(uid);
1509 mPw.print(" idle");
1510 if (disabled) {
1511 mPw.print(" disabled");
1512 }
1513 mPw.println();
1514 mPw.flush();
1515 } finally {
1516 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001517 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001518 }
1519 }
1520
1521 @Override
1522 public void onUidCachedChanged(int uid, boolean cached) throws RemoteException {
1523 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001524 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1525 try {
1526 mPw.print(uid);
1527 mPw.println(cached ? " cached" : " uncached");
1528 mPw.flush();
1529 } finally {
1530 StrictMode.setThreadPolicy(oldPolicy);
1531 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001532 }
1533 }
1534
Dianne Hackborne51505a2017-08-07 17:13:52 -07001535 @Override
1536 public void onOomAdjMessage(String msg) {
1537 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001538 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1539 try {
1540 mPw.print("# ");
1541 mPw.println(msg);
1542 mPw.flush();
1543 } finally {
1544 StrictMode.setThreadPolicy(oldPolicy);
1545 }
Dianne Hackborne51505a2017-08-07 17:13:52 -07001546 }
1547 }
1548
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001549 void printMessageForState() {
1550 switch (mState) {
1551 case STATE_NORMAL:
1552 mPw.println("Watching uid states... available commands:");
1553 break;
1554 }
1555 mPw.println("(q)uit: finish watching");
1556 }
1557
1558 void run() throws RemoteException {
1559 try {
1560 printMessageForState();
1561 mPw.flush();
1562
1563 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE
1564 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
1565 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
1566 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackborne51505a2017-08-07 17:13:52 -07001567 if (mUid >= 0) {
1568 mInternal.setOomAdjObserver(mUid, this);
1569 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001570 mState = STATE_NORMAL;
1571
1572 InputStreamReader converter = new InputStreamReader(mInput);
1573 BufferedReader in = new BufferedReader(converter);
1574 String line;
1575
1576 while ((line = in.readLine()) != null) {
1577 boolean addNewline = true;
1578 if (line.length() <= 0) {
1579 addNewline = false;
1580 } else if ("q".equals(line) || "quit".equals(line)) {
1581 break;
1582 } else {
1583 mPw.println("Invalid command: " + line);
1584 }
1585
1586 synchronized (this) {
1587 if (addNewline) {
1588 mPw.println("");
1589 }
1590 printMessageForState();
1591 mPw.flush();
1592 }
1593 }
1594
1595 } catch (IOException e) {
1596 e.printStackTrace(mPw);
1597 mPw.flush();
1598 } finally {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001599 if (mUid >= 0) {
1600 mInternal.clearOomAdjObserver();
1601 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001602 mInterface.unregisterUidObserver(this);
1603 }
1604 }
1605 }
1606
1607 int runWatchUids(PrintWriter pw) throws RemoteException {
1608 String opt;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001609 int uid = -1;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001610 while ((opt=getNextOption()) != null) {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001611 if (opt.equals("--oom")) {
1612 uid = Integer.parseInt(getNextArgRequired());
1613 } else {
1614 getErrPrintWriter().println("Error: Unknown option: " + opt);
1615 return -1;
1616
1617 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001618 }
1619
Dianne Hackborne51505a2017-08-07 17:13:52 -07001620 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001621 controller.run();
1622 return 0;
1623 }
1624
Dianne Hackborn331084d2016-10-07 17:57:00 -07001625 int runHang(PrintWriter pw) throws RemoteException {
1626 String opt;
1627 boolean allowRestart = false;
1628 while ((opt=getNextOption()) != null) {
1629 if (opt.equals("--allow-restart")) {
1630 allowRestart = true;
1631 } else {
1632 getErrPrintWriter().println("Error: Unknown option: " + opt);
1633 return -1;
1634 }
1635 }
1636
1637 pw.println("Hanging the system...");
1638 pw.flush();
1639 mInterface.hang(new Binder(), allowRestart);
1640 return 0;
1641 }
1642
1643 int runRestart(PrintWriter pw) throws RemoteException {
1644 String opt;
1645 while ((opt=getNextOption()) != null) {
1646 getErrPrintWriter().println("Error: Unknown option: " + opt);
1647 return -1;
1648 }
1649
1650 pw.println("Restart the system...");
1651 pw.flush();
1652 mInterface.restart();
1653 return 0;
1654 }
1655
1656 int runIdleMaintenance(PrintWriter pw) throws RemoteException {
1657 String opt;
1658 while ((opt=getNextOption()) != null) {
1659 getErrPrintWriter().println("Error: Unknown option: " + opt);
1660 return -1;
1661 }
1662
1663 pw.println("Performing idle maintenance...");
1664 mInterface.sendIdleJobTrigger();
1665 return 0;
1666 }
1667
1668 int runScreenCompat(PrintWriter pw) throws RemoteException {
1669 String mode = getNextArgRequired();
1670 boolean enabled;
1671 if ("on".equals(mode)) {
1672 enabled = true;
1673 } else if ("off".equals(mode)) {
1674 enabled = false;
1675 } else {
1676 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode);
1677 return -1;
1678 }
1679
1680 String packageName = getNextArgRequired();
1681 do {
1682 try {
1683 mInterface.setPackageScreenCompatMode(packageName, enabled
1684 ? ActivityManager.COMPAT_MODE_ENABLED
1685 : ActivityManager.COMPAT_MODE_DISABLED);
1686 } catch (RemoteException e) {
1687 }
1688 packageName = getNextArg();
1689 } while (packageName != null);
1690 return 0;
1691 }
1692
1693 int runPackageImportance(PrintWriter pw) throws RemoteException {
1694 String packageName = getNextArgRequired();
1695 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell");
1696 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
1697 return 0;
1698 }
1699
1700 int runToUri(PrintWriter pw, int flags) throws RemoteException {
1701 Intent intent;
1702 try {
1703 intent = makeIntent(UserHandle.USER_CURRENT);
1704 } catch (URISyntaxException e) {
1705 throw new RuntimeException(e.getMessage(), e);
1706 }
1707 pw.println(intent.toUri(flags));
1708 return 0;
1709 }
1710
1711 int runSwitchUser(PrintWriter pw) throws RemoteException {
Alex Chau5c0df232018-02-22 15:57:17 +08001712 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
Varun Shah50ef2002019-03-04 16:41:12 -08001713 final int userSwitchable = userManager.getUserSwitchability();
1714 if (userSwitchable != UserManager.SWITCHABILITY_STATUS_OK) {
1715 getErrPrintWriter().println("Error: " + userSwitchable);
Alex Chau5c0df232018-02-22 15:57:17 +08001716 return -1;
1717 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001718 String user = getNextArgRequired();
1719 mInterface.switchUser(Integer.parseInt(user));
1720 return 0;
1721 }
1722
1723 int runGetCurrentUser(PrintWriter pw) throws RemoteException {
1724 UserInfo currentUser = Preconditions.checkNotNull(mInterface.getCurrentUser(),
1725 "Current user not set");
1726 pw.println(currentUser.id);
1727 return 0;
1728 }
1729
1730 int runStartUser(PrintWriter pw) throws RemoteException {
Bookatz03bfe6f2019-03-01 15:46:04 -08001731 boolean wait = false;
1732 String opt;
1733 while ((opt = getNextOption()) != null) {
1734 if ("-w".equals(opt)) {
1735 wait = true;
1736 } else {
1737 getErrPrintWriter().println("Error: unknown option: " + opt);
1738 return -1;
1739 }
1740 }
1741 int userId = Integer.parseInt(getNextArgRequired());
1742
1743 final ProgressWaiter waiter = wait ? new ProgressWaiter() : null;
1744 boolean success = mInterface.startUserInBackgroundWithListener(userId, waiter);
1745 if (wait && success) {
1746 success = waiter.waitForFinish(USER_OPERATION_TIMEOUT_MS);
1747 }
1748
Dianne Hackborn331084d2016-10-07 17:57:00 -07001749 if (success) {
1750 pw.println("Success: user started");
1751 } else {
1752 getErrPrintWriter().println("Error: could not start user");
1753 }
1754 return 0;
1755 }
1756
1757 private static byte[] argToBytes(String arg) {
1758 if (arg.equals("!")) {
1759 return null;
1760 } else {
1761 return HexDump.hexStringToByteArray(arg);
1762 }
1763 }
1764
1765 int runUnlockUser(PrintWriter pw) throws RemoteException {
1766 int userId = Integer.parseInt(getNextArgRequired());
1767 byte[] token = argToBytes(getNextArgRequired());
1768 byte[] secret = argToBytes(getNextArgRequired());
1769 boolean success = mInterface.unlockUser(userId, token, secret, null);
1770 if (success) {
1771 pw.println("Success: user unlocked");
1772 } else {
1773 getErrPrintWriter().println("Error: could not unlock user");
1774 }
1775 return 0;
1776 }
1777
1778 static final class StopUserCallback extends IStopUserCallback.Stub {
1779 private boolean mFinished = false;
1780
1781 public synchronized void waitForFinish() {
1782 try {
1783 while (!mFinished) wait();
1784 } catch (InterruptedException e) {
1785 throw new IllegalStateException(e);
1786 }
1787 }
1788
1789 @Override
1790 public synchronized void userStopped(int userId) {
1791 mFinished = true;
1792 notifyAll();
1793 }
1794
1795 @Override
1796 public synchronized void userStopAborted(int userId) {
1797 mFinished = true;
1798 notifyAll();
1799 }
1800 }
1801
1802 int runStopUser(PrintWriter pw) throws RemoteException {
1803 boolean wait = false;
1804 boolean force = false;
1805 String opt;
1806 while ((opt = getNextOption()) != null) {
1807 if ("-w".equals(opt)) {
1808 wait = true;
1809 } else if ("-f".equals(opt)) {
1810 force = true;
1811 } else {
1812 getErrPrintWriter().println("Error: unknown option: " + opt);
1813 return -1;
1814 }
1815 }
1816 int user = Integer.parseInt(getNextArgRequired());
1817 StopUserCallback callback = wait ? new StopUserCallback() : null;
1818
1819 int res = mInterface.stopUser(user, force, callback);
1820 if (res != ActivityManager.USER_OP_SUCCESS) {
1821 String txt = "";
1822 switch (res) {
1823 case ActivityManager.USER_OP_IS_CURRENT:
1824 txt = " (Can't stop current user)";
1825 break;
1826 case ActivityManager.USER_OP_UNKNOWN_USER:
1827 txt = " (Unknown user " + user + ")";
1828 break;
1829 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
1830 txt = " (System user cannot be stopped)";
1831 break;
1832 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP:
1833 txt = " (Can't stop user " + user
1834 + " - one of its related users can't be stopped)";
1835 break;
1836 }
1837 getErrPrintWriter().println("Switch failed: " + res + txt);
1838 return -1;
1839 } else if (callback != null) {
1840 callback.waitForFinish();
1841 }
1842 return 0;
1843 }
1844
1845 int runIsUserStopped(PrintWriter pw) {
1846 int userId = UserHandle.parseUserArg(getNextArgRequired());
1847 boolean stopped = mInternal.isUserStopped(userId);
1848 pw.println(stopped);
1849 return 0;
1850 }
1851
1852 int runGetStartedUserState(PrintWriter pw) throws RemoteException {
1853 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1854 "runGetStartedUserState()");
1855 final int userId = Integer.parseInt(getNextArgRequired());
1856 try {
1857 pw.println(mInternal.getStartedUserState(userId));
1858 } catch (NullPointerException e) {
1859 pw.println("User is not started: " + userId);
1860 }
Dianne Hackborn2e441072015-10-28 18:00:57 -07001861 return 0;
1862 }
1863
1864 int runTrackAssociations(PrintWriter pw) {
1865 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Makoto Onukid5e74ed2019-01-31 15:50:18 -08001866 "runTrackAssociations()");
Dianne Hackborn2e441072015-10-28 18:00:57 -07001867 synchronized (mInternal) {
1868 if (!mInternal.mTrackingAssociations) {
1869 mInternal.mTrackingAssociations = true;
1870 pw.println("Association tracking started.");
1871 } else {
1872 pw.println("Association tracking already enabled.");
1873 }
1874 }
1875 return 0;
1876 }
1877
1878 int runUntrackAssociations(PrintWriter pw) {
1879 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Makoto Onukid5e74ed2019-01-31 15:50:18 -08001880 "runUntrackAssociations()");
Dianne Hackborn2e441072015-10-28 18:00:57 -07001881 synchronized (mInternal) {
1882 if (mInternal.mTrackingAssociations) {
1883 mInternal.mTrackingAssociations = false;
1884 mInternal.mAssociations.clear();
1885 pw.println("Association tracking stopped.");
1886 } else {
1887 pw.println("Association tracking not running.");
1888 }
1889 }
1890 return 0;
1891 }
1892
Felipe Leme2f1b2272016-03-25 16:15:02 -07001893 int getUidState(PrintWriter pw) throws RemoteException {
1894 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1895 "getUidState()");
1896 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
1897 pw.print(state);
1898 pw.print(" (");
1899 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
1900 pw.println(")");
1901 return 0;
1902 }
1903
Dianne Hackborn331084d2016-10-07 17:57:00 -07001904 private List<Configuration> getRecentConfigurations(int days) {
1905 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1906 Context.USAGE_STATS_SERVICE));
1907 final long now = System.currentTimeMillis();
1908 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
Sudheer Shanka28537b62016-09-07 11:12:31 -07001909 try {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001910 @SuppressWarnings("unchecked")
1911 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
1912 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
1913 if (configStatsSlice == null) {
1914 return Collections.emptyList();
1915 }
1916
1917 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
1918 final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
1919 final int configStatsListSize = configStatsList.size();
1920 for (int i = 0; i < configStatsListSize; i++) {
1921 final ConfigurationStats stats = configStatsList.get(i);
1922 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
1923 if (indexOfKey < 0) {
1924 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
1925 } else {
1926 recentConfigs.setValueAt(indexOfKey,
1927 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
1928 }
1929 }
1930
1931 final Comparator<Configuration> comparator = new Comparator<Configuration>() {
1932 @Override
1933 public int compare(Configuration a, Configuration b) {
1934 return recentConfigs.get(b).compareTo(recentConfigs.get(a));
1935 }
1936 };
1937
1938 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
1939 configs.addAll(recentConfigs.keySet());
1940 Collections.sort(configs, comparator);
1941 return configs;
1942
1943 } catch (RemoteException e) {
1944 return Collections.emptyList();
Sudheer Shanka28537b62016-09-07 11:12:31 -07001945 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001946 }
1947
Dianne Hackborn337e01a2018-02-27 17:16:37 -08001948 /**
1949 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
1950 * and EGLSurface and querying extensions.
1951 *
1952 * @param egl An EGL API object
1953 * @param display An EGLDisplay to create a context and surface with
1954 * @param config The EGLConfig to get the extensions for
1955 * @param surfaceSize eglCreatePbufferSurface generic parameters
1956 * @param contextAttribs eglCreateContext generic parameters
1957 * @param glExtensions A Set<String> to add GL extensions to
1958 */
1959 private static void addExtensionsForConfig(
1960 EGL10 egl,
1961 EGLDisplay display,
1962 EGLConfig config,
1963 int[] surfaceSize,
1964 int[] contextAttribs,
1965 Set<String> glExtensions) {
1966 // Create a context.
1967 EGLContext context =
1968 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
1969 // No-op if we can't create a context.
1970 if (context == EGL10.EGL_NO_CONTEXT) {
1971 return;
1972 }
1973
1974 // Create a surface.
1975 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
1976 if (surface == EGL10.EGL_NO_SURFACE) {
1977 egl.eglDestroyContext(display, context);
1978 return;
1979 }
1980
1981 // Update the current surface and context.
1982 egl.eglMakeCurrent(display, surface, surface, context);
1983
1984 // Get the list of extensions.
1985 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
1986 if (!TextUtils.isEmpty(extensionList)) {
1987 // The list of extensions comes from the driver separated by spaces.
1988 // Split them apart and add them into a Set for deduping purposes.
1989 for (String extension : extensionList.split(" ")) {
1990 glExtensions.add(extension);
1991 }
1992 }
1993
1994 // Tear down the context and surface for this config.
1995 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
1996 egl.eglDestroySurface(display, surface);
1997 egl.eglDestroyContext(display, context);
1998 }
1999
2000
2001 Set<String> getGlExtensionsFromDriver() {
2002 Set<String> glExtensions = new HashSet<>();
2003
2004 // Get the EGL implementation.
2005 EGL10 egl = (EGL10) EGLContext.getEGL();
2006 if (egl == null) {
2007 getErrPrintWriter().println("Warning: couldn't get EGL");
2008 return glExtensions;
2009 }
2010
2011 // Get the default display and initialize it.
2012 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
2013 int[] version = new int[2];
2014 egl.eglInitialize(display, version);
2015
2016 // Call getConfigs() in order to find out how many there are.
2017 int[] numConfigs = new int[1];
2018 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
2019 getErrPrintWriter().println("Warning: couldn't get EGL config count");
2020 return glExtensions;
2021 }
2022
2023 // Allocate space for all configs and ask again.
2024 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
2025 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
2026 getErrPrintWriter().println("Warning: couldn't get EGL configs");
2027 return glExtensions;
2028 }
2029
2030 // Allocate surface size parameters outside of the main loop to cut down
2031 // on GC thrashing. 1x1 is enough since we are only using it to get at
2032 // the list of extensions.
2033 int[] surfaceSize =
2034 new int[] {
2035 EGL10.EGL_WIDTH, 1,
2036 EGL10.EGL_HEIGHT, 1,
2037 EGL10.EGL_NONE
2038 };
2039
2040 // For when we need to create a GLES2.0 context.
2041 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
2042 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
2043
2044 // For getting return values from eglGetConfigAttrib
2045 int[] attrib = new int[1];
2046
2047 for (int i = 0; i < numConfigs[0]; i++) {
2048 // Get caveat for this config in order to skip slow (i.e. software) configs.
2049 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
2050 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
2051 continue;
2052 }
2053
2054 // If the config does not support pbuffers we cannot do an eglMakeCurrent
2055 // on it in addExtensionsForConfig(), so skip it here. Attempting to make
2056 // it current with a pbuffer will result in an EGL_BAD_MATCH error
2057 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
2058 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
2059 continue;
2060 }
2061
2062 final int EGL_OPENGL_ES_BIT = 0x0001;
2063 final int EGL_OPENGL_ES2_BIT = 0x0004;
2064 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
2065 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
2066 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
2067 }
2068 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
2069 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
2070 }
2071 }
2072
2073 // Release all EGL resources.
2074 egl.eglTerminate(display);
2075
2076 return glExtensions;
2077 }
2078
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002079 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
Jeff Change9467b22018-09-28 11:40:38 +08002080 PrintWriter pw, Configuration config, DisplayMetrics displayMetrics) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002081 long token = -1;
2082 if (protoOutputStream != null) {
2083 token = protoOutputStream.start(fieldId);
Jeff Change9467b22018-09-28 11:40:38 +08002084 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX,
2085 displayMetrics.widthPixels);
2086 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX,
2087 displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002088 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI,
2089 DisplayMetrics.DENSITY_DEVICE_STABLE);
2090 }
2091 if (pw != null) {
Jeff Change9467b22018-09-28 11:40:38 +08002092 pw.print("stable-width-px: "); pw.println(displayMetrics.widthPixels);
2093 pw.print("stable-height-px: "); pw.println(displayMetrics.heightPixels);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002094 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE);
2095 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002096
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002097 MemInfoReader memreader = new MemInfoReader();
2098 memreader.readMemInfo();
2099 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class);
2100 if (protoOutputStream != null) {
2101 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize());
2102 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM,
2103 ActivityManager.isLowRamDeviceStatic());
2104 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES,
2105 Runtime.getRuntime().availableProcessors());
2106 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK,
2107 kgm.isDeviceSecure());
2108 }
2109 if (pw != null) {
2110 pw.print("total-ram: "); pw.println(memreader.getTotalSize());
2111 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic());
2112 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors());
2113 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
2114 }
2115
Yunfan Chen75157d72018-07-27 14:47:21 +09002116 ConfigurationInfo configInfo = null;
2117 try {
2118 configInfo = mTaskInterface.getDeviceConfigurationInfo();
2119 } catch (RemoteException e) {
2120 throw e.rethrowFromSystemServer();
2121 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002122 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
2123 if (protoOutputStream != null) {
2124 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
2125 configInfo.reqGlEsVersion);
2126 }
2127 if (pw != null) {
2128 pw.print("opengl-version: 0x");
2129 pw.println(Integer.toHexString(configInfo.reqGlEsVersion));
2130 }
2131 }
2132
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002133 Set<String> glExtensionsSet = getGlExtensionsFromDriver();
2134 String[] glExtensions = new String[glExtensionsSet.size()];
2135 glExtensions = glExtensionsSet.toArray(glExtensions);
2136 Arrays.sort(glExtensions);
2137 for (int i = 0; i < glExtensions.length; i++) {
2138 if (protoOutputStream != null) {
2139 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
2140 glExtensions[i]);
2141 }
2142 if (pw != null) {
2143 pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
2144 }
2145
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002146 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002147
2148 PackageManager pm = mInternal.mContext.getPackageManager();
2149 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002150 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002151 for (int i = 0; i < slibs.size(); i++) {
2152 if (protoOutputStream != null) {
2153 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
2154 slibs.get(i).getName());
2155 }
2156 if (pw != null) {
2157 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName());
2158 }
2159 }
2160
2161 FeatureInfo[] features = pm.getSystemAvailableFeatures();
weijuncheng12030002018-10-30 14:07:53 +08002162 Arrays.sort(features, (o1, o2) -> {
2163 if (o1.name == o2.name) return 0;
2164 if (o1.name == null) return -1;
2165 if (o2.name == null) return 1;
2166 return o1.name.compareTo(o2.name);
2167 });
2168
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002169 for (int i = 0; i < features.length; i++) {
2170 if (features[i].name != null) {
2171 if (protoOutputStream != null) {
2172 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name);
2173 }
2174 if (pw != null) {
2175 pw.print("features: "); pw.println(features[i].name);
2176 }
2177 }
2178 }
2179
2180 if (protoOutputStream != null) {
2181 protoOutputStream.end(token);
2182 }
2183 }
2184
2185 int runGetConfig(PrintWriter pw) throws RemoteException {
2186 int days = -1;
Jeff Change9467b22018-09-28 11:40:38 +08002187 int displayId = Display.DEFAULT_DISPLAY;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002188 boolean asProto = false;
2189 boolean inclDevice = false;
2190
2191 String opt;
Jeff Change9467b22018-09-28 11:40:38 +08002192 while ((opt = getNextOption()) != null) {
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002193 if (opt.equals("--days")) {
2194 days = Integer.parseInt(getNextArgRequired());
2195 if (days <= 0) {
2196 throw new IllegalArgumentException("--days must be a positive integer");
2197 }
2198 } else if (opt.equals("--proto")) {
2199 asProto = true;
2200 } else if (opt.equals("--device")) {
2201 inclDevice = true;
Jeff Change9467b22018-09-28 11:40:38 +08002202 } else if (opt.equals("--display")) {
2203 displayId = Integer.parseInt(getNextArgRequired());
2204 if (displayId < 0) {
2205 throw new IllegalArgumentException("--display must be a non-negative integer");
2206 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002207 } else {
2208 getErrPrintWriter().println("Error: Unknown option: " + opt);
2209 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -07002210 }
2211 }
2212
2213 Configuration config = mInterface.getConfiguration();
2214 if (config == null) {
2215 getErrPrintWriter().println("Activity manager has no configuration");
2216 return -1;
2217 }
2218
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002219 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class);
Jeff Change9467b22018-09-28 11:40:38 +08002220 Display display = dm.getDisplay(displayId);
2221
2222 if (display == null) {
2223 getErrPrintWriter().println("Error: Display does not exist: " + displayId);
2224 return -1;
2225 }
2226
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002227 DisplayMetrics metrics = new DisplayMetrics();
2228 display.getMetrics(metrics);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002229
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002230 if (asProto) {
2231 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor());
2232 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics);
2233 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002234 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002235 }
2236 proto.flush();
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002237 } else {
2238 pw.println("config: " + Configuration.resourceQualifierString(config, metrics));
2239 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
2240 if (inclDevice) {
Jeff Change9467b22018-09-28 11:40:38 +08002241 writeDeviceConfig(null, -1, pw, config, metrics);
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002242 }
2243
2244 if (days >= 0) {
2245 final List<Configuration> recentConfigs = getRecentConfigurations(days);
2246 final int recentConfigSize = recentConfigs.size();
2247 if (recentConfigSize > 0) {
2248 pw.println("recentConfigs:");
2249 for (int i = 0; i < recentConfigSize; i++) {
2250 pw.println(" config: " + Configuration.resourceQualifierString(
2251 recentConfigs.get(i)));
2252 }
2253 }
2254 }
2255
Dianne Hackborn331084d2016-10-07 17:57:00 -07002256 }
2257 return 0;
2258 }
2259
2260 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
2261 boolean suppress = Boolean.valueOf(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002262 mTaskInterface.suppressResizeConfigChanges(suppress);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002263 return 0;
2264 }
2265
2266 int runSetInactive(PrintWriter pw) throws RemoteException {
2267 int userId = UserHandle.USER_CURRENT;
2268
2269 String opt;
2270 while ((opt=getNextOption()) != null) {
2271 if (opt.equals("--user")) {
2272 userId = UserHandle.parseUserArg(getNextArgRequired());
2273 } else {
2274 getErrPrintWriter().println("Error: Unknown option: " + opt);
2275 return -1;
2276 }
2277 }
2278 String packageName = getNextArgRequired();
2279 String value = getNextArgRequired();
2280
2281 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2282 Context.USAGE_STATS_SERVICE));
2283 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId);
2284 return 0;
2285 }
2286
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002287 private int bucketNameToBucketValue(String name) {
2288 String lower = name.toLowerCase();
2289 if (lower.startsWith("ac")) {
2290 return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
2291 } else if (lower.startsWith("wo")) {
2292 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
2293 } else if (lower.startsWith("fr")) {
2294 return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
2295 } else if (lower.startsWith("ra")) {
2296 return UsageStatsManager.STANDBY_BUCKET_RARE;
2297 } else if (lower.startsWith("ne")) {
2298 return UsageStatsManager.STANDBY_BUCKET_NEVER;
2299 } else {
2300 try {
2301 int bucket = Integer.parseInt(lower);
2302 return bucket;
2303 } catch (NumberFormatException nfe) {
2304 getErrPrintWriter().println("Error: Unknown bucket: " + name);
2305 }
2306 }
2307 return -1;
2308 }
2309
Amith Yamasani17fffee2017-09-29 13:17:43 -07002310 int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
2311 int userId = UserHandle.USER_CURRENT;
2312
2313 String opt;
2314 while ((opt=getNextOption()) != null) {
2315 if (opt.equals("--user")) {
2316 userId = UserHandle.parseUserArg(getNextArgRequired());
2317 } else {
2318 getErrPrintWriter().println("Error: Unknown option: " + opt);
2319 return -1;
2320 }
2321 }
2322 String packageName = getNextArgRequired();
2323 String value = getNextArgRequired();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002324 int bucket = bucketNameToBucketValue(value);
2325 if (bucket < 0) return -1;
Amith Yamasanie8789312017-12-10 14:34:26 -08002326 boolean multiple = peekNextArg() != null;
2327
Amith Yamasani17fffee2017-09-29 13:17:43 -07002328
2329 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2330 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002331 if (!multiple) {
2332 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
2333 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002334 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
2335 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002336 while ((packageName = getNextArg()) != null) {
2337 value = getNextArgRequired();
2338 bucket = bucketNameToBucketValue(value);
2339 if (bucket < 0) continue;
Suprabh Shukla868bde22018-02-20 20:59:52 -08002340 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002341 }
Suprabh Shukla868bde22018-02-20 20:59:52 -08002342 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
2343 usm.setAppStandbyBuckets(slice, userId);
Amith Yamasanie8789312017-12-10 14:34:26 -08002344 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002345 return 0;
2346 }
2347
2348 int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
2349 int userId = UserHandle.USER_CURRENT;
2350
2351 String opt;
2352 while ((opt=getNextOption()) != null) {
2353 if (opt.equals("--user")) {
2354 userId = UserHandle.parseUserArg(getNextArgRequired());
2355 } else {
2356 getErrPrintWriter().println("Error: Unknown option: " + opt);
2357 return -1;
2358 }
2359 }
Amith Yamasanie8789312017-12-10 14:34:26 -08002360 String packageName = getNextArg();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002361
2362 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2363 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002364 if (packageName != null) {
2365 int bucket = usm.getAppStandbyBucket(packageName, null, userId);
2366 pw.println(bucket);
2367 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002368 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -08002369 SHELL_PACKAGE_NAME, userId);
Suprabh Shukla868bde22018-02-20 20:59:52 -08002370 for (AppStandbyInfo bucketInfo : buckets.getList()) {
2371 pw.print(bucketInfo.mPackageName); pw.print(": ");
2372 pw.println(bucketInfo.mStandbyBucket);
Amith Yamasanie8789312017-12-10 14:34:26 -08002373 }
2374 }
Amith Yamasani17fffee2017-09-29 13:17:43 -07002375 return 0;
2376 }
2377
Dianne Hackborn331084d2016-10-07 17:57:00 -07002378 int runGetInactive(PrintWriter pw) throws RemoteException {
2379 int userId = UserHandle.USER_CURRENT;
2380
2381 String opt;
2382 while ((opt=getNextOption()) != null) {
2383 if (opt.equals("--user")) {
2384 userId = UserHandle.parseUserArg(getNextArgRequired());
2385 } else {
2386 getErrPrintWriter().println("Error: Unknown option: " + opt);
2387 return -1;
2388 }
2389 }
2390 String packageName = getNextArgRequired();
2391
2392 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2393 Context.USAGE_STATS_SERVICE));
2394 boolean isIdle = usm.isAppInactive(packageName, userId);
2395 pw.println("Idle=" + isIdle);
2396 return 0;
2397 }
2398
2399 int runSendTrimMemory(PrintWriter pw) throws RemoteException {
2400 int userId = UserHandle.USER_CURRENT;
2401 String opt;
2402 while ((opt = getNextOption()) != null) {
2403 if (opt.equals("--user")) {
2404 userId = UserHandle.parseUserArg(getNextArgRequired());
2405 if (userId == UserHandle.USER_ALL) {
2406 getErrPrintWriter().println("Error: Can't use user 'all'");
2407 return -1;
2408 }
2409 } else {
2410 getErrPrintWriter().println("Error: Unknown option: " + opt);
2411 return -1;
2412 }
2413 }
2414
2415 String proc = getNextArgRequired();
2416 String levelArg = getNextArgRequired();
2417 int level;
2418 switch (levelArg) {
2419 case "HIDDEN":
2420 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
2421 break;
2422 case "RUNNING_MODERATE":
2423 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
2424 break;
2425 case "BACKGROUND":
2426 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
2427 break;
2428 case "RUNNING_LOW":
2429 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
2430 break;
2431 case "MODERATE":
2432 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
2433 break;
2434 case "RUNNING_CRITICAL":
2435 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
2436 break;
2437 case "COMPLETE":
2438 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
2439 break;
2440 default:
Dianne Hackborne51505a2017-08-07 17:13:52 -07002441 try {
2442 level = Integer.parseInt(levelArg);
2443 } catch (NumberFormatException e) {
2444 getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
2445 return -1;
2446 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002447 }
2448 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
2449 getErrPrintWriter().println("Unknown error: failed to set trim level");
2450 return -1;
2451 }
2452 return 0;
2453 }
2454
Andrii Kulian839def92016-11-02 10:58:58 -07002455 int runDisplay(PrintWriter pw) throws RemoteException {
2456 String op = getNextArgRequired();
2457 switch (op) {
2458 case "move-stack":
2459 return runDisplayMoveStack(pw);
2460 default:
2461 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2462 return -1;
2463 }
2464 }
2465
Dianne Hackborn331084d2016-10-07 17:57:00 -07002466 int runStack(PrintWriter pw) throws RemoteException {
2467 String op = getNextArgRequired();
2468 switch (op) {
Andrii Kulian839def92016-11-02 10:58:58 -07002469 case "move-task":
Dianne Hackborn331084d2016-10-07 17:57:00 -07002470 return runStackMoveTask(pw);
2471 case "resize":
2472 return runStackResize(pw);
2473 case "resize-animated":
2474 return runStackResizeAnimated(pw);
2475 case "resize-docked-stack":
2476 return runStackResizeDocked(pw);
2477 case "positiontask":
2478 return runStackPositionTask(pw);
2479 case "list":
2480 return runStackList(pw);
2481 case "info":
2482 return runStackInfo(pw);
2483 case "move-top-activity-to-pinned-stack":
2484 return runMoveTopActivityToPinnedStack(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002485 case "remove":
2486 return runStackRemove(pw);
2487 default:
2488 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2489 return -1;
2490 }
2491 }
2492
2493
2494 private Rect getBounds() {
2495 String leftStr = getNextArgRequired();
2496 int left = Integer.parseInt(leftStr);
2497 String topStr = getNextArgRequired();
2498 int top = Integer.parseInt(topStr);
2499 String rightStr = getNextArgRequired();
2500 int right = Integer.parseInt(rightStr);
2501 String bottomStr = getNextArgRequired();
2502 int bottom = Integer.parseInt(bottomStr);
2503 if (left < 0) {
2504 getErrPrintWriter().println("Error: bad left arg: " + leftStr);
2505 return null;
2506 }
2507 if (top < 0) {
2508 getErrPrintWriter().println("Error: bad top arg: " + topStr);
2509 return null;
2510 }
2511 if (right <= 0) {
2512 getErrPrintWriter().println("Error: bad right arg: " + rightStr);
2513 return null;
2514 }
2515 if (bottom <= 0) {
2516 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr);
2517 return null;
2518 }
2519 return new Rect(left, top, right, bottom);
2520 }
2521
Andrii Kulian839def92016-11-02 10:58:58 -07002522 int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
2523 String stackIdStr = getNextArgRequired();
2524 int stackId = Integer.parseInt(stackIdStr);
2525 String displayIdStr = getNextArgRequired();
2526 int displayId = Integer.parseInt(displayIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002527 mTaskInterface.moveStackToDisplay(stackId, displayId);
Andrii Kulian839def92016-11-02 10:58:58 -07002528 return 0;
2529 }
2530
Dianne Hackborn331084d2016-10-07 17:57:00 -07002531 int runStackMoveTask(PrintWriter pw) throws RemoteException {
2532 String taskIdStr = getNextArgRequired();
2533 int taskId = Integer.parseInt(taskIdStr);
2534 String stackIdStr = getNextArgRequired();
2535 int stackId = Integer.parseInt(stackIdStr);
2536 String toTopStr = getNextArgRequired();
2537 final boolean toTop;
2538 if ("true".equals(toTopStr)) {
2539 toTop = true;
2540 } else if ("false".equals(toTopStr)) {
2541 toTop = false;
2542 } else {
2543 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr);
2544 return -1;
2545 }
2546
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002547 mTaskInterface.moveTaskToStack(taskId, stackId, toTop);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002548 return 0;
2549 }
2550
2551 int runStackResize(PrintWriter pw) throws RemoteException {
2552 String stackIdStr = getNextArgRequired();
2553 int stackId = Integer.parseInt(stackIdStr);
2554 final Rect bounds = getBounds();
2555 if (bounds == null) {
2556 getErrPrintWriter().println("Error: invalid input bounds");
2557 return -1;
2558 }
2559 return resizeStack(stackId, bounds, 0);
2560 }
2561
2562 int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
2563 String stackIdStr = getNextArgRequired();
2564 int stackId = Integer.parseInt(stackIdStr);
2565 final Rect bounds;
2566 if ("null".equals(peekNextArg())) {
2567 bounds = null;
2568 } else {
2569 bounds = getBounds();
2570 if (bounds == null) {
2571 getErrPrintWriter().println("Error: invalid input bounds");
2572 return -1;
2573 }
2574 }
2575 return resizeStackUnchecked(stackId, bounds, 0, true);
2576 }
2577
2578 int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate)
2579 throws RemoteException {
2580 try {
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002581 mTaskInterface.resizeStack(stackId, bounds, false, false, animate, -1);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002582 Thread.sleep(delayMs);
2583 } catch (InterruptedException e) {
2584 }
2585 return 0;
2586 }
2587
2588 int runStackResizeDocked(PrintWriter pw) throws RemoteException {
2589 final Rect bounds = getBounds();
2590 final Rect taskBounds = getBounds();
2591 if (bounds == null || taskBounds == null) {
2592 getErrPrintWriter().println("Error: invalid input bounds");
2593 return -1;
2594 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002595 mTaskInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002596 return 0;
2597 }
2598
2599 int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException {
2600 if (bounds == null) {
2601 getErrPrintWriter().println("Error: invalid input bounds");
2602 return -1;
2603 }
2604 return resizeStackUnchecked(stackId, bounds, delayMs, false);
2605 }
2606
2607 int runStackPositionTask(PrintWriter pw) throws RemoteException {
2608 String taskIdStr = getNextArgRequired();
2609 int taskId = Integer.parseInt(taskIdStr);
2610 String stackIdStr = getNextArgRequired();
2611 int stackId = Integer.parseInt(stackIdStr);
2612 String positionStr = getNextArgRequired();
2613 int position = Integer.parseInt(positionStr);
2614
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002615 mTaskInterface.positionTaskInStack(taskId, stackId, position);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002616 return 0;
2617 }
2618
2619 int runStackList(PrintWriter pw) throws RemoteException {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002620 List<ActivityManager.StackInfo> stacks = mTaskInterface.getAllStackInfos();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002621 for (ActivityManager.StackInfo info : stacks) {
2622 pw.println(info);
2623 }
2624 return 0;
2625 }
2626
2627 int runStackInfo(PrintWriter pw) throws RemoteException {
Wale Ogunwale68278562017-09-23 17:13:55 -07002628 int windowingMode = Integer.parseInt(getNextArgRequired());
2629 int activityType = Integer.parseInt(getNextArgRequired());
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002630 ActivityManager.StackInfo info = mTaskInterface.getStackInfo(windowingMode, activityType);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002631 pw.println(info);
2632 return 0;
2633 }
2634
2635 int runStackRemove(PrintWriter pw) throws RemoteException {
2636 String stackIdStr = getNextArgRequired();
2637 int stackId = Integer.parseInt(stackIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002638 mTaskInterface.removeStack(stackId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002639 return 0;
2640 }
2641
2642 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException {
2643 int stackId = Integer.parseInt(getNextArgRequired());
2644 final Rect bounds = getBounds();
2645 if (bounds == null) {
2646 getErrPrintWriter().println("Error: invalid input bounds");
2647 return -1;
2648 }
2649
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002650 if (!mTaskInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -07002651 getErrPrintWriter().println("Didn't move top activity to pinned stack.");
2652 return -1;
2653 }
2654 return 0;
2655 }
2656
Dianne Hackborn331084d2016-10-07 17:57:00 -07002657 void setBoundsSide(Rect bounds, String side, int value) {
2658 switch (side) {
2659 case "l":
2660 bounds.left = value;
2661 break;
2662 case "r":
2663 bounds.right = value;
2664 break;
2665 case "t":
2666 bounds.top = value;
2667 break;
2668 case "b":
2669 bounds.bottom = value;
2670 break;
2671 default:
2672 getErrPrintWriter().println("Unknown set side: " + side);
2673 break;
2674 }
2675 }
2676
2677 int runTask(PrintWriter pw) throws RemoteException {
2678 String op = getNextArgRequired();
2679 if (op.equals("lock")) {
2680 return runTaskLock(pw);
2681 } else if (op.equals("resizeable")) {
2682 return runTaskResizeable(pw);
2683 } else if (op.equals("resize")) {
2684 return runTaskResize(pw);
David Stevensee9e2772017-02-09 16:30:27 -08002685 } else if (op.equals("focus")) {
2686 return runTaskFocus(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002687 } else {
2688 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2689 return -1;
2690 }
2691 }
2692
2693 int runTaskLock(PrintWriter pw) throws RemoteException {
2694 String taskIdStr = getNextArgRequired();
2695 if (taskIdStr.equals("stop")) {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002696 mTaskInterface.stopSystemLockTaskMode();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002697 } else {
2698 int taskId = Integer.parseInt(taskIdStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002699 mTaskInterface.startSystemLockTaskMode(taskId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002700 }
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002701 pw.println("Activity manager is " + (mTaskInterface.isInLockTaskMode() ? "" : "not ") +
Dianne Hackborn331084d2016-10-07 17:57:00 -07002702 "in lockTaskMode");
2703 return 0;
2704 }
2705
2706 int runTaskResizeable(PrintWriter pw) throws RemoteException {
2707 final String taskIdStr = getNextArgRequired();
2708 final int taskId = Integer.parseInt(taskIdStr);
2709 final String resizeableStr = getNextArgRequired();
2710 final int resizeableMode = Integer.parseInt(resizeableStr);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002711 mTaskInterface.setTaskResizeable(taskId, resizeableMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002712 return 0;
2713 }
2714
2715 int runTaskResize(PrintWriter pw) throws RemoteException {
2716 final String taskIdStr = getNextArgRequired();
2717 final int taskId = Integer.parseInt(taskIdStr);
2718 final Rect bounds = getBounds();
2719 if (bounds == null) {
2720 getErrPrintWriter().println("Error: invalid input bounds");
2721 return -1;
2722 }
2723 taskResize(taskId, bounds, 0, false);
2724 return 0;
2725 }
2726
2727 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
2728 throws RemoteException {
2729 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002730 mTaskInterface.resizeTask(taskId, bounds, resizeMode);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002731 try {
2732 Thread.sleep(delay_ms);
2733 } catch (InterruptedException e) {
2734 }
2735 }
2736
Dianne Hackborn331084d2016-10-07 17:57:00 -07002737 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
2738 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
2739 throws RemoteException {
2740 int maxMove;
2741 if (movingForward) {
2742 while (maxToTravel > 0
2743 && ((horizontal && taskRect.right < stackRect.right)
2744 ||(!horizontal && taskRect.bottom < stackRect.bottom))) {
2745 if (horizontal) {
2746 maxMove = Math.min(stepSize, stackRect.right - taskRect.right);
2747 maxToTravel -= maxMove;
2748 taskRect.right += maxMove;
2749 taskRect.left += maxMove;
2750 } else {
2751 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom);
2752 maxToTravel -= maxMove;
2753 taskRect.top += maxMove;
2754 taskRect.bottom += maxMove;
2755 }
2756 taskResize(taskId, taskRect, delay_ms, false);
2757 }
2758 } else {
2759 while (maxToTravel < 0
2760 && ((horizontal && taskRect.left > stackRect.left)
2761 ||(!horizontal && taskRect.top > stackRect.top))) {
2762 if (horizontal) {
2763 maxMove = Math.min(stepSize, taskRect.left - stackRect.left);
2764 maxToTravel -= maxMove;
2765 taskRect.right -= maxMove;
2766 taskRect.left -= maxMove;
2767 } else {
2768 maxMove = Math.min(stepSize, taskRect.top - stackRect.top);
2769 maxToTravel -= maxMove;
2770 taskRect.top -= maxMove;
2771 taskRect.bottom -= maxMove;
2772 }
2773 taskResize(taskId, taskRect, delay_ms, false);
2774 }
2775 }
2776 // Return the remaining distance we didn't travel because we reached the target location.
2777 return maxToTravel;
2778 }
2779
2780 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) {
2781 int stepSize = 0;
2782 if (greaterThanTarget && target < current) {
2783 current -= inStepSize;
2784 stepSize = inStepSize;
2785 if (target > current) {
2786 stepSize -= (target - current);
2787 }
2788 }
2789 if (!greaterThanTarget && target > current) {
2790 current += inStepSize;
2791 stepSize = inStepSize;
2792 if (target < current) {
2793 stepSize += (current - target);
2794 }
2795 }
2796 return stepSize;
2797 }
2798
David Stevensee9e2772017-02-09 16:30:27 -08002799 int runTaskFocus(PrintWriter pw) throws RemoteException {
2800 final int taskId = Integer.parseInt(getNextArgRequired());
2801 pw.println("Setting focus to task " + taskId);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002802 mTaskInterface.setFocusedTask(taskId);
David Stevensee9e2772017-02-09 16:30:27 -08002803 return 0;
2804 }
2805
Dianne Hackborn331084d2016-10-07 17:57:00 -07002806 int runWrite(PrintWriter pw) {
2807 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2808 "registerUidObserver()");
Wale Ogunwaled7889f52018-10-25 11:03:20 -07002809 mInternal.mAtmInternal.flushRecentTasks();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002810 pw.println("All tasks persisted.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002811 return 0;
2812 }
2813
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002814 int runAttachAgent(PrintWriter pw) {
2815 // TODO: revisit the permissions required for attaching agents
2816 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2817 "attach-agent");
2818 String process = getNextArgRequired();
2819 String agent = getNextArgRequired();
2820 String opt;
2821 if ((opt = getNextArg()) != null) {
2822 pw.println("Error: Unknown option: " + opt);
2823 return -1;
2824 }
2825 mInternal.attachAgent(process, agent);
2826 return 0;
2827 }
2828
Michael Kwan94438b72016-11-03 15:30:34 -07002829 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
Matthew Ng626e0cc2016-12-07 17:25:53 -08002830 final Resources res = getResources(pw);
2831 if (res == null) {
2832 return -1;
2833 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002834 pw.println(ActivityTaskManager.supportsMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002835 return 0;
2836 }
2837
2838 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException {
2839 final Resources res = getResources(pw);
2840 if (res == null) {
2841 return -1;
2842 }
Wale Ogunwale65ebd952018-04-25 15:41:44 -07002843 pw.println(ActivityTaskManager.supportsSplitScreenMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002844 return 0;
2845 }
2846
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002847 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
2848 int userid = UserHandle.parseUserArg(getNextArgRequired());
2849 ArrayList<String> packages = new ArrayList<>();
2850 packages.add(getNextArgRequired());
2851 String packageName;
2852 while ((packageName = getNextArg()) != null) {
2853 packages.add(packageName);
2854 }
2855 mInternal.scheduleApplicationInfoChanged(packages, userid);
2856 pw.println("Packages updated with most recent ApplicationInfos.");
2857 return 0;
2858 }
2859
Arthur Hsuf3f3a602017-02-21 14:01:53 -08002860 int runNoHomeScreen(PrintWriter pw) throws RemoteException {
2861 final Resources res = getResources(pw);
2862 if (res == null) {
2863 return -1;
2864 }
2865 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen));
2866 return 0;
2867 }
2868
Jeff Sharkeyfd658132017-05-03 11:38:01 -06002869 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
2870 mInternal.waitForBroadcastIdle(pw);
2871 return 0;
2872 }
2873
atrost8851c3c2019-08-29 16:17:52 +01002874 private int runCompat(PrintWriter pw) throws RemoteException {
atrostf69bbe12019-11-06 16:00:38 +00002875 final PlatformCompat platformCompat = (PlatformCompat)
2876 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002877 String toggleValue = getNextArgRequired();
2878 long changeId;
2879 String changeIdString = getNextArgRequired();
2880 try {
2881 changeId = Long.parseLong(changeIdString);
2882 } catch (NumberFormatException e) {
atrostf69bbe12019-11-06 16:00:38 +00002883 changeId = platformCompat.lookupChangeId(changeIdString);
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002884 }
2885 if (changeId == -1) {
2886 pw.println("Unknown or invalid change: '" + changeIdString + "'.");
atrostf69bbe12019-11-06 16:00:38 +00002887 return -1;
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002888 }
2889 String packageName = getNextArgRequired();
atrostf69bbe12019-11-06 16:00:38 +00002890 if (!platformCompat.isKnownChangeId(changeId)) {
2891 pw.println("Warning! Change " + changeId + " is not known yet. Enabling/disabling it"
2892 + " could have no effect.");
2893 }
2894 ArraySet<Long> enabled = new ArraySet<>();
2895 ArraySet<Long> disabled = new ArraySet<>();
atrost8851c3c2019-08-29 16:17:52 +01002896 switch (toggleValue) {
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002897 case "enable":
atrostf69bbe12019-11-06 16:00:38 +00002898 enabled.add(changeId);
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002899 pw.println("Enabled change " + changeId + " for " + packageName + ".");
atrostf69bbe12019-11-06 16:00:38 +00002900 CompatibilityChangeConfig overrides =
2901 new CompatibilityChangeConfig(
2902 new Compatibility.ChangeConfig(enabled, disabled));
2903 platformCompat.setOverrides(overrides, packageName);
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002904 return 0;
2905 case "disable":
atrostf69bbe12019-11-06 16:00:38 +00002906 disabled.add(changeId);
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002907 pw.println("Disabled change " + changeId + " for " + packageName + ".");
atrostf69bbe12019-11-06 16:00:38 +00002908 overrides =
2909 new CompatibilityChangeConfig(
2910 new Compatibility.ChangeConfig(enabled, disabled));
2911 platformCompat.setOverrides(overrides, packageName);
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002912 return 0;
2913 case "reset":
atrostf69bbe12019-11-06 16:00:38 +00002914 if (platformCompat.clearOverride(changeId, packageName)) {
Andrei Oneac014fb5c2019-06-28 18:42:22 +01002915 pw.println("Reset change " + changeId + " for " + packageName
2916 + " to default value.");
2917 } else {
2918 pw.println("No override exists for changeId " + changeId + ".");
2919 }
2920 return 0;
2921 default:
2922 pw.println("Invalid toggle value: '" + toggleValue + "'.");
2923 }
2924 return -1;
2925 }
2926
2927
Matthew Ng626e0cc2016-12-07 17:25:53 -08002928 private Resources getResources(PrintWriter pw) throws RemoteException {
Michael Kwan94438b72016-11-03 15:30:34 -07002929 // system resources does not contain all the device configuration, construct it manually.
2930 Configuration config = mInterface.getConfiguration();
2931 if (config == null) {
2932 pw.println("Error: Activity manager has no configuration");
Matthew Ng626e0cc2016-12-07 17:25:53 -08002933 return null;
Michael Kwan94438b72016-11-03 15:30:34 -07002934 }
2935
2936 final DisplayMetrics metrics = new DisplayMetrics();
2937 metrics.setToDefaults();
2938
Matthew Ng626e0cc2016-12-07 17:25:53 -08002939 return new Resources(AssetManager.getSystem(), metrics, config);
Michael Kwan94438b72016-11-03 15:30:34 -07002940 }
2941
Dianne Hackborn2e441072015-10-28 18:00:57 -07002942 @Override
2943 public void onHelp() {
2944 PrintWriter pw = getOutPrintWriter();
2945 dumpHelp(pw, mDumping);
2946 }
2947
2948 static void dumpHelp(PrintWriter pw, boolean dumping) {
2949 if (dumping) {
2950 pw.println("Activity manager dump options:");
2951 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
2952 pw.println(" WHAT may be one of:");
2953 pw.println(" a[ctivities]: activity stack state");
2954 pw.println(" r[recents]: recent activities state");
2955 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002956 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002957 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
2958 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
2959 pw.println(" o[om]: out of memory management");
2960 pw.println(" perm[issions]: URI permission grant state");
2961 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
2962 pw.println(" provider [COMP_SPEC]: provider client-side state");
2963 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborn769b2e72018-12-05 08:51:20 -08002964 pw.println(" allowed-associations: current package association restrictions");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002965 pw.println(" as[sociations]: tracked app associations");
Dianne Hackborna631d562018-11-20 15:58:15 -08002966 pw.println(" lmk: stats on low memory killer");
2967 pw.println(" lru: raw LRU process list");
2968 pw.println(" binder-proxies: stats on binder objects and IPCs");
Dianne Hackborn0ef403e2017-01-24 18:22:15 -08002969 pw.println(" settings: currently applied config settings");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002970 pw.println(" service [COMP_SPEC]: service client-side state");
2971 pw.println(" package [PACKAGE_NAME]: all state related to given package");
2972 pw.println(" all: dump all activities");
2973 pw.println(" top: dump the top activity");
2974 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
2975 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
2976 pw.println(" a partial substring in a component name, a");
2977 pw.println(" hex object identifier.");
2978 pw.println(" -a: include all available server state.");
2979 pw.println(" -c: include client state.");
2980 pw.println(" -p: limit output to given package.");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002981 pw.println(" --checkin: output checkin format, resetting data.");
2982 pw.println(" --C: output checkin format, not resetting data.");
Steven Timotius4346f0a2017-09-12 11:07:21 -07002983 pw.println(" --proto: output dump in protocol buffer format.");
Felipe Lemeb546ca72018-08-15 08:44:12 -07002984 pw.println(" --autofill: dump just the autofill-related state of an activity");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002985 } else {
2986 pw.println("Activity manager (activity) commands:");
2987 pw.println(" help");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002988 pw.println(" Print this help text.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002989 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002990 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002991 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002992 pw.println(" Start an Activity. Options are:");
2993 pw.println(" -D: enable debugging");
2994 pw.println(" -N: enable native debugging");
2995 pw.println(" -W: wait for launch to complete");
2996 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>");
2997 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2998 pw.println(" between samples (use with --start-profiler)");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002999 pw.println(" --streaming: stream the profiling output to the specified file");
3000 pw.println(" (use with --start-profiler)");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003001 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
Andreas Gampe83085bb2017-06-26 17:54:11 -07003002 pw.println(" --attach-agent <agent>: attach the given agent before binding");
Andreas Gampeab8a63b2018-01-05 13:55:15 -08003003 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003004 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
3005 pw.println(" the top activity will be finished.");
3006 pw.println(" -S: force stop the target app before starting the activity");
3007 pw.println(" --track-allocation: enable tracking of object allocations");
3008 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
3009 pw.println(" specified then run as the current user.");
Wale Ogunwale0568aed2017-09-08 13:29:37 -07003010 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into.");
3011 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
Louis Changf379f802018-07-13 09:41:28 +08003012 pw.println(" --display <DISPLAY_ID>: The display to launch the activity into.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003013 pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
3014 pw.println(" Start a Service. Options are:");
3015 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
3016 pw.println(" specified then run as the current user.");
Jaewan Kim329b35f2017-04-11 11:19:49 +09003017 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
3018 pw.println(" Start a foreground Service. Options are:");
3019 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
3020 pw.println(" specified then run as the current user.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003021 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
3022 pw.println(" Stop a Service. Options are:");
3023 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
3024 pw.println(" specified then run as the current user.");
3025 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>");
3026 pw.println(" Send a broadcast Intent. Options are:");
3027 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not");
3028 pw.println(" specified then send to all users.");
3029 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
Dianne Hackborn28824062016-10-18 13:19:20 -07003030 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
Artur Satayeve2ebc1b2019-10-31 12:07:55 +00003031 pw.println(" [--user <USER_ID> | current]");
3032 pw.println(" [--no-hidden-api-checks [--no-test-api-checks]]");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07003033 pw.println(" [--no-isolated-storage]");
Dianne Hackborn28824062016-10-18 13:19:20 -07003034 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
3035 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
3036 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
3037 pw.println(" is only one instrumentation. Options are:");
3038 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with");
3039 pw.println(" [-e perf true] to generate raw output for performance measurements.");
3040 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a");
3041 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]].");
3042 pw.println(" -p <FILE>: write profiling data to <FILE>");
Mike Mad2239822017-10-31 12:30:42 -07003043 pw.println(" -m: Write output as protobuf to stdout (machine readable)");
3044 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine");
3045 pw.println(" readable). If path is not specified, default directory and file name will");
3046 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto");
Dianne Hackborn28824062016-10-18 13:19:20 -07003047 pw.println(" -w: wait for instrumentation to finish before returning. Required for");
3048 pw.println(" test runners.");
3049 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
3050 pw.println(" current user if not specified.");
David Brazdild5d42172018-02-14 19:39:03 +00003051 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
Artur Satayeve2ebc1b2019-10-31 12:07:55 +00003052 pw.println(" --no-test-api-checks: disable restrictions to test APIs, if hidden");
3053 pw.println(" API checks are enabled.");
Sudheer Shanka8f99bff2018-10-21 16:19:53 -07003054 pw.println(" --no-isolated-storage: don't use isolated storage sandbox and ");
3055 pw.println(" mount full external storage");
Dianne Hackborn28824062016-10-18 13:19:20 -07003056 pw.println(" --no-window-animation: turn off window animations while running.");
3057 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
3058 pw.println(" This assumes that the process supports the selected ABI.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003059 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]");
3060 pw.println(" Trace IPC transactions.");
3061 pw.println(" start: start tracing IPC transactions.");
3062 pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
3063 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
Orion Hodson4e6a3142019-04-08 10:12:02 +01003064 pw.println(" profile start [--user <USER_ID> current]");
3065 pw.println(" [--sampling INTERVAL | --streaming] <PROCESS> <FILE>");
3066 pw.println(" Start profiler on a process. The given <PROCESS> argument");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003067 pw.println(" may be either a process name or pid. Options are:");
3068 pw.println(" --user <USER_ID> | current: When supplying a process name,");
Orion Hodson4e6a3142019-04-08 10:12:02 +01003069 pw.println(" specify user of process to profile; uses current user if not");
3070 pw.println(" specified.");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08003071 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
Orion Hodson4e6a3142019-04-08 10:12:02 +01003072 pw.println(" between samples.");
3073 pw.println(" --streaming: stream the profiling output to the specified file.");
3074 pw.println(" profile stop [--user <USER_ID> current] <PROCESS>");
3075 pw.println(" Stop profiler on a process. The given <PROCESS> argument");
3076 pw.println(" may be either a process name or pid. Options are:");
3077 pw.println(" --user <USER_ID> | current: When supplying a process name,");
3078 pw.println(" specify user of process to profile; uses current user if not");
3079 pw.println(" specified.");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07003080 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003081 pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
3082 pw.println(" be either a process name or pid. Options are:");
3083 pw.println(" -n: dump native heap instead of managed heap");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07003084 pw.println(" -g: force GC before dumping the heap");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003085 pw.println(" --user <USER_ID> | current: When supplying a process name,");
3086 pw.println(" specify user of process to dump; uses current user if not specified.");
3087 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>");
3088 pw.println(" Set application <PACKAGE> to debug. Options are:");
3089 pw.println(" -w: wait for debugger when application starts");
3090 pw.println(" --persistent: retain this value");
3091 pw.println(" clear-debug-app");
3092 pw.println(" Clear the previously set-debug-app.");
3093 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>");
3094 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or");
3095 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
3096 pw.println(" clear-watch-heap");
3097 pw.println(" Clear the previously set-watch-heap.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08003098 pw.println(" bug-report [--progress | --telephony]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003099 pw.println(" Request bug report generation; will launch a notification");
3100 pw.println(" when done to select where it should be delivered. Options are:");
3101 pw.println(" --progress: will launch a notification right away to show its progress.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08003102 pw.println(" --telephony: will dump only telephony sections.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003103 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003104 pw.println(" Completely stop the given application package.");
Christopher Tate8aa8fe12017-01-20 17:50:32 -08003105 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>");
3106 pw.println(" Induce a VM crash in the specified package or process");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003107 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
Makoto Onuki6569c362018-02-27 15:52:01 -08003108 pw.println(" Kill all background processes associated with the given application.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003109 pw.println(" kill-all");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003110 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn85e35642017-01-12 15:10:57 -08003111 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
3112 pw.println(" If the given application's uid is in the background and waiting to");
3113 pw.println(" become idle (not allowing background services), do that now.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003114 pw.println(" monitor [--gdb <port>]");
3115 pw.println(" Start monitoring for crashes or ANRs.");
3116 pw.println(" --gdb: start gdbserv on the given port at crash/ANR");
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07003117 pw.println(" watch-uids [--oom <uid>]");
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01003118 pw.println(" Start watching for and reporting uid state changes.");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003119 pw.println(" --oom: specify a uid for which to report detailed change messages.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003120 pw.println(" hang [--allow-restart]");
3121 pw.println(" Hang the system.");
3122 pw.println(" --allow-restart: allow watchdog to perform normal system restart");
3123 pw.println(" restart");
3124 pw.println(" Restart the user-space system.");
3125 pw.println(" idle-maintenance");
3126 pw.println(" Perform idle maintenance now.");
3127 pw.println(" screen-compat [on|off] <PACKAGE>");
3128 pw.println(" Control screen compatibility mode of <PACKAGE>.");
3129 pw.println(" package-importance <PACKAGE>");
3130 pw.println(" Print current importance of <PACKAGE>.");
3131 pw.println(" to-uri [INTENT]");
3132 pw.println(" Print the given Intent specification as a URI.");
3133 pw.println(" to-intent-uri [INTENT]");
3134 pw.println(" Print the given Intent specification as an intent: URI.");
3135 pw.println(" to-app-uri [INTENT]");
3136 pw.println(" Print the given Intent specification as an android-app: URI.");
3137 pw.println(" switch-user <USER_ID>");
3138 pw.println(" Switch to put USER_ID in the foreground, starting");
3139 pw.println(" execution of that user if it is currently stopped.");
3140 pw.println(" get-current-user");
3141 pw.println(" Returns id of the current foreground user.");
Bookatz03bfe6f2019-03-01 15:46:04 -08003142 pw.println(" start-user [-w] <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003143 pw.println(" Start USER_ID in background if it is currently stopped;");
Bookatz03bfe6f2019-03-01 15:46:04 -08003144 pw.println(" use switch-user if you want to start the user in foreground.");
3145 pw.println(" -w: wait for start-user to complete and the user to be unlocked.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003146 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]");
3147 pw.println(" Attempt to unlock the given user using the given authorization token.");
3148 pw.println(" stop-user [-w] [-f] <USER_ID>");
3149 pw.println(" Stop execution of USER_ID, not allowing it to run any");
3150 pw.println(" code until a later explicit start or switch to it.");
3151 pw.println(" -w: wait for stop-user to complete.");
3152 pw.println(" -f: force stop even if there are related users that cannot be stopped.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003153 pw.println(" is-user-stopped <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003154 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07003155 pw.println(" get-started-user-state <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003156 pw.println(" Gets the current state of the given started user.");
3157 pw.println(" track-associations");
3158 pw.println(" Enable association tracking.");
3159 pw.println(" untrack-associations");
3160 pw.println(" Disable and clear association tracking.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003161 pw.println(" get-uid-state <UID>");
3162 pw.println(" Gets the process state of an app given its <UID>.");
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07003163 pw.println(" attach-agent <PROCESS> <FILE>");
3164 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 +08003165 pw.println(" get-config [--days N] [--device] [--proto] [--display <DISPLAY_ID>]");
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08003166 pw.println(" Retrieve the configuration and any recent configurations of the device.");
3167 pw.println(" --days: also return last N days of configurations that have been seen.");
3168 pw.println(" --device: also output global device configuration info.");
3169 pw.println(" --proto: return result as a proto; does not include --days info.");
Jeff Change9467b22018-09-28 11:40:38 +08003170 pw.println(" --display: Specify for which display to run the command; if not ");
3171 pw.println(" specified then run for the default display.");
Michael Kwan94438b72016-11-03 15:30:34 -07003172 pw.println(" supports-multiwindow");
3173 pw.println(" Returns true if the device supports multiwindow.");
Matthew Ng626e0cc2016-12-07 17:25:53 -08003174 pw.println(" supports-split-screen-multi-window");
3175 pw.println(" Returns true if the device supports split screen multiwindow.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003176 pw.println(" suppress-resize-config-changes <true|false>");
3177 pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
3178 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
3179 pw.println(" Sets the inactive state of an app.");
3180 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
3181 pw.println(" Returns the inactive state of an app.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003182 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
Amith Yamasani17fffee2017-09-29 13:17:43 -07003183 pw.println(" Puts an app in the standby bucket.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003184 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
3185 pw.println(" Returns the standby bucket of an app.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003186 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
3187 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003188 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 -07003189 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays.");
3190 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>");
3191 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003192 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
Andrii Kulian839def92016-11-02 10:58:58 -07003193 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003194 pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
3195 pw.println(" bottom (false) of <STACK_ID>.");
3196 pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3197 pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.");
3198 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3199 pw.println(" Same as resize, but allow animation.");
3200 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
3201 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
3202 pw.println(" and supplying temporary different task bounds indicated by");
3203 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003204 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3205 pw.println(" Moves the top activity from");
3206 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
3207 pw.println(" bounds of the pinned stack.");
3208 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>");
3209 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
3210 pw.println(" list");
3211 pw.println(" List all of the activity stacks and their sizes.");
Wale Ogunwale68278562017-09-23 17:13:55 -07003212 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
3213 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003214 pw.println(" remove <STACK_ID>");
3215 pw.println(" Remove stack <STACK_ID>.");
3216 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
3217 pw.println(" lock <TASK_ID>");
3218 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run.");
3219 pw.println(" lock stop");
3220 pw.println(" End the current task lock.");
3221 pw.println(" resizeable <TASK_ID> [0|1|2|3]");
3222 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:");
3223 pw.println(" 0: unresizeable");
3224 pw.println(" 1: crop_windows");
3225 pw.println(" 2: resizeable");
3226 pw.println(" 3: resizeable_and_pipable");
3227 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3228 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
3229 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
3230 pw.println(" has the specified bounds.");
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01003231 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
3232 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
3233 pw.println(" without restarting any processes.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003234 pw.println(" write");
3235 pw.println(" Write all pending state to storage.");
Andrei Oneac014fb5c2019-06-28 18:42:22 +01003236 pw.println(" compat enable|disable|reset <CHANGE_ID|CHANGE_NAME> <PACKAGE_NAME>");
3237 pw.println(" Toggles a change either by id or by name for <PACKAGE_NAME>.");
atrost8851c3c2019-08-29 16:17:52 +01003238 pw.println(" It kills <PACKAGE_NAME> (to allow the toggle to take effect).");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003239 pw.println();
3240 Intent.printIntentArgsHelp(pw, "");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003241 }
3242 }
3243}