blob: 843699ccf19185c14da79e53fe98fba7cba56508 [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
Felipe Leme2f1b2272016-03-25 16:15:02 -070019import android.app.ActivityManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070020import android.app.ActivityOptions;
21import android.app.AppGlobals;
Dianne Hackborn331084d2016-10-07 17:57:00 -070022import android.app.IActivityController;
Dianne Hackborn2e441072015-10-28 18:00:57 -070023import android.app.IActivityManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070024import android.app.IStopUserCallback;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +010025import android.app.IUidObserver;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080026import android.app.KeyguardManager;
Dianne Hackborn354736e2016-08-22 17:00:05 -070027import android.app.ProfilerInfo;
Sudheer Shankafc46e9b2016-10-21 17:55:27 -070028import android.app.WaitResult;
Suprabh Shukla868bde22018-02-20 20:59:52 -080029import android.app.usage.AppStandbyInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070030import android.app.usage.ConfigurationStats;
31import android.app.usage.IUsageStatsManager;
32import android.app.usage.UsageStatsManager;
33import android.content.ComponentCallbacks2;
34import android.content.ComponentName;
35import android.content.Context;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080036import android.content.DeviceConfigurationProto;
37import android.content.GlobalConfigurationProto;
Dianne Hackborn331084d2016-10-07 17:57:00 -070038import android.content.IIntentReceiver;
Dianne Hackborn354736e2016-08-22 17:00:05 -070039import android.content.Intent;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080040import android.content.pm.ConfigurationInfo;
41import android.content.pm.FeatureInfo;
Dianne Hackborn354736e2016-08-22 17:00:05 -070042import android.content.pm.IPackageManager;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080043import android.content.pm.PackageManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070044import android.content.pm.ParceledListSlice;
Dianne Hackborn354736e2016-08-22 17:00:05 -070045import android.content.pm.ResolveInfo;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080046import android.content.pm.SharedLibraryInfo;
Dianne Hackborn331084d2016-10-07 17:57:00 -070047import android.content.pm.UserInfo;
Michael Kwan94438b72016-11-03 15:30:34 -070048import android.content.res.AssetManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070049import android.content.res.Configuration;
Michael Kwan94438b72016-11-03 15:30:34 -070050import android.content.res.Resources;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080051import android.graphics.Point;
Dianne Hackborn331084d2016-10-07 17:57:00 -070052import android.graphics.Rect;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080053import android.hardware.display.DisplayManager;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080054import android.opengl.GLES10;
Dianne Hackborn331084d2016-10-07 17:57:00 -070055import android.os.Binder;
56import android.os.Build;
57import android.os.Bundle;
Dianne Hackborn354736e2016-08-22 17:00:05 -070058import android.os.ParcelFileDescriptor;
Dianne Hackborn2e441072015-10-28 18:00:57 -070059import android.os.RemoteException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070060import android.os.ServiceManager;
Dianne Hackborn2e441072015-10-28 18:00:57 -070061import android.os.ShellCommand;
Dianne Hackborn5c3296a2017-12-13 17:52:26 -080062import android.os.StrictMode;
Dianne Hackborn354736e2016-08-22 17:00:05 -070063import android.os.SystemClock;
Dianne Hackborn331084d2016-10-07 17:57:00 -070064import android.os.SystemProperties;
Dianne Hackborn2e441072015-10-28 18:00:57 -070065import android.os.UserHandle;
Alex Chau5c0df232018-02-22 15:57:17 +080066import android.os.UserManager;
Dianne Hackborn331084d2016-10-07 17:57:00 -070067import android.text.TextUtils;
68import android.util.ArrayMap;
Felipe Leme2f1b2272016-03-25 16:15:02 -070069import android.util.DebugUtils;
Michael Kwan94438b72016-11-03 15:30:34 -070070import android.util.DisplayMetrics;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080071import android.util.proto.ProtoOutputStream;
72import android.view.Display;
Dianne Hackborn2e441072015-10-28 18:00:57 -070073
Dianne Hackborn331084d2016-10-07 17:57:00 -070074import com.android.internal.util.HexDump;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080075import com.android.internal.util.MemInfoReader;
Dianne Hackborn331084d2016-10-07 17:57:00 -070076import com.android.internal.util.Preconditions;
77
78import java.io.BufferedReader;
79import java.io.File;
80import java.io.IOException;
81import java.io.InputStream;
82import java.io.InputStreamReader;
Dianne Hackborn2e441072015-10-28 18:00:57 -070083import java.io.PrintWriter;
Dianne Hackborn354736e2016-08-22 17:00:05 -070084import java.net.URISyntaxException;
Dianne Hackborn331084d2016-10-07 17:57:00 -070085import java.util.ArrayList;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080086import java.util.Arrays;
Dianne Hackborn331084d2016-10-07 17:57:00 -070087import java.util.Collections;
88import java.util.Comparator;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080089import java.util.HashSet;
Dianne Hackborn354736e2016-08-22 17:00:05 -070090import java.util.List;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080091import java.util.Set;
Dianne Hackborn354736e2016-08-22 17:00:05 -070092
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080093import javax.microedition.khronos.egl.EGL10;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080094import javax.microedition.khronos.egl.EGLConfig;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080095import javax.microedition.khronos.egl.EGLContext;
Dianne Hackborn337e01a2018-02-27 17:16:37 -080096import javax.microedition.khronos.egl.EGLDisplay;
97import javax.microedition.khronos.egl.EGLSurface;
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -080098
Dianne Hackborn331084d2016-10-07 17:57:00 -070099import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
100import static android.app.ActivityManager.RESIZE_MODE_USER;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700101import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700102import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
103import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700104import static android.view.Display.INVALID_DISPLAY;
Dianne Hackborn2e441072015-10-28 18:00:57 -0700105
Winson Chung6954fc92017-03-24 16:22:12 -0700106import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
107
Dianne Hackborn331084d2016-10-07 17:57:00 -0700108final class ActivityManagerShellCommand extends ShellCommand {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700109 public static final String NO_CLASS_ERROR_CODE = "Error type 3";
Dianne Hackborn331084d2016-10-07 17:57:00 -0700110 private static final String SHELL_PACKAGE_NAME = "com.android.shell";
111
Dianne Hackborn2e441072015-10-28 18:00:57 -0700112 // IPC interface to activity manager -- don't need to do additional security checks.
113 final IActivityManager mInterface;
114
115 // Internal service impl -- must perform security checks before touching.
116 final ActivityManagerService mInternal;
117
Dianne Hackborn354736e2016-08-22 17:00:05 -0700118 // Convenience for interacting with package manager.
119 final IPackageManager mPm;
120
121 private int mStartFlags = 0;
122 private boolean mWaitOption = false;
123 private boolean mStopOption = false;
124
125 private int mRepeat = 0;
126 private int mUserId;
127 private String mReceiverPermission;
128
129 private String mProfileFile;
130 private int mSamplingInterval;
131 private boolean mAutoStop;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800132 private boolean mStreaming; // Streaming the profiling output to a file.
Andreas Gampe83085bb2017-06-26 17:54:11 -0700133 private String mAgent; // Agent to attach on startup.
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800134 private boolean mAttachAgentDuringBind; // Whether agent should be attached late.
Andrii Kulian16802aa2016-11-02 12:21:33 -0700135 private int mDisplayId;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700136 private int mWindowingMode;
137 private int mActivityType;
Winson Chung6954fc92017-03-24 16:22:12 -0700138 private int mTaskId;
139 private boolean mIsTaskOverlay;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000140 private boolean mIsLockTask;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700141
Dianne Hackborn2e441072015-10-28 18:00:57 -0700142 final boolean mDumping;
143
144 ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) {
145 mInterface = service;
146 mInternal = service;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700147 mPm = AppGlobals.getPackageManager();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700148 mDumping = dumping;
149 }
150
151 @Override
152 public int onCommand(String cmd) {
153 if (cmd == null) {
154 return handleDefaultCommands(cmd);
155 }
Dianne Hackborn5c3296a2017-12-13 17:52:26 -0800156 final PrintWriter pw = getOutPrintWriter();
Dianne Hackborn2e441072015-10-28 18:00:57 -0700157 try {
158 switch (cmd) {
Dianne Hackborn354736e2016-08-22 17:00:05 -0700159 case "start":
160 case "start-activity":
161 return runStartActivity(pw);
162 case "startservice":
163 case "start-service":
Christopher Tate7e1368d2017-03-30 17:20:12 -0700164 return runStartService(pw, false);
165 case "startforegroundservice":
166 case "startfgservice":
167 case "start-foreground-service":
168 case "start-fg-service":
169 return runStartService(pw, true);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700170 case "stopservice":
171 case "stop-service":
Dianne Hackborn331084d2016-10-07 17:57:00 -0700172 return runStopService(pw);
173 case "broadcast":
174 return runSendBroadcast(pw);
175 case "instrument":
Dianne Hackborn28824062016-10-18 13:19:20 -0700176 getOutPrintWriter().println("Error: must be invoked through 'am instrument'.");
177 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700178 case "trace-ipc":
179 return runTraceIpc(pw);
180 case "profile":
181 return runProfile(pw);
182 case "dumpheap":
183 return runDumpHeap(pw);
184 case "set-debug-app":
185 return runSetDebugApp(pw);
Andreas Gampe5b495d52018-01-22 15:15:54 -0800186 case "set-agent-app":
187 return runSetAgentApp(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700188 case "clear-debug-app":
189 return runClearDebugApp(pw);
190 case "set-watch-heap":
191 return runSetWatchHeap(pw);
192 case "clear-watch-heap":
193 return runClearWatchHeap(pw);
194 case "bug-report":
195 return runBugReport(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700196 case "force-stop":
197 return runForceStop(pw);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800198 case "crash":
199 return runCrash(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700200 case "kill":
201 return runKill(pw);
202 case "kill-all":
203 return runKillAll(pw);
Dianne Hackborn85e35642017-01-12 15:10:57 -0800204 case "make-uid-idle":
Dianne Hackborne07641d2016-11-09 15:07:23 -0800205 return runMakeIdle(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700206 case "monitor":
207 return runMonitor(pw);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +0100208 case "watch-uids":
209 return runWatchUids(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700210 case "hang":
211 return runHang(pw);
212 case "restart":
213 return runRestart(pw);
214 case "idle-maintenance":
215 return runIdleMaintenance(pw);
216 case "screen-compat":
217 return runScreenCompat(pw);
218 case "package-importance":
219 return runPackageImportance(pw);
220 case "to-uri":
221 return runToUri(pw, 0);
222 case "to-intent-uri":
223 return runToUri(pw, Intent.URI_INTENT_SCHEME);
224 case "to-app-uri":
225 return runToUri(pw, Intent.URI_ANDROID_APP_SCHEME);
226 case "switch-user":
227 return runSwitchUser(pw);
228 case "get-current-user":
229 return runGetCurrentUser(pw);
230 case "start-user":
231 return runStartUser(pw);
232 case "unlock-user":
233 return runUnlockUser(pw);
234 case "stop-user":
235 return runStopUser(pw);
236 case "is-user-stopped":
237 return runIsUserStopped(pw);
238 case "get-started-user-state":
239 return runGetStartedUserState(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700240 case "track-associations":
241 return runTrackAssociations(pw);
242 case "untrack-associations":
243 return runUntrackAssociations(pw);
Felipe Leme2f1b2272016-03-25 16:15:02 -0700244 case "get-uid-state":
245 return getUidState(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700246 case "get-config":
247 return runGetConfig(pw);
248 case "suppress-resize-config-changes":
249 return runSuppressResizeConfigChanges(pw);
250 case "set-inactive":
251 return runSetInactive(pw);
252 case "get-inactive":
253 return runGetInactive(pw);
Amith Yamasani17fffee2017-09-29 13:17:43 -0700254 case "set-standby-bucket":
255 return runSetStandbyBucket(pw);
Amith Yamasaniafbccb72017-11-27 10:44:24 -0800256 case "get-standby-bucket":
257 return runGetStandbyBucket(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700258 case "send-trim-memory":
259 return runSendTrimMemory(pw);
Andrii Kulian839def92016-11-02 10:58:58 -0700260 case "display":
261 return runDisplay(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700262 case "stack":
263 return runStack(pw);
264 case "task":
265 return runTask(pw);
266 case "write":
267 return runWrite(pw);
Leonard Mosescuf3409ce2016-10-06 17:32:05 -0700268 case "attach-agent":
269 return runAttachAgent(pw);
Michael Kwan94438b72016-11-03 15:30:34 -0700270 case "supports-multiwindow":
271 return runSupportsMultiwindow(pw);
Matthew Ng626e0cc2016-12-07 17:25:53 -0800272 case "supports-split-screen-multi-window":
273 return runSupportsSplitScreenMultiwindow(pw);
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +0100274 case "update-appinfo":
275 return runUpdateApplicationInfo(pw);
Arthur Hsuf3f3a602017-02-21 14:01:53 -0800276 case "no-home-screen":
277 return runNoHomeScreen(pw);
Jeff Sharkeyfd658132017-05-03 11:38:01 -0600278 case "wait-for-broadcast-idle":
279 return runWaitForBroadcastIdle(pw);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700280 default:
281 return handleDefaultCommands(cmd);
282 }
283 } catch (RemoteException e) {
284 pw.println("Remote exception: " + e);
285 }
286 return -1;
287 }
288
Dianne Hackborn354736e2016-08-22 17:00:05 -0700289 private Intent makeIntent(int defUser) throws URISyntaxException {
290 mStartFlags = 0;
291 mWaitOption = false;
292 mStopOption = false;
293 mRepeat = 0;
294 mProfileFile = null;
295 mSamplingInterval = 0;
296 mAutoStop = false;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800297 mStreaming = false;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700298 mUserId = defUser;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700299 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700300 mWindowingMode = WINDOWING_MODE_UNDEFINED;
301 mActivityType = ACTIVITY_TYPE_UNDEFINED;
Winson Chung6954fc92017-03-24 16:22:12 -0700302 mTaskId = INVALID_TASK_ID;
303 mIsTaskOverlay = false;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000304 mIsLockTask = false;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700305
306 return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
307 @Override
308 public boolean handleOption(String opt, ShellCommand cmd) {
309 if (opt.equals("-D")) {
310 mStartFlags |= ActivityManager.START_FLAG_DEBUG;
311 } else if (opt.equals("-N")) {
312 mStartFlags |= ActivityManager.START_FLAG_NATIVE_DEBUGGING;
313 } else if (opt.equals("-W")) {
314 mWaitOption = true;
315 } else if (opt.equals("-P")) {
316 mProfileFile = getNextArgRequired();
317 mAutoStop = true;
318 } else if (opt.equals("--start-profiler")) {
319 mProfileFile = getNextArgRequired();
320 mAutoStop = false;
321 } else if (opt.equals("--sampling")) {
322 mSamplingInterval = Integer.parseInt(getNextArgRequired());
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800323 } else if (opt.equals("--streaming")) {
324 mStreaming = true;
Andreas Gampe83085bb2017-06-26 17:54:11 -0700325 } else if (opt.equals("--attach-agent")) {
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800326 if (mAgent != null) {
327 cmd.getErrPrintWriter().println(
328 "Multiple --attach-agent(-bind) not supported");
329 return false;
330 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700331 mAgent = getNextArgRequired();
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800332 mAttachAgentDuringBind = false;
333 } else if (opt.equals("--attach-agent-bind")) {
334 if (mAgent != null) {
335 cmd.getErrPrintWriter().println(
336 "Multiple --attach-agent(-bind) not supported");
337 return false;
338 }
339 mAgent = getNextArgRequired();
340 mAttachAgentDuringBind = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700341 } else if (opt.equals("-R")) {
342 mRepeat = Integer.parseInt(getNextArgRequired());
343 } else if (opt.equals("-S")) {
344 mStopOption = true;
345 } else if (opt.equals("--track-allocation")) {
346 mStartFlags |= ActivityManager.START_FLAG_TRACK_ALLOCATION;
347 } else if (opt.equals("--user")) {
348 mUserId = UserHandle.parseUserArg(getNextArgRequired());
349 } else if (opt.equals("--receiver-permission")) {
350 mReceiverPermission = getNextArgRequired();
Andrii Kulian16802aa2016-11-02 12:21:33 -0700351 } else if (opt.equals("--display")) {
352 mDisplayId = Integer.parseInt(getNextArgRequired());
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700353 } else if (opt.equals("--windowingMode")) {
354 mWindowingMode = Integer.parseInt(getNextArgRequired());
355 } else if (opt.equals("--activityType")) {
356 mActivityType = Integer.parseInt(getNextArgRequired());
Winson Chung6954fc92017-03-24 16:22:12 -0700357 } else if (opt.equals("--task")) {
358 mTaskId = Integer.parseInt(getNextArgRequired());
359 } else if (opt.equals("--task-overlay")) {
360 mIsTaskOverlay = true;
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000361 } else if (opt.equals("--lock-task")) {
362 mIsLockTask = true;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700363 } else {
364 return false;
365 }
366 return true;
367 }
368 });
369 }
370
Dianne Hackborn354736e2016-08-22 17:00:05 -0700371 int runStartActivity(PrintWriter pw) throws RemoteException {
372 Intent intent;
373 try {
374 intent = makeIntent(UserHandle.USER_CURRENT);
375 } catch (URISyntaxException e) {
376 throw new RuntimeException(e.getMessage(), e);
377 }
378
379 if (mUserId == UserHandle.USER_ALL) {
380 getErrPrintWriter().println("Error: Can't start service with user 'all'");
381 return 1;
382 }
383
384 String mimeType = intent.getType();
385 if (mimeType == null && intent.getData() != null
386 && "content".equals(intent.getData().getScheme())) {
387 mimeType = mInterface.getProviderMimeType(intent.getData(), mUserId);
388 }
389
390 do {
391 if (mStopOption) {
392 String packageName;
393 if (intent.getComponent() != null) {
394 packageName = intent.getComponent().getPackageName();
395 } else {
396 List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0,
397 mUserId).getList();
398 if (activities == null || activities.size() <= 0) {
399 getErrPrintWriter().println("Error: Intent does not match any activities: "
400 + intent);
401 return 1;
402 } else if (activities.size() > 1) {
403 getErrPrintWriter().println(
404 "Error: Intent matches multiple activities; can't stop: "
405 + intent);
406 return 1;
407 }
408 packageName = activities.get(0).activityInfo.packageName;
409 }
410 pw.println("Stopping: " + packageName);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700411 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700412 mInterface.forceStopPackage(packageName, mUserId);
413 try {
414 Thread.sleep(250);
415 } catch (InterruptedException e) {
416 }
417 }
418
419 ProfilerInfo profilerInfo = null;
420
Andreas Gampe83085bb2017-06-26 17:54:11 -0700421 if (mProfileFile != null || mAgent != null) {
422 ParcelFileDescriptor fd = null;
423 if (mProfileFile != null) {
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700424 fd = openFileForSystem(mProfileFile, "w");
Andreas Gampe83085bb2017-06-26 17:54:11 -0700425 if (fd == null) {
426 return 1;
427 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700428 }
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800429 profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800430 mStreaming, mAgent, mAttachAgentDuringBind);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700431 }
432
433 pw.println("Starting: " + intent);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700434 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700435 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
436
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700437 WaitResult result = null;
Dianne Hackborn354736e2016-08-22 17:00:05 -0700438 int res;
439 final long startTime = SystemClock.uptimeMillis();
440 ActivityOptions options = null;
Andrii Kulian16802aa2016-11-02 12:21:33 -0700441 if (mDisplayId != INVALID_DISPLAY) {
442 options = ActivityOptions.makeBasic();
443 options.setLaunchDisplayId(mDisplayId);
444 }
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700445 if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
446 if (options == null) {
447 options = ActivityOptions.makeBasic();
448 }
449 options.setLaunchWindowingMode(mWindowingMode);
450 }
451 if (mActivityType != ACTIVITY_TYPE_UNDEFINED) {
452 if (options == null) {
453 options = ActivityOptions.makeBasic();
454 }
455 options.setLaunchActivityType(mActivityType);
Dianne Hackborn354736e2016-08-22 17:00:05 -0700456 }
Winson Chung6954fc92017-03-24 16:22:12 -0700457 if (mTaskId != INVALID_TASK_ID) {
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000458 if (options == null) {
459 options = ActivityOptions.makeBasic();
460 }
Winson Chung6954fc92017-03-24 16:22:12 -0700461 options.setLaunchTaskId(mTaskId);
462
463 if (mIsTaskOverlay) {
464 options.setTaskOverlay(true, true /* canResume */);
465 }
466 }
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000467 if (mIsLockTask) {
468 if (options == null) {
469 options = ActivityOptions.makeBasic();
470 }
Benjamin Franzcaffa772018-02-05 16:36:10 +0000471 options.setLockTaskEnabled(true);
Benjamin Franz8aedcc82018-02-02 08:49:27 +0000472 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700473 if (mWaitOption) {
474 result = mInterface.startActivityAndWait(null, null, intent, mimeType,
475 null, null, 0, mStartFlags, profilerInfo,
476 options != null ? options.toBundle() : null, mUserId);
477 res = result.result;
478 } else {
479 res = mInterface.startActivityAsUser(null, null, intent, mimeType,
480 null, null, 0, mStartFlags, profilerInfo,
481 options != null ? options.toBundle() : null, mUserId);
482 }
483 final long endTime = SystemClock.uptimeMillis();
484 PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
485 boolean launched = false;
486 switch (res) {
487 case ActivityManager.START_SUCCESS:
488 launched = true;
489 break;
490 case ActivityManager.START_SWITCHES_CANCELED:
491 launched = true;
492 out.println(
493 "Warning: Activity not started because the "
494 + " current activity is being kept for the user.");
495 break;
496 case ActivityManager.START_DELIVERED_TO_TOP:
497 launched = true;
498 out.println(
499 "Warning: Activity not started, intent has "
500 + "been delivered to currently running "
501 + "top-most instance.");
502 break;
503 case ActivityManager.START_RETURN_INTENT_TO_CALLER:
504 launched = true;
505 out.println(
506 "Warning: Activity not started because intent "
507 + "should be handled by the caller");
508 break;
509 case ActivityManager.START_TASK_TO_FRONT:
510 launched = true;
511 out.println(
512 "Warning: Activity not started, its current "
513 + "task has been brought to the front");
514 break;
515 case ActivityManager.START_INTENT_NOT_RESOLVED:
516 out.println(
517 "Error: Activity not started, unable to "
518 + "resolve " + intent.toString());
519 break;
520 case ActivityManager.START_CLASS_NOT_FOUND:
521 out.println(NO_CLASS_ERROR_CODE);
522 out.println("Error: Activity class " +
523 intent.getComponent().toShortString()
524 + " does not exist.");
525 break;
526 case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
527 out.println(
528 "Error: Activity not started, you requested to "
529 + "both forward and receive its result");
530 break;
531 case ActivityManager.START_PERMISSION_DENIED:
532 out.println(
533 "Error: Activity not started, you do not "
534 + "have permission to access it.");
535 break;
536 case ActivityManager.START_NOT_VOICE_COMPATIBLE:
537 out.println(
538 "Error: Activity not started, voice control not allowed for: "
539 + intent);
540 break;
541 case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
542 out.println(
543 "Error: Not allowed to start background user activity"
544 + " that shouldn't be displayed for all users.");
545 break;
546 default:
547 out.println(
548 "Error: Activity not started, unknown error code " + res);
549 break;
550 }
Dianne Hackborn331084d2016-10-07 17:57:00 -0700551 out.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700552 if (mWaitOption && launched) {
553 if (result == null) {
Sudheer Shankafc46e9b2016-10-21 17:55:27 -0700554 result = new WaitResult();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700555 result.who = intent.getComponent();
556 }
557 pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
558 if (result.who != null) {
559 pw.println("Activity: " + result.who.flattenToShortString());
560 }
561 if (result.thisTime >= 0) {
562 pw.println("ThisTime: " + result.thisTime);
563 }
564 if (result.totalTime >= 0) {
565 pw.println("TotalTime: " + result.totalTime);
566 }
567 pw.println("WaitTime: " + (endTime-startTime));
568 pw.println("Complete");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700569 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700570 }
571 mRepeat--;
572 if (mRepeat > 0) {
573 mInterface.unhandledBack();
574 }
575 } while (mRepeat > 0);
576 return 0;
577 }
578
Christopher Tate7e1368d2017-03-30 17:20:12 -0700579 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700580 final PrintWriter err = getErrPrintWriter();
581 Intent intent;
582 try {
583 intent = makeIntent(UserHandle.USER_CURRENT);
584 } catch (URISyntaxException e) {
585 throw new RuntimeException(e.getMessage(), e);
586 }
587 if (mUserId == UserHandle.USER_ALL) {
588 err.println("Error: Can't start activity with user 'all'");
589 return -1;
590 }
591 pw.println("Starting service: " + intent);
592 pw.flush();
593 ComponentName cn = mInterface.startService(null, intent, intent.getType(),
Christopher Tate242ba3e92017-04-14 15:07:06 -0700594 asForeground, SHELL_PACKAGE_NAME, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700595 if (cn == null) {
596 err.println("Error: Not found; no service started.");
597 return -1;
598 } else if (cn.getPackageName().equals("!")) {
599 err.println("Error: Requires permission " + cn.getClassName());
600 return -1;
601 } else if (cn.getPackageName().equals("!!")) {
602 err.println("Error: " + cn.getClassName());
603 return -1;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800604 } else if (cn.getPackageName().equals("?")) {
605 err.println("Error: " + cn.getClassName());
606 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700607 }
608 return 0;
609 }
610
611 int runStopService(PrintWriter pw) throws RemoteException {
612 final PrintWriter err = getErrPrintWriter();
613 Intent intent;
614 try {
615 intent = makeIntent(UserHandle.USER_CURRENT);
616 } catch (URISyntaxException e) {
617 throw new RuntimeException(e.getMessage(), e);
618 }
619 if (mUserId == UserHandle.USER_ALL) {
620 err.println("Error: Can't stop activity with user 'all'");
621 return -1;
622 }
623 pw.println("Stopping service: " + intent);
624 pw.flush();
625 int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
626 if (result == 0) {
627 err.println("Service not stopped: was not running.");
628 return -1;
629 } else if (result == 1) {
630 err.println("Service stopped");
631 return -1;
632 } else if (result == -1) {
633 err.println("Error stopping service");
634 return -1;
635 }
636 return 0;
637 }
638
639 final static class IntentReceiver extends IIntentReceiver.Stub {
640 private final PrintWriter mPw;
641 private boolean mFinished = false;
642
643 IntentReceiver(PrintWriter pw) {
644 mPw = pw;
645 }
646
647 @Override
648 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
649 boolean ordered, boolean sticky, int sendingUser) {
650 String line = "Broadcast completed: result=" + resultCode;
651 if (data != null) line = line + ", data=\"" + data + "\"";
652 if (extras != null) line = line + ", extras: " + extras;
653 mPw.println(line);
654 mPw.flush();
655 synchronized (this) {
656 mFinished = true;
657 notifyAll();
658 }
659 }
660
661 public synchronized void waitForFinish() {
662 try {
663 while (!mFinished) wait();
664 } catch (InterruptedException e) {
665 throw new IllegalStateException(e);
666 }
667 }
668 }
669
670 int runSendBroadcast(PrintWriter pw) throws RemoteException {
671 Intent intent;
672 try {
673 intent = makeIntent(UserHandle.USER_CURRENT);
674 } catch (URISyntaxException e) {
675 throw new RuntimeException(e.getMessage(), e);
676 }
Jeff Sharkey6a34e562016-12-21 09:56:00 -0700677 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700678 IntentReceiver receiver = new IntentReceiver(pw);
679 String[] requiredPermissions = mReceiverPermission == null ? null
680 : new String[] {mReceiverPermission};
681 pw.println("Broadcasting: " + intent);
682 pw.flush();
683 mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
684 android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
685 receiver.waitForFinish();
686 return 0;
687 }
688
Dianne Hackborn331084d2016-10-07 17:57:00 -0700689 int runTraceIpc(PrintWriter pw) throws RemoteException {
690 String op = getNextArgRequired();
691 if (op.equals("start")) {
692 return runTraceIpcStart(pw);
693 } else if (op.equals("stop")) {
694 return runTraceIpcStop(pw);
695 } else {
696 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'");
697 return -1;
698 }
699 }
700
701 int runTraceIpcStart(PrintWriter pw) throws RemoteException {
702 pw.println("Starting IPC tracing.");
703 pw.flush();
704 mInterface.startBinderTracking();
705 return 0;
706 }
707
708 int runTraceIpcStop(PrintWriter pw) throws RemoteException {
709 final PrintWriter err = getErrPrintWriter();
710 String opt;
711 String filename = null;
712 while ((opt=getNextOption()) != null) {
713 if (opt.equals("--dump-file")) {
714 filename = getNextArgRequired();
715 } else {
716 err.println("Error: Unknown option: " + opt);
717 return -1;
718 }
719 }
720 if (filename == null) {
721 err.println("Error: Specify filename to dump logs to.");
722 return -1;
723 }
724
725 File file = new File(filename);
726 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700727 ParcelFileDescriptor fd = openFileForSystem(filename, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700728 if (fd == null) {
729 return -1;
730 }
731
732 ;
733 if (!mInterface.stopBinderTrackingAndDump(fd)) {
734 err.println("STOP TRACE FAILED.");
735 return -1;
736 }
737
738 pw.println("Stopped IPC tracing. Dumping logs to: " + filename);
739 return 0;
740 }
741
742 static void removeWallOption() {
743 String props = SystemProperties.get("dalvik.vm.extra-opts");
744 if (props != null && props.contains("-Xprofile:wallclock")) {
745 props = props.replace("-Xprofile:wallclock", "");
746 props = props.trim();
747 SystemProperties.set("dalvik.vm.extra-opts", props);
748 }
749 }
750
751 private int runProfile(PrintWriter pw) throws RemoteException {
752 final PrintWriter err = getErrPrintWriter();
753 String profileFile = null;
754 boolean start = false;
755 boolean wall = false;
756 int userId = UserHandle.USER_CURRENT;
757 int profileType = 0;
758 mSamplingInterval = 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800759 mStreaming = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700760
761 String process = null;
762
763 String cmd = getNextArgRequired();
764
765 if ("start".equals(cmd)) {
766 start = true;
767 String opt;
768 while ((opt=getNextOption()) != null) {
769 if (opt.equals("--user")) {
770 userId = UserHandle.parseUserArg(getNextArgRequired());
771 } else if (opt.equals("--wall")) {
772 wall = true;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800773 } else if (opt.equals("--streaming")) {
774 mStreaming = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700775 } else if (opt.equals("--sampling")) {
776 mSamplingInterval = Integer.parseInt(getNextArgRequired());
777 } else {
778 err.println("Error: Unknown option: " + opt);
779 return -1;
780 }
781 }
782 process = getNextArgRequired();
783 } else if ("stop".equals(cmd)) {
784 String opt;
785 while ((opt=getNextOption()) != null) {
786 if (opt.equals("--user")) {
787 userId = UserHandle.parseUserArg(getNextArgRequired());
788 } else {
789 err.println("Error: Unknown option: " + opt);
790 return -1;
791 }
792 }
793 process = getNextArg();
794 } else {
795 // Compatibility with old syntax: process is specified first.
796 process = cmd;
797 cmd = getNextArgRequired();
798 if ("start".equals(cmd)) {
799 start = true;
800 } else if (!"stop".equals(cmd)) {
801 throw new IllegalArgumentException("Profile command " + process + " not valid");
802 }
803 }
804
805 if (userId == UserHandle.USER_ALL) {
806 err.println("Error: Can't profile with user 'all'");
807 return -1;
808 }
809
810 ParcelFileDescriptor fd = null;
811 ProfilerInfo profilerInfo = null;
812
813 if (start) {
814 profileFile = getNextArgRequired();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700815 fd = openFileForSystem(profileFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700816 if (fd == null) {
817 return -1;
818 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700819 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800820 null, false);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700821 }
822
823 try {
824 if (wall) {
825 // XXX doesn't work -- this needs to be set before booting.
826 String props = SystemProperties.get("dalvik.vm.extra-opts");
827 if (props == null || !props.contains("-Xprofile:wallclock")) {
828 props = props + " -Xprofile:wallclock";
829 //SystemProperties.set("dalvik.vm.extra-opts", props);
830 }
831 } else if (start) {
832 //removeWallOption();
833 }
834 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
835 wall = false;
836 err.println("PROFILE FAILED on process " + process);
837 return -1;
838 }
839 } finally {
840 if (!wall) {
841 //removeWallOption();
842 }
843 }
844 return 0;
845 }
846
847 int runDumpHeap(PrintWriter pw) throws RemoteException {
848 final PrintWriter err = getErrPrintWriter();
849 boolean managed = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700850 boolean mallocInfo = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700851 int userId = UserHandle.USER_CURRENT;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700852 boolean runGc = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700853
854 String opt;
855 while ((opt=getNextOption()) != null) {
856 if (opt.equals("--user")) {
857 userId = UserHandle.parseUserArg(getNextArgRequired());
858 if (userId == UserHandle.USER_ALL) {
859 err.println("Error: Can't dump heap with user 'all'");
860 return -1;
861 }
862 } else if (opt.equals("-n")) {
863 managed = false;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700864 } else if (opt.equals("-g")) {
865 runGc = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700866 } else if (opt.equals("-m")) {
867 managed = false;
868 mallocInfo = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700869 } else {
870 err.println("Error: Unknown option: " + opt);
871 return -1;
872 }
873 }
874 String process = getNextArgRequired();
875 String heapFile = getNextArgRequired();
876
877 File file = new File(heapFile);
878 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700879 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700880 if (fd == null) {
881 return -1;
882 }
883
Christopher Ferris8d652f82017-04-11 16:29:18 -0700884 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700885 err.println("HEAP DUMP FAILED on process " + process);
886 return -1;
887 }
888 return 0;
889 }
890
891 int runSetDebugApp(PrintWriter pw) throws RemoteException {
892 boolean wait = false;
893 boolean persistent = false;
894
895 String opt;
896 while ((opt=getNextOption()) != null) {
897 if (opt.equals("-w")) {
898 wait = true;
899 } else if (opt.equals("--persistent")) {
900 persistent = true;
901 } else {
902 getErrPrintWriter().println("Error: Unknown option: " + opt);
903 return -1;
904 }
905 }
906
907 String pkg = getNextArgRequired();
908 mInterface.setDebugApp(pkg, wait, persistent);
909 return 0;
910 }
911
Andreas Gampe5b495d52018-01-22 15:15:54 -0800912 int runSetAgentApp(PrintWriter pw) throws RemoteException {
913 String pkg = getNextArgRequired();
914 String agent = getNextArg();
915 mInterface.setAgentApp(pkg, agent);
916 return 0;
917 }
918
Dianne Hackborn331084d2016-10-07 17:57:00 -0700919 int runClearDebugApp(PrintWriter pw) throws RemoteException {
920 mInterface.setDebugApp(null, false, true);
921 return 0;
922 }
923
924 int runSetWatchHeap(PrintWriter pw) throws RemoteException {
925 String proc = getNextArgRequired();
926 String limit = getNextArgRequired();
927 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
928 return 0;
929 }
930
931 int runClearWatchHeap(PrintWriter pw) throws RemoteException {
932 String proc = getNextArgRequired();
933 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null);
934 return 0;
935 }
936
937 int runBugReport(PrintWriter pw) throws RemoteException {
938 String opt;
939 int bugreportType = ActivityManager.BUGREPORT_OPTION_FULL;
940 while ((opt=getNextOption()) != null) {
941 if (opt.equals("--progress")) {
942 bugreportType = ActivityManager.BUGREPORT_OPTION_INTERACTIVE;
Felipe Leme9606c3b2017-01-05 14:57:12 -0800943 } else if (opt.equals("--telephony")) {
944 bugreportType = ActivityManager.BUGREPORT_OPTION_TELEPHONY;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700945 } else {
946 getErrPrintWriter().println("Error: Unknown option: " + opt);
947 return -1;
948 }
949 }
950 mInterface.requestBugReport(bugreportType);
951 pw.println("Your lovely bug report is being created; please be patient.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800952 return 0;
953 }
954
Dianne Hackborn2e441072015-10-28 18:00:57 -0700955 int runForceStop(PrintWriter pw) throws RemoteException {
956 int userId = UserHandle.USER_ALL;
957
958 String opt;
959 while ((opt = getNextOption()) != null) {
960 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800961 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -0700962 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700963 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700964 return -1;
965 }
966 }
967 mInterface.forceStopPackage(getNextArgRequired(), userId);
968 return 0;
969 }
970
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800971 int runCrash(PrintWriter pw) throws RemoteException {
972 int userId = UserHandle.USER_ALL;
973
974 String opt;
975 while ((opt=getNextOption()) != null) {
976 if (opt.equals("--user")) {
977 userId = UserHandle.parseUserArg(getNextArgRequired());
978 } else {
979 getErrPrintWriter().println("Error: Unknown option: " + opt);
980 return -1;
981 }
982 }
983
984 int pid = -1;
985 String packageName = null;
986 final String arg = getNextArgRequired();
987 // The argument is either a pid or a package name
988 try {
989 pid = Integer.parseInt(arg);
990 } catch (NumberFormatException e) {
991 packageName = arg;
992 }
993 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
994 return 0;
995 }
996
Dianne Hackborn2e441072015-10-28 18:00:57 -0700997 int runKill(PrintWriter pw) throws RemoteException {
998 int userId = UserHandle.USER_ALL;
999
1000 String opt;
1001 while ((opt=getNextOption()) != null) {
1002 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001003 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001004 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001005 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001006 return -1;
1007 }
1008 }
1009 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
1010 return 0;
1011 }
1012
1013 int runKillAll(PrintWriter pw) throws RemoteException {
1014 mInterface.killAllBackgroundProcesses();
1015 return 0;
1016 }
1017
Dianne Hackborne07641d2016-11-09 15:07:23 -08001018 int runMakeIdle(PrintWriter pw) throws RemoteException {
1019 int userId = UserHandle.USER_ALL;
1020
1021 String opt;
1022 while ((opt = getNextOption()) != null) {
1023 if (opt.equals("--user")) {
1024 userId = UserHandle.parseUserArg(getNextArgRequired());
1025 } else {
1026 getErrPrintWriter().println("Error: Unknown option: " + opt);
1027 return -1;
1028 }
1029 }
1030 mInterface.makePackageIdle(getNextArgRequired(), userId);
1031 return 0;
1032 }
1033
Dianne Hackborn331084d2016-10-07 17:57:00 -07001034 static final class MyActivityController extends IActivityController.Stub {
1035 final IActivityManager mInterface;
1036 final PrintWriter mPw;
1037 final InputStream mInput;
1038 final String mGdbPort;
1039 final boolean mMonkey;
1040
1041 static final int STATE_NORMAL = 0;
1042 static final int STATE_CRASHED = 1;
1043 static final int STATE_EARLY_ANR = 2;
1044 static final int STATE_ANR = 3;
1045
1046 int mState;
1047
1048 static final int RESULT_DEFAULT = 0;
1049
1050 static final int RESULT_CRASH_DIALOG = 0;
1051 static final int RESULT_CRASH_KILL = 1;
1052
1053 static final int RESULT_EARLY_ANR_CONTINUE = 0;
1054 static final int RESULT_EARLY_ANR_KILL = 1;
1055
1056 static final int RESULT_ANR_DIALOG = 0;
1057 static final int RESULT_ANR_KILL = 1;
1058 static final int RESULT_ANR_WAIT = 1;
1059
1060 int mResult;
1061
1062 Process mGdbProcess;
1063 Thread mGdbThread;
1064 boolean mGotGdbPrint;
1065
1066 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
1067 String gdbPort, boolean monkey) {
1068 mInterface = iam;
1069 mPw = pw;
1070 mInput = input;
1071 mGdbPort = gdbPort;
1072 mMonkey = monkey;
1073 }
1074
1075 @Override
1076 public boolean activityResuming(String pkg) {
1077 synchronized (this) {
1078 mPw.println("** Activity resuming: " + pkg);
1079 mPw.flush();
1080 }
1081 return true;
1082 }
1083
1084 @Override
1085 public boolean activityStarting(Intent intent, String pkg) {
1086 synchronized (this) {
1087 mPw.println("** Activity starting: " + pkg);
1088 mPw.flush();
1089 }
1090 return true;
1091 }
1092
1093 @Override
1094 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
1095 long timeMillis, String stackTrace) {
1096 synchronized (this) {
1097 mPw.println("** ERROR: PROCESS CRASHED");
1098 mPw.println("processName: " + processName);
1099 mPw.println("processPid: " + pid);
1100 mPw.println("shortMsg: " + shortMsg);
1101 mPw.println("longMsg: " + longMsg);
1102 mPw.println("timeMillis: " + timeMillis);
1103 mPw.println("stack:");
1104 mPw.print(stackTrace);
1105 mPw.println("#");
1106 mPw.flush();
1107 int result = waitControllerLocked(pid, STATE_CRASHED);
1108 return result == RESULT_CRASH_KILL ? false : true;
1109 }
1110 }
1111
1112 @Override
1113 public int appEarlyNotResponding(String processName, int pid, String annotation) {
1114 synchronized (this) {
1115 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING");
1116 mPw.println("processName: " + processName);
1117 mPw.println("processPid: " + pid);
1118 mPw.println("annotation: " + annotation);
1119 mPw.flush();
1120 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
1121 if (result == RESULT_EARLY_ANR_KILL) return -1;
1122 return 0;
1123 }
1124 }
1125
1126 @Override
1127 public int appNotResponding(String processName, int pid, String processStats) {
1128 synchronized (this) {
1129 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1130 mPw.println("processName: " + processName);
1131 mPw.println("processPid: " + pid);
1132 mPw.println("processStats:");
1133 mPw.print(processStats);
1134 mPw.println("#");
1135 mPw.flush();
1136 int result = waitControllerLocked(pid, STATE_ANR);
1137 if (result == RESULT_ANR_KILL) return -1;
1138 if (result == RESULT_ANR_WAIT) return 1;
1139 return 0;
1140 }
1141 }
1142
1143 @Override
1144 public int systemNotResponding(String message) {
1145 synchronized (this) {
1146 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1147 mPw.println("message: " + message);
1148 mPw.println("#");
1149 mPw.println("Allowing system to die.");
1150 mPw.flush();
1151 return -1;
1152 }
1153 }
1154
1155 void killGdbLocked() {
1156 mGotGdbPrint = false;
1157 if (mGdbProcess != null) {
1158 mPw.println("Stopping gdbserver");
1159 mPw.flush();
1160 mGdbProcess.destroy();
1161 mGdbProcess = null;
1162 }
1163 if (mGdbThread != null) {
1164 mGdbThread.interrupt();
1165 mGdbThread = null;
1166 }
1167 }
1168
1169 int waitControllerLocked(int pid, int state) {
1170 if (mGdbPort != null) {
1171 killGdbLocked();
1172
1173 try {
1174 mPw.println("Starting gdbserver on port " + mGdbPort);
1175 mPw.println("Do the following:");
1176 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
1177 mPw.println(" gdbclient app_process :" + mGdbPort);
1178 mPw.flush();
1179
1180 mGdbProcess = Runtime.getRuntime().exec(new String[] {
1181 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
1182 });
1183 final InputStreamReader converter = new InputStreamReader(
1184 mGdbProcess.getInputStream());
1185 mGdbThread = new Thread() {
1186 @Override
1187 public void run() {
1188 BufferedReader in = new BufferedReader(converter);
1189 String line;
1190 int count = 0;
1191 while (true) {
1192 synchronized (MyActivityController.this) {
1193 if (mGdbThread == null) {
1194 return;
1195 }
1196 if (count == 2) {
1197 mGotGdbPrint = true;
1198 MyActivityController.this.notifyAll();
1199 }
1200 }
1201 try {
1202 line = in.readLine();
1203 if (line == null) {
1204 return;
1205 }
1206 mPw.println("GDB: " + line);
1207 mPw.flush();
1208 count++;
1209 } catch (IOException e) {
1210 return;
1211 }
1212 }
1213 }
1214 };
1215 mGdbThread.start();
1216
1217 // Stupid waiting for .5s. Doesn't matter if we end early.
1218 try {
1219 this.wait(500);
1220 } catch (InterruptedException e) {
1221 }
1222
1223 } catch (IOException e) {
1224 mPw.println("Failure starting gdbserver: " + e);
1225 mPw.flush();
1226 killGdbLocked();
1227 }
1228 }
1229 mState = state;
1230 mPw.println("");
1231 printMessageForState();
1232 mPw.flush();
1233
1234 while (mState != STATE_NORMAL) {
1235 try {
1236 wait();
1237 } catch (InterruptedException e) {
1238 }
1239 }
1240
1241 killGdbLocked();
1242
1243 return mResult;
1244 }
1245
1246 void resumeController(int result) {
1247 synchronized (this) {
1248 mState = STATE_NORMAL;
1249 mResult = result;
1250 notifyAll();
1251 }
1252 }
1253
1254 void printMessageForState() {
1255 switch (mState) {
1256 case STATE_NORMAL:
1257 mPw.println("Monitoring activity manager... available commands:");
1258 break;
1259 case STATE_CRASHED:
1260 mPw.println("Waiting after crash... available commands:");
1261 mPw.println("(c)ontinue: show crash dialog");
1262 mPw.println("(k)ill: immediately kill app");
1263 break;
1264 case STATE_EARLY_ANR:
1265 mPw.println("Waiting after early ANR... available commands:");
1266 mPw.println("(c)ontinue: standard ANR processing");
1267 mPw.println("(k)ill: immediately kill app");
1268 break;
1269 case STATE_ANR:
1270 mPw.println("Waiting after ANR... available commands:");
1271 mPw.println("(c)ontinue: show ANR dialog");
1272 mPw.println("(k)ill: immediately kill app");
1273 mPw.println("(w)ait: wait some more");
1274 break;
1275 }
1276 mPw.println("(q)uit: finish monitoring");
1277 }
1278
1279 void run() throws RemoteException {
1280 try {
1281 printMessageForState();
1282 mPw.flush();
1283
1284 mInterface.setActivityController(this, mMonkey);
1285 mState = STATE_NORMAL;
1286
1287 InputStreamReader converter = new InputStreamReader(mInput);
1288 BufferedReader in = new BufferedReader(converter);
1289 String line;
1290
1291 while ((line = in.readLine()) != null) {
1292 boolean addNewline = true;
1293 if (line.length() <= 0) {
1294 addNewline = false;
1295 } else if ("q".equals(line) || "quit".equals(line)) {
1296 resumeController(RESULT_DEFAULT);
1297 break;
1298 } else if (mState == STATE_CRASHED) {
1299 if ("c".equals(line) || "continue".equals(line)) {
1300 resumeController(RESULT_CRASH_DIALOG);
1301 } else if ("k".equals(line) || "kill".equals(line)) {
1302 resumeController(RESULT_CRASH_KILL);
1303 } else {
1304 mPw.println("Invalid command: " + line);
1305 }
1306 } else if (mState == STATE_ANR) {
1307 if ("c".equals(line) || "continue".equals(line)) {
1308 resumeController(RESULT_ANR_DIALOG);
1309 } else if ("k".equals(line) || "kill".equals(line)) {
1310 resumeController(RESULT_ANR_KILL);
1311 } else if ("w".equals(line) || "wait".equals(line)) {
1312 resumeController(RESULT_ANR_WAIT);
1313 } else {
1314 mPw.println("Invalid command: " + line);
1315 }
1316 } else if (mState == STATE_EARLY_ANR) {
1317 if ("c".equals(line) || "continue".equals(line)) {
1318 resumeController(RESULT_EARLY_ANR_CONTINUE);
1319 } else if ("k".equals(line) || "kill".equals(line)) {
1320 resumeController(RESULT_EARLY_ANR_KILL);
1321 } else {
1322 mPw.println("Invalid command: " + line);
1323 }
1324 } else {
1325 mPw.println("Invalid command: " + line);
1326 }
1327
1328 synchronized (this) {
1329 if (addNewline) {
1330 mPw.println("");
1331 }
1332 printMessageForState();
1333 mPw.flush();
1334 }
1335 }
1336
1337 } catch (IOException e) {
1338 e.printStackTrace(mPw);
1339 mPw.flush();
1340 } finally {
1341 mInterface.setActivityController(null, mMonkey);
1342 }
1343 }
1344 }
1345
1346 int runMonitor(PrintWriter pw) throws RemoteException {
1347 String opt;
1348 String gdbPort = null;
1349 boolean monkey = false;
1350 while ((opt=getNextOption()) != null) {
1351 if (opt.equals("--gdb")) {
1352 gdbPort = getNextArgRequired();
1353 } else if (opt.equals("-m")) {
1354 monkey = true;
1355 } else {
1356 getErrPrintWriter().println("Error: Unknown option: " + opt);
1357 return -1;
1358 }
1359 }
1360
1361 MyActivityController controller = new MyActivityController(mInterface, pw,
1362 getRawInputStream(), gdbPort, monkey);
1363 controller.run();
1364 return 0;
1365 }
1366
Dianne Hackborne51505a2017-08-07 17:13:52 -07001367 static final class MyUidObserver extends IUidObserver.Stub
1368 implements ActivityManagerService.OomAdjObserver {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001369 final IActivityManager mInterface;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001370 final ActivityManagerService mInternal;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001371 final PrintWriter mPw;
1372 final InputStream mInput;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001373 final int mUid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001374
1375 static final int STATE_NORMAL = 0;
1376
1377 int mState;
1378
Dianne Hackborne51505a2017-08-07 17:13:52 -07001379 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
1380 mInterface = service;
1381 mInternal = service;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001382 mPw = pw;
1383 mInput = input;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001384 mUid = uid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001385 }
1386
1387 @Override
1388 public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException {
1389 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001390 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1391 try {
1392 mPw.print(uid);
1393 mPw.print(" procstate ");
1394 mPw.print(ProcessList.makeProcStateString(procState));
1395 mPw.print(" seq ");
1396 mPw.println(procStateSeq);
1397 mPw.flush();
1398 } finally {
1399 StrictMode.setThreadPolicy(oldPolicy);
1400 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001401 }
1402 }
1403
1404 @Override
1405 public void onUidGone(int uid, boolean disabled) throws RemoteException {
1406 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001407 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1408 try {
1409 mPw.print(uid);
1410 mPw.print(" gone");
1411 if (disabled) {
1412 mPw.print(" disabled");
1413 }
1414 mPw.println();
1415 mPw.flush();
1416 } finally {
1417 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001418 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001419 }
1420 }
1421
1422 @Override
1423 public void onUidActive(int uid) throws RemoteException {
1424 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001425 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1426 try {
1427 mPw.print(uid);
1428 mPw.println(" active");
1429 mPw.flush();
1430 } finally {
1431 StrictMode.setThreadPolicy(oldPolicy);
1432 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001433 }
1434 }
1435
1436 @Override
1437 public void onUidIdle(int uid, boolean disabled) throws RemoteException {
1438 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001439 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1440 try {
1441 mPw.print(uid);
1442 mPw.print(" idle");
1443 if (disabled) {
1444 mPw.print(" disabled");
1445 }
1446 mPw.println();
1447 mPw.flush();
1448 } finally {
1449 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001450 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001451 }
1452 }
1453
1454 @Override
1455 public void onUidCachedChanged(int uid, boolean cached) 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.println(cached ? " cached" : " uncached");
1461 mPw.flush();
1462 } finally {
1463 StrictMode.setThreadPolicy(oldPolicy);
1464 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001465 }
1466 }
1467
Dianne Hackborne51505a2017-08-07 17:13:52 -07001468 @Override
1469 public void onOomAdjMessage(String msg) {
1470 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001471 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1472 try {
1473 mPw.print("# ");
1474 mPw.println(msg);
1475 mPw.flush();
1476 } finally {
1477 StrictMode.setThreadPolicy(oldPolicy);
1478 }
Dianne Hackborne51505a2017-08-07 17:13:52 -07001479 }
1480 }
1481
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001482 void printMessageForState() {
1483 switch (mState) {
1484 case STATE_NORMAL:
1485 mPw.println("Watching uid states... available commands:");
1486 break;
1487 }
1488 mPw.println("(q)uit: finish watching");
1489 }
1490
1491 void run() throws RemoteException {
1492 try {
1493 printMessageForState();
1494 mPw.flush();
1495
1496 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE
1497 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
1498 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
1499 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackborne51505a2017-08-07 17:13:52 -07001500 if (mUid >= 0) {
1501 mInternal.setOomAdjObserver(mUid, this);
1502 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001503 mState = STATE_NORMAL;
1504
1505 InputStreamReader converter = new InputStreamReader(mInput);
1506 BufferedReader in = new BufferedReader(converter);
1507 String line;
1508
1509 while ((line = in.readLine()) != null) {
1510 boolean addNewline = true;
1511 if (line.length() <= 0) {
1512 addNewline = false;
1513 } else if ("q".equals(line) || "quit".equals(line)) {
1514 break;
1515 } else {
1516 mPw.println("Invalid command: " + line);
1517 }
1518
1519 synchronized (this) {
1520 if (addNewline) {
1521 mPw.println("");
1522 }
1523 printMessageForState();
1524 mPw.flush();
1525 }
1526 }
1527
1528 } catch (IOException e) {
1529 e.printStackTrace(mPw);
1530 mPw.flush();
1531 } finally {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001532 if (mUid >= 0) {
1533 mInternal.clearOomAdjObserver();
1534 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001535 mInterface.unregisterUidObserver(this);
1536 }
1537 }
1538 }
1539
1540 int runWatchUids(PrintWriter pw) throws RemoteException {
1541 String opt;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001542 int uid = -1;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001543 while ((opt=getNextOption()) != null) {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001544 if (opt.equals("--oom")) {
1545 uid = Integer.parseInt(getNextArgRequired());
1546 } else {
1547 getErrPrintWriter().println("Error: Unknown option: " + opt);
1548 return -1;
1549
1550 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001551 }
1552
Dianne Hackborne51505a2017-08-07 17:13:52 -07001553 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001554 controller.run();
1555 return 0;
1556 }
1557
Dianne Hackborn331084d2016-10-07 17:57:00 -07001558 int runHang(PrintWriter pw) throws RemoteException {
1559 String opt;
1560 boolean allowRestart = false;
1561 while ((opt=getNextOption()) != null) {
1562 if (opt.equals("--allow-restart")) {
1563 allowRestart = true;
1564 } else {
1565 getErrPrintWriter().println("Error: Unknown option: " + opt);
1566 return -1;
1567 }
1568 }
1569
1570 pw.println("Hanging the system...");
1571 pw.flush();
1572 mInterface.hang(new Binder(), allowRestart);
1573 return 0;
1574 }
1575
1576 int runRestart(PrintWriter pw) throws RemoteException {
1577 String opt;
1578 while ((opt=getNextOption()) != null) {
1579 getErrPrintWriter().println("Error: Unknown option: " + opt);
1580 return -1;
1581 }
1582
1583 pw.println("Restart the system...");
1584 pw.flush();
1585 mInterface.restart();
1586 return 0;
1587 }
1588
1589 int runIdleMaintenance(PrintWriter pw) throws RemoteException {
1590 String opt;
1591 while ((opt=getNextOption()) != null) {
1592 getErrPrintWriter().println("Error: Unknown option: " + opt);
1593 return -1;
1594 }
1595
1596 pw.println("Performing idle maintenance...");
1597 mInterface.sendIdleJobTrigger();
1598 return 0;
1599 }
1600
1601 int runScreenCompat(PrintWriter pw) throws RemoteException {
1602 String mode = getNextArgRequired();
1603 boolean enabled;
1604 if ("on".equals(mode)) {
1605 enabled = true;
1606 } else if ("off".equals(mode)) {
1607 enabled = false;
1608 } else {
1609 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode);
1610 return -1;
1611 }
1612
1613 String packageName = getNextArgRequired();
1614 do {
1615 try {
1616 mInterface.setPackageScreenCompatMode(packageName, enabled
1617 ? ActivityManager.COMPAT_MODE_ENABLED
1618 : ActivityManager.COMPAT_MODE_DISABLED);
1619 } catch (RemoteException e) {
1620 }
1621 packageName = getNextArg();
1622 } while (packageName != null);
1623 return 0;
1624 }
1625
1626 int runPackageImportance(PrintWriter pw) throws RemoteException {
1627 String packageName = getNextArgRequired();
1628 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell");
1629 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
1630 return 0;
1631 }
1632
1633 int runToUri(PrintWriter pw, int flags) throws RemoteException {
1634 Intent intent;
1635 try {
1636 intent = makeIntent(UserHandle.USER_CURRENT);
1637 } catch (URISyntaxException e) {
1638 throw new RuntimeException(e.getMessage(), e);
1639 }
1640 pw.println(intent.toUri(flags));
1641 return 0;
1642 }
1643
1644 int runSwitchUser(PrintWriter pw) throws RemoteException {
Alex Chau5c0df232018-02-22 15:57:17 +08001645 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
1646 if (!userManager.canSwitchUsers()) {
1647 getErrPrintWriter().println("Error: disallowed switching user");
1648 return -1;
1649 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001650 String user = getNextArgRequired();
1651 mInterface.switchUser(Integer.parseInt(user));
1652 return 0;
1653 }
1654
1655 int runGetCurrentUser(PrintWriter pw) throws RemoteException {
1656 UserInfo currentUser = Preconditions.checkNotNull(mInterface.getCurrentUser(),
1657 "Current user not set");
1658 pw.println(currentUser.id);
1659 return 0;
1660 }
1661
1662 int runStartUser(PrintWriter pw) throws RemoteException {
1663 String user = getNextArgRequired();
1664 boolean success = mInterface.startUserInBackground(Integer.parseInt(user));
1665 if (success) {
1666 pw.println("Success: user started");
1667 } else {
1668 getErrPrintWriter().println("Error: could not start user");
1669 }
1670 return 0;
1671 }
1672
1673 private static byte[] argToBytes(String arg) {
1674 if (arg.equals("!")) {
1675 return null;
1676 } else {
1677 return HexDump.hexStringToByteArray(arg);
1678 }
1679 }
1680
1681 int runUnlockUser(PrintWriter pw) throws RemoteException {
1682 int userId = Integer.parseInt(getNextArgRequired());
1683 byte[] token = argToBytes(getNextArgRequired());
1684 byte[] secret = argToBytes(getNextArgRequired());
1685 boolean success = mInterface.unlockUser(userId, token, secret, null);
1686 if (success) {
1687 pw.println("Success: user unlocked");
1688 } else {
1689 getErrPrintWriter().println("Error: could not unlock user");
1690 }
1691 return 0;
1692 }
1693
1694 static final class StopUserCallback extends IStopUserCallback.Stub {
1695 private boolean mFinished = false;
1696
1697 public synchronized void waitForFinish() {
1698 try {
1699 while (!mFinished) wait();
1700 } catch (InterruptedException e) {
1701 throw new IllegalStateException(e);
1702 }
1703 }
1704
1705 @Override
1706 public synchronized void userStopped(int userId) {
1707 mFinished = true;
1708 notifyAll();
1709 }
1710
1711 @Override
1712 public synchronized void userStopAborted(int userId) {
1713 mFinished = true;
1714 notifyAll();
1715 }
1716 }
1717
1718 int runStopUser(PrintWriter pw) throws RemoteException {
1719 boolean wait = false;
1720 boolean force = false;
1721 String opt;
1722 while ((opt = getNextOption()) != null) {
1723 if ("-w".equals(opt)) {
1724 wait = true;
1725 } else if ("-f".equals(opt)) {
1726 force = true;
1727 } else {
1728 getErrPrintWriter().println("Error: unknown option: " + opt);
1729 return -1;
1730 }
1731 }
1732 int user = Integer.parseInt(getNextArgRequired());
1733 StopUserCallback callback = wait ? new StopUserCallback() : null;
1734
1735 int res = mInterface.stopUser(user, force, callback);
1736 if (res != ActivityManager.USER_OP_SUCCESS) {
1737 String txt = "";
1738 switch (res) {
1739 case ActivityManager.USER_OP_IS_CURRENT:
1740 txt = " (Can't stop current user)";
1741 break;
1742 case ActivityManager.USER_OP_UNKNOWN_USER:
1743 txt = " (Unknown user " + user + ")";
1744 break;
1745 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
1746 txt = " (System user cannot be stopped)";
1747 break;
1748 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP:
1749 txt = " (Can't stop user " + user
1750 + " - one of its related users can't be stopped)";
1751 break;
1752 }
1753 getErrPrintWriter().println("Switch failed: " + res + txt);
1754 return -1;
1755 } else if (callback != null) {
1756 callback.waitForFinish();
1757 }
1758 return 0;
1759 }
1760
1761 int runIsUserStopped(PrintWriter pw) {
1762 int userId = UserHandle.parseUserArg(getNextArgRequired());
1763 boolean stopped = mInternal.isUserStopped(userId);
1764 pw.println(stopped);
1765 return 0;
1766 }
1767
1768 int runGetStartedUserState(PrintWriter pw) throws RemoteException {
1769 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1770 "runGetStartedUserState()");
1771 final int userId = Integer.parseInt(getNextArgRequired());
1772 try {
1773 pw.println(mInternal.getStartedUserState(userId));
1774 } catch (NullPointerException e) {
1775 pw.println("User is not started: " + userId);
1776 }
Dianne Hackborn2e441072015-10-28 18:00:57 -07001777 return 0;
1778 }
1779
1780 int runTrackAssociations(PrintWriter pw) {
1781 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1782 "registerUidObserver()");
1783 synchronized (mInternal) {
1784 if (!mInternal.mTrackingAssociations) {
1785 mInternal.mTrackingAssociations = true;
1786 pw.println("Association tracking started.");
1787 } else {
1788 pw.println("Association tracking already enabled.");
1789 }
1790 }
1791 return 0;
1792 }
1793
1794 int runUntrackAssociations(PrintWriter pw) {
1795 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1796 "registerUidObserver()");
1797 synchronized (mInternal) {
1798 if (mInternal.mTrackingAssociations) {
1799 mInternal.mTrackingAssociations = false;
1800 mInternal.mAssociations.clear();
1801 pw.println("Association tracking stopped.");
1802 } else {
1803 pw.println("Association tracking not running.");
1804 }
1805 }
1806 return 0;
1807 }
1808
Felipe Leme2f1b2272016-03-25 16:15:02 -07001809 int getUidState(PrintWriter pw) throws RemoteException {
1810 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1811 "getUidState()");
1812 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
1813 pw.print(state);
1814 pw.print(" (");
1815 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
1816 pw.println(")");
1817 return 0;
1818 }
1819
Dianne Hackborn331084d2016-10-07 17:57:00 -07001820 private List<Configuration> getRecentConfigurations(int days) {
1821 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1822 Context.USAGE_STATS_SERVICE));
1823 final long now = System.currentTimeMillis();
1824 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
Sudheer Shanka28537b62016-09-07 11:12:31 -07001825 try {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001826 @SuppressWarnings("unchecked")
1827 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
1828 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
1829 if (configStatsSlice == null) {
1830 return Collections.emptyList();
1831 }
1832
1833 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
1834 final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
1835 final int configStatsListSize = configStatsList.size();
1836 for (int i = 0; i < configStatsListSize; i++) {
1837 final ConfigurationStats stats = configStatsList.get(i);
1838 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
1839 if (indexOfKey < 0) {
1840 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
1841 } else {
1842 recentConfigs.setValueAt(indexOfKey,
1843 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
1844 }
1845 }
1846
1847 final Comparator<Configuration> comparator = new Comparator<Configuration>() {
1848 @Override
1849 public int compare(Configuration a, Configuration b) {
1850 return recentConfigs.get(b).compareTo(recentConfigs.get(a));
1851 }
1852 };
1853
1854 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
1855 configs.addAll(recentConfigs.keySet());
1856 Collections.sort(configs, comparator);
1857 return configs;
1858
1859 } catch (RemoteException e) {
1860 return Collections.emptyList();
Sudheer Shanka28537b62016-09-07 11:12:31 -07001861 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001862 }
1863
Dianne Hackborn337e01a2018-02-27 17:16:37 -08001864 /**
1865 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
1866 * and EGLSurface and querying extensions.
1867 *
1868 * @param egl An EGL API object
1869 * @param display An EGLDisplay to create a context and surface with
1870 * @param config The EGLConfig to get the extensions for
1871 * @param surfaceSize eglCreatePbufferSurface generic parameters
1872 * @param contextAttribs eglCreateContext generic parameters
1873 * @param glExtensions A Set<String> to add GL extensions to
1874 */
1875 private static void addExtensionsForConfig(
1876 EGL10 egl,
1877 EGLDisplay display,
1878 EGLConfig config,
1879 int[] surfaceSize,
1880 int[] contextAttribs,
1881 Set<String> glExtensions) {
1882 // Create a context.
1883 EGLContext context =
1884 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
1885 // No-op if we can't create a context.
1886 if (context == EGL10.EGL_NO_CONTEXT) {
1887 return;
1888 }
1889
1890 // Create a surface.
1891 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
1892 if (surface == EGL10.EGL_NO_SURFACE) {
1893 egl.eglDestroyContext(display, context);
1894 return;
1895 }
1896
1897 // Update the current surface and context.
1898 egl.eglMakeCurrent(display, surface, surface, context);
1899
1900 // Get the list of extensions.
1901 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
1902 if (!TextUtils.isEmpty(extensionList)) {
1903 // The list of extensions comes from the driver separated by spaces.
1904 // Split them apart and add them into a Set for deduping purposes.
1905 for (String extension : extensionList.split(" ")) {
1906 glExtensions.add(extension);
1907 }
1908 }
1909
1910 // Tear down the context and surface for this config.
1911 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
1912 egl.eglDestroySurface(display, surface);
1913 egl.eglDestroyContext(display, context);
1914 }
1915
1916
1917 Set<String> getGlExtensionsFromDriver() {
1918 Set<String> glExtensions = new HashSet<>();
1919
1920 // Get the EGL implementation.
1921 EGL10 egl = (EGL10) EGLContext.getEGL();
1922 if (egl == null) {
1923 getErrPrintWriter().println("Warning: couldn't get EGL");
1924 return glExtensions;
1925 }
1926
1927 // Get the default display and initialize it.
1928 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
1929 int[] version = new int[2];
1930 egl.eglInitialize(display, version);
1931
1932 // Call getConfigs() in order to find out how many there are.
1933 int[] numConfigs = new int[1];
1934 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
1935 getErrPrintWriter().println("Warning: couldn't get EGL config count");
1936 return glExtensions;
1937 }
1938
1939 // Allocate space for all configs and ask again.
1940 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
1941 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
1942 getErrPrintWriter().println("Warning: couldn't get EGL configs");
1943 return glExtensions;
1944 }
1945
1946 // Allocate surface size parameters outside of the main loop to cut down
1947 // on GC thrashing. 1x1 is enough since we are only using it to get at
1948 // the list of extensions.
1949 int[] surfaceSize =
1950 new int[] {
1951 EGL10.EGL_WIDTH, 1,
1952 EGL10.EGL_HEIGHT, 1,
1953 EGL10.EGL_NONE
1954 };
1955
1956 // For when we need to create a GLES2.0 context.
1957 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
1958 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
1959
1960 // For getting return values from eglGetConfigAttrib
1961 int[] attrib = new int[1];
1962
1963 for (int i = 0; i < numConfigs[0]; i++) {
1964 // Get caveat for this config in order to skip slow (i.e. software) configs.
1965 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
1966 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
1967 continue;
1968 }
1969
1970 // If the config does not support pbuffers we cannot do an eglMakeCurrent
1971 // on it in addExtensionsForConfig(), so skip it here. Attempting to make
1972 // it current with a pbuffer will result in an EGL_BAD_MATCH error
1973 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
1974 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
1975 continue;
1976 }
1977
1978 final int EGL_OPENGL_ES_BIT = 0x0001;
1979 final int EGL_OPENGL_ES2_BIT = 0x0004;
1980 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
1981 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
1982 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
1983 }
1984 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
1985 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
1986 }
1987 }
1988
1989 // Release all EGL resources.
1990 egl.eglTerminate(display);
1991
1992 return glExtensions;
1993 }
1994
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08001995 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
1996 PrintWriter pw, Configuration config, DisplayManager dm) {
1997 Point stableSize = dm.getStableDisplaySize();
1998 long token = -1;
1999 if (protoOutputStream != null) {
2000 token = protoOutputStream.start(fieldId);
2001 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX, stableSize.x);
2002 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX, stableSize.y);
2003 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI,
2004 DisplayMetrics.DENSITY_DEVICE_STABLE);
2005 }
2006 if (pw != null) {
2007 pw.print("stable-width-px: "); pw.println(stableSize.x);
2008 pw.print("stable-height-px: "); pw.println(stableSize.y);
2009 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE);
2010 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002011
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002012 MemInfoReader memreader = new MemInfoReader();
2013 memreader.readMemInfo();
2014 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class);
2015 if (protoOutputStream != null) {
2016 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize());
2017 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM,
2018 ActivityManager.isLowRamDeviceStatic());
2019 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES,
2020 Runtime.getRuntime().availableProcessors());
2021 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK,
2022 kgm.isDeviceSecure());
2023 }
2024 if (pw != null) {
2025 pw.print("total-ram: "); pw.println(memreader.getTotalSize());
2026 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic());
2027 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors());
2028 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
2029 }
2030
2031 ConfigurationInfo configInfo = mInternal.getDeviceConfigurationInfo();
2032 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
2033 if (protoOutputStream != null) {
2034 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
2035 configInfo.reqGlEsVersion);
2036 }
2037 if (pw != null) {
2038 pw.print("opengl-version: 0x");
2039 pw.println(Integer.toHexString(configInfo.reqGlEsVersion));
2040 }
2041 }
2042
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002043 Set<String> glExtensionsSet = getGlExtensionsFromDriver();
2044 String[] glExtensions = new String[glExtensionsSet.size()];
2045 glExtensions = glExtensionsSet.toArray(glExtensions);
2046 Arrays.sort(glExtensions);
2047 for (int i = 0; i < glExtensions.length; i++) {
2048 if (protoOutputStream != null) {
2049 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
2050 glExtensions[i]);
2051 }
2052 if (pw != null) {
2053 pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
2054 }
2055
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002056 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002057
2058 PackageManager pm = mInternal.mContext.getPackageManager();
2059 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002060 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002061 for (int i = 0; i < slibs.size(); i++) {
2062 if (protoOutputStream != null) {
2063 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
2064 slibs.get(i).getName());
2065 }
2066 if (pw != null) {
2067 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName());
2068 }
2069 }
2070
2071 FeatureInfo[] features = pm.getSystemAvailableFeatures();
weijuncheng12030002018-10-30 14:07:53 +08002072 Arrays.sort(features, (o1, o2) -> {
2073 if (o1.name == o2.name) return 0;
2074 if (o1.name == null) return -1;
2075 if (o2.name == null) return 1;
2076 return o1.name.compareTo(o2.name);
2077 });
2078
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002079 for (int i = 0; i < features.length; i++) {
2080 if (features[i].name != null) {
2081 if (protoOutputStream != null) {
2082 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name);
2083 }
2084 if (pw != null) {
2085 pw.print("features: "); pw.println(features[i].name);
2086 }
2087 }
2088 }
2089
2090 if (protoOutputStream != null) {
2091 protoOutputStream.end(token);
2092 }
2093 }
2094
2095 int runGetConfig(PrintWriter pw) throws RemoteException {
2096 int days = -1;
2097 boolean asProto = false;
2098 boolean inclDevice = false;
2099
2100 String opt;
2101 while ((opt=getNextOption()) != null) {
2102 if (opt.equals("--days")) {
2103 days = Integer.parseInt(getNextArgRequired());
2104 if (days <= 0) {
2105 throw new IllegalArgumentException("--days must be a positive integer");
2106 }
2107 } else if (opt.equals("--proto")) {
2108 asProto = true;
2109 } else if (opt.equals("--device")) {
2110 inclDevice = true;
2111 } else {
2112 getErrPrintWriter().println("Error: Unknown option: " + opt);
2113 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -07002114 }
2115 }
2116
2117 Configuration config = mInterface.getConfiguration();
2118 if (config == null) {
2119 getErrPrintWriter().println("Activity manager has no configuration");
2120 return -1;
2121 }
2122
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002123 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class);
2124 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
2125 DisplayMetrics metrics = new DisplayMetrics();
2126 display.getMetrics(metrics);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002127
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002128 if (asProto) {
2129 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor());
2130 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics);
2131 if (inclDevice) {
2132 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, dm);
2133 }
2134 proto.flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002135
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002136 } else {
2137 pw.println("config: " + Configuration.resourceQualifierString(config, metrics));
2138 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
2139 if (inclDevice) {
2140 writeDeviceConfig(null, -1, pw, config, dm);
2141 }
2142
2143 if (days >= 0) {
2144 final List<Configuration> recentConfigs = getRecentConfigurations(days);
2145 final int recentConfigSize = recentConfigs.size();
2146 if (recentConfigSize > 0) {
2147 pw.println("recentConfigs:");
2148 for (int i = 0; i < recentConfigSize; i++) {
2149 pw.println(" config: " + Configuration.resourceQualifierString(
2150 recentConfigs.get(i)));
2151 }
2152 }
2153 }
2154
Dianne Hackborn331084d2016-10-07 17:57:00 -07002155 }
2156 return 0;
2157 }
2158
2159 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
2160 boolean suppress = Boolean.valueOf(getNextArgRequired());
2161 mInterface.suppressResizeConfigChanges(suppress);
2162 return 0;
2163 }
2164
2165 int runSetInactive(PrintWriter pw) throws RemoteException {
2166 int userId = UserHandle.USER_CURRENT;
2167
2168 String opt;
2169 while ((opt=getNextOption()) != null) {
2170 if (opt.equals("--user")) {
2171 userId = UserHandle.parseUserArg(getNextArgRequired());
2172 } else {
2173 getErrPrintWriter().println("Error: Unknown option: " + opt);
2174 return -1;
2175 }
2176 }
2177 String packageName = getNextArgRequired();
2178 String value = getNextArgRequired();
2179
2180 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2181 Context.USAGE_STATS_SERVICE));
2182 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId);
2183 return 0;
2184 }
2185
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002186 private int bucketNameToBucketValue(String name) {
2187 String lower = name.toLowerCase();
2188 if (lower.startsWith("ac")) {
2189 return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
2190 } else if (lower.startsWith("wo")) {
2191 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
2192 } else if (lower.startsWith("fr")) {
2193 return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
2194 } else if (lower.startsWith("ra")) {
2195 return UsageStatsManager.STANDBY_BUCKET_RARE;
2196 } else if (lower.startsWith("ne")) {
2197 return UsageStatsManager.STANDBY_BUCKET_NEVER;
2198 } else {
2199 try {
2200 int bucket = Integer.parseInt(lower);
2201 return bucket;
2202 } catch (NumberFormatException nfe) {
2203 getErrPrintWriter().println("Error: Unknown bucket: " + name);
2204 }
2205 }
2206 return -1;
2207 }
2208
Amith Yamasani17fffee2017-09-29 13:17:43 -07002209 int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
2210 int userId = UserHandle.USER_CURRENT;
2211
2212 String opt;
2213 while ((opt=getNextOption()) != null) {
2214 if (opt.equals("--user")) {
2215 userId = UserHandle.parseUserArg(getNextArgRequired());
2216 } else {
2217 getErrPrintWriter().println("Error: Unknown option: " + opt);
2218 return -1;
2219 }
2220 }
2221 String packageName = getNextArgRequired();
2222 String value = getNextArgRequired();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002223 int bucket = bucketNameToBucketValue(value);
2224 if (bucket < 0) return -1;
Amith Yamasanie8789312017-12-10 14:34:26 -08002225 boolean multiple = peekNextArg() != null;
2226
Amith Yamasani17fffee2017-09-29 13:17:43 -07002227
2228 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2229 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002230 if (!multiple) {
2231 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
2232 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002233 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
2234 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002235 while ((packageName = getNextArg()) != null) {
2236 value = getNextArgRequired();
2237 bucket = bucketNameToBucketValue(value);
2238 if (bucket < 0) continue;
Suprabh Shukla868bde22018-02-20 20:59:52 -08002239 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002240 }
Suprabh Shukla868bde22018-02-20 20:59:52 -08002241 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
2242 usm.setAppStandbyBuckets(slice, userId);
Amith Yamasanie8789312017-12-10 14:34:26 -08002243 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002244 return 0;
2245 }
2246
2247 int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
2248 int userId = UserHandle.USER_CURRENT;
2249
2250 String opt;
2251 while ((opt=getNextOption()) != null) {
2252 if (opt.equals("--user")) {
2253 userId = UserHandle.parseUserArg(getNextArgRequired());
2254 } else {
2255 getErrPrintWriter().println("Error: Unknown option: " + opt);
2256 return -1;
2257 }
2258 }
Amith Yamasanie8789312017-12-10 14:34:26 -08002259 String packageName = getNextArg();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002260
2261 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2262 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002263 if (packageName != null) {
2264 int bucket = usm.getAppStandbyBucket(packageName, null, userId);
2265 pw.println(bucket);
2266 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002267 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -08002268 SHELL_PACKAGE_NAME, userId);
Suprabh Shukla868bde22018-02-20 20:59:52 -08002269 for (AppStandbyInfo bucketInfo : buckets.getList()) {
2270 pw.print(bucketInfo.mPackageName); pw.print(": ");
2271 pw.println(bucketInfo.mStandbyBucket);
Amith Yamasanie8789312017-12-10 14:34:26 -08002272 }
2273 }
Amith Yamasani17fffee2017-09-29 13:17:43 -07002274 return 0;
2275 }
2276
Dianne Hackborn331084d2016-10-07 17:57:00 -07002277 int runGetInactive(PrintWriter pw) throws RemoteException {
2278 int userId = UserHandle.USER_CURRENT;
2279
2280 String opt;
2281 while ((opt=getNextOption()) != null) {
2282 if (opt.equals("--user")) {
2283 userId = UserHandle.parseUserArg(getNextArgRequired());
2284 } else {
2285 getErrPrintWriter().println("Error: Unknown option: " + opt);
2286 return -1;
2287 }
2288 }
2289 String packageName = getNextArgRequired();
2290
2291 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2292 Context.USAGE_STATS_SERVICE));
2293 boolean isIdle = usm.isAppInactive(packageName, userId);
2294 pw.println("Idle=" + isIdle);
2295 return 0;
2296 }
2297
2298 int runSendTrimMemory(PrintWriter pw) throws RemoteException {
2299 int userId = UserHandle.USER_CURRENT;
2300 String opt;
2301 while ((opt = getNextOption()) != null) {
2302 if (opt.equals("--user")) {
2303 userId = UserHandle.parseUserArg(getNextArgRequired());
2304 if (userId == UserHandle.USER_ALL) {
2305 getErrPrintWriter().println("Error: Can't use user 'all'");
2306 return -1;
2307 }
2308 } else {
2309 getErrPrintWriter().println("Error: Unknown option: " + opt);
2310 return -1;
2311 }
2312 }
2313
2314 String proc = getNextArgRequired();
2315 String levelArg = getNextArgRequired();
2316 int level;
2317 switch (levelArg) {
2318 case "HIDDEN":
2319 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
2320 break;
2321 case "RUNNING_MODERATE":
2322 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
2323 break;
2324 case "BACKGROUND":
2325 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
2326 break;
2327 case "RUNNING_LOW":
2328 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
2329 break;
2330 case "MODERATE":
2331 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
2332 break;
2333 case "RUNNING_CRITICAL":
2334 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
2335 break;
2336 case "COMPLETE":
2337 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
2338 break;
2339 default:
Dianne Hackborne51505a2017-08-07 17:13:52 -07002340 try {
2341 level = Integer.parseInt(levelArg);
2342 } catch (NumberFormatException e) {
2343 getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
2344 return -1;
2345 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002346 }
2347 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
2348 getErrPrintWriter().println("Unknown error: failed to set trim level");
2349 return -1;
2350 }
2351 return 0;
2352 }
2353
Andrii Kulian839def92016-11-02 10:58:58 -07002354 int runDisplay(PrintWriter pw) throws RemoteException {
2355 String op = getNextArgRequired();
2356 switch (op) {
2357 case "move-stack":
2358 return runDisplayMoveStack(pw);
2359 default:
2360 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2361 return -1;
2362 }
2363 }
2364
Dianne Hackborn331084d2016-10-07 17:57:00 -07002365 int runStack(PrintWriter pw) throws RemoteException {
2366 String op = getNextArgRequired();
2367 switch (op) {
2368 case "start":
2369 return runStackStart(pw);
Andrii Kulian839def92016-11-02 10:58:58 -07002370 case "move-task":
Dianne Hackborn331084d2016-10-07 17:57:00 -07002371 return runStackMoveTask(pw);
2372 case "resize":
2373 return runStackResize(pw);
2374 case "resize-animated":
2375 return runStackResizeAnimated(pw);
2376 case "resize-docked-stack":
2377 return runStackResizeDocked(pw);
2378 case "positiontask":
2379 return runStackPositionTask(pw);
2380 case "list":
2381 return runStackList(pw);
2382 case "info":
2383 return runStackInfo(pw);
2384 case "move-top-activity-to-pinned-stack":
2385 return runMoveTopActivityToPinnedStack(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002386 case "remove":
2387 return runStackRemove(pw);
2388 default:
2389 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2390 return -1;
2391 }
2392 }
2393
2394
2395 private Rect getBounds() {
2396 String leftStr = getNextArgRequired();
2397 int left = Integer.parseInt(leftStr);
2398 String topStr = getNextArgRequired();
2399 int top = Integer.parseInt(topStr);
2400 String rightStr = getNextArgRequired();
2401 int right = Integer.parseInt(rightStr);
2402 String bottomStr = getNextArgRequired();
2403 int bottom = Integer.parseInt(bottomStr);
2404 if (left < 0) {
2405 getErrPrintWriter().println("Error: bad left arg: " + leftStr);
2406 return null;
2407 }
2408 if (top < 0) {
2409 getErrPrintWriter().println("Error: bad top arg: " + topStr);
2410 return null;
2411 }
2412 if (right <= 0) {
2413 getErrPrintWriter().println("Error: bad right arg: " + rightStr);
2414 return null;
2415 }
2416 if (bottom <= 0) {
2417 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr);
2418 return null;
2419 }
2420 return new Rect(left, top, right, bottom);
2421 }
2422
Andrii Kulian839def92016-11-02 10:58:58 -07002423 int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
2424 String stackIdStr = getNextArgRequired();
2425 int stackId = Integer.parseInt(stackIdStr);
2426 String displayIdStr = getNextArgRequired();
2427 int displayId = Integer.parseInt(displayIdStr);
2428 mInterface.moveStackToDisplay(stackId, displayId);
2429 return 0;
2430 }
2431
Dianne Hackborn331084d2016-10-07 17:57:00 -07002432 int runStackStart(PrintWriter pw) throws RemoteException {
2433 String displayIdStr = getNextArgRequired();
2434 int displayId = Integer.parseInt(displayIdStr);
2435 Intent intent;
2436 try {
2437 intent = makeIntent(UserHandle.USER_CURRENT);
2438 } catch (URISyntaxException e) {
2439 throw new RuntimeException(e.getMessage(), e);
2440 }
2441
Andrii Kulianb1cdb102017-07-13 15:33:06 -07002442 final int stackId = mInterface.createStackOnDisplay(displayId);
2443 if (stackId != INVALID_STACK_ID) {
2444 // TODO: Need proper support if this is used by test...
2445// container.startActivity(intent);
2446// ActivityOptions options = ActivityOptions.makeBasic();
2447// options.setLaunchDisplayId(displayId);
2448// options.setLaunchStackId(stackId);
2449// mInterface.startAct
2450// mInterface.startActivityAsUser(null, null, intent, mimeType,
2451// null, null, 0, mStartFlags, profilerInfo,
2452// options != null ? options.toBundle() : null, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002453 }
2454 return 0;
2455 }
2456
2457 int runStackMoveTask(PrintWriter pw) throws RemoteException {
2458 String taskIdStr = getNextArgRequired();
2459 int taskId = Integer.parseInt(taskIdStr);
2460 String stackIdStr = getNextArgRequired();
2461 int stackId = Integer.parseInt(stackIdStr);
2462 String toTopStr = getNextArgRequired();
2463 final boolean toTop;
2464 if ("true".equals(toTopStr)) {
2465 toTop = true;
2466 } else if ("false".equals(toTopStr)) {
2467 toTop = false;
2468 } else {
2469 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr);
2470 return -1;
2471 }
2472
2473 mInterface.moveTaskToStack(taskId, stackId, toTop);
2474 return 0;
2475 }
2476
2477 int runStackResize(PrintWriter pw) throws RemoteException {
2478 String stackIdStr = getNextArgRequired();
2479 int stackId = Integer.parseInt(stackIdStr);
2480 final Rect bounds = getBounds();
2481 if (bounds == null) {
2482 getErrPrintWriter().println("Error: invalid input bounds");
2483 return -1;
2484 }
2485 return resizeStack(stackId, bounds, 0);
2486 }
2487
2488 int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
2489 String stackIdStr = getNextArgRequired();
2490 int stackId = Integer.parseInt(stackIdStr);
2491 final Rect bounds;
2492 if ("null".equals(peekNextArg())) {
2493 bounds = null;
2494 } else {
2495 bounds = getBounds();
2496 if (bounds == null) {
2497 getErrPrintWriter().println("Error: invalid input bounds");
2498 return -1;
2499 }
2500 }
2501 return resizeStackUnchecked(stackId, bounds, 0, true);
2502 }
2503
2504 int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate)
2505 throws RemoteException {
2506 try {
2507 mInterface.resizeStack(stackId, bounds, false, false, animate, -1);
2508 Thread.sleep(delayMs);
2509 } catch (InterruptedException e) {
2510 }
2511 return 0;
2512 }
2513
2514 int runStackResizeDocked(PrintWriter pw) throws RemoteException {
2515 final Rect bounds = getBounds();
2516 final Rect taskBounds = getBounds();
2517 if (bounds == null || taskBounds == null) {
2518 getErrPrintWriter().println("Error: invalid input bounds");
2519 return -1;
2520 }
2521 mInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
2522 return 0;
2523 }
2524
2525 int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException {
2526 if (bounds == null) {
2527 getErrPrintWriter().println("Error: invalid input bounds");
2528 return -1;
2529 }
2530 return resizeStackUnchecked(stackId, bounds, delayMs, false);
2531 }
2532
2533 int runStackPositionTask(PrintWriter pw) throws RemoteException {
2534 String taskIdStr = getNextArgRequired();
2535 int taskId = Integer.parseInt(taskIdStr);
2536 String stackIdStr = getNextArgRequired();
2537 int stackId = Integer.parseInt(stackIdStr);
2538 String positionStr = getNextArgRequired();
2539 int position = Integer.parseInt(positionStr);
2540
2541 mInterface.positionTaskInStack(taskId, stackId, position);
2542 return 0;
2543 }
2544
2545 int runStackList(PrintWriter pw) throws RemoteException {
2546 List<ActivityManager.StackInfo> stacks = mInterface.getAllStackInfos();
2547 for (ActivityManager.StackInfo info : stacks) {
2548 pw.println(info);
2549 }
2550 return 0;
2551 }
2552
2553 int runStackInfo(PrintWriter pw) throws RemoteException {
Wale Ogunwale68278562017-09-23 17:13:55 -07002554 int windowingMode = Integer.parseInt(getNextArgRequired());
2555 int activityType = Integer.parseInt(getNextArgRequired());
2556 ActivityManager.StackInfo info = mInterface.getStackInfo(windowingMode, activityType);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002557 pw.println(info);
2558 return 0;
2559 }
2560
2561 int runStackRemove(PrintWriter pw) throws RemoteException {
2562 String stackIdStr = getNextArgRequired();
2563 int stackId = Integer.parseInt(stackIdStr);
2564 mInterface.removeStack(stackId);
2565 return 0;
2566 }
2567
2568 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException {
2569 int stackId = Integer.parseInt(getNextArgRequired());
2570 final Rect bounds = getBounds();
2571 if (bounds == null) {
2572 getErrPrintWriter().println("Error: invalid input bounds");
2573 return -1;
2574 }
2575
2576 if (!mInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
2577 getErrPrintWriter().println("Didn't move top activity to pinned stack.");
2578 return -1;
2579 }
2580 return 0;
2581 }
2582
Dianne Hackborn331084d2016-10-07 17:57:00 -07002583 void setBoundsSide(Rect bounds, String side, int value) {
2584 switch (side) {
2585 case "l":
2586 bounds.left = value;
2587 break;
2588 case "r":
2589 bounds.right = value;
2590 break;
2591 case "t":
2592 bounds.top = value;
2593 break;
2594 case "b":
2595 bounds.bottom = value;
2596 break;
2597 default:
2598 getErrPrintWriter().println("Unknown set side: " + side);
2599 break;
2600 }
2601 }
2602
2603 int runTask(PrintWriter pw) throws RemoteException {
2604 String op = getNextArgRequired();
2605 if (op.equals("lock")) {
2606 return runTaskLock(pw);
2607 } else if (op.equals("resizeable")) {
2608 return runTaskResizeable(pw);
2609 } else if (op.equals("resize")) {
2610 return runTaskResize(pw);
David Stevensee9e2772017-02-09 16:30:27 -08002611 } else if (op.equals("focus")) {
2612 return runTaskFocus(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002613 } else {
2614 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2615 return -1;
2616 }
2617 }
2618
2619 int runTaskLock(PrintWriter pw) throws RemoteException {
2620 String taskIdStr = getNextArgRequired();
2621 if (taskIdStr.equals("stop")) {
Benjamin Franza83859f2017-07-03 16:34:14 +01002622 mInterface.stopSystemLockTaskMode();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002623 } else {
2624 int taskId = Integer.parseInt(taskIdStr);
Winson Chungbb348802017-01-30 12:01:45 -08002625 mInterface.startSystemLockTaskMode(taskId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002626 }
2627 pw.println("Activity manager is " + (mInterface.isInLockTaskMode() ? "" : "not ") +
2628 "in lockTaskMode");
2629 return 0;
2630 }
2631
2632 int runTaskResizeable(PrintWriter pw) throws RemoteException {
2633 final String taskIdStr = getNextArgRequired();
2634 final int taskId = Integer.parseInt(taskIdStr);
2635 final String resizeableStr = getNextArgRequired();
2636 final int resizeableMode = Integer.parseInt(resizeableStr);
2637 mInterface.setTaskResizeable(taskId, resizeableMode);
2638 return 0;
2639 }
2640
2641 int runTaskResize(PrintWriter pw) throws RemoteException {
2642 final String taskIdStr = getNextArgRequired();
2643 final int taskId = Integer.parseInt(taskIdStr);
2644 final Rect bounds = getBounds();
2645 if (bounds == null) {
2646 getErrPrintWriter().println("Error: invalid input bounds");
2647 return -1;
2648 }
2649 taskResize(taskId, bounds, 0, false);
2650 return 0;
2651 }
2652
2653 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
2654 throws RemoteException {
2655 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
2656 mInterface.resizeTask(taskId, bounds, resizeMode);
2657 try {
2658 Thread.sleep(delay_ms);
2659 } catch (InterruptedException e) {
2660 }
2661 }
2662
Dianne Hackborn331084d2016-10-07 17:57:00 -07002663 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
2664 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
2665 throws RemoteException {
2666 int maxMove;
2667 if (movingForward) {
2668 while (maxToTravel > 0
2669 && ((horizontal && taskRect.right < stackRect.right)
2670 ||(!horizontal && taskRect.bottom < stackRect.bottom))) {
2671 if (horizontal) {
2672 maxMove = Math.min(stepSize, stackRect.right - taskRect.right);
2673 maxToTravel -= maxMove;
2674 taskRect.right += maxMove;
2675 taskRect.left += maxMove;
2676 } else {
2677 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom);
2678 maxToTravel -= maxMove;
2679 taskRect.top += maxMove;
2680 taskRect.bottom += maxMove;
2681 }
2682 taskResize(taskId, taskRect, delay_ms, false);
2683 }
2684 } else {
2685 while (maxToTravel < 0
2686 && ((horizontal && taskRect.left > stackRect.left)
2687 ||(!horizontal && taskRect.top > stackRect.top))) {
2688 if (horizontal) {
2689 maxMove = Math.min(stepSize, taskRect.left - stackRect.left);
2690 maxToTravel -= maxMove;
2691 taskRect.right -= maxMove;
2692 taskRect.left -= maxMove;
2693 } else {
2694 maxMove = Math.min(stepSize, taskRect.top - stackRect.top);
2695 maxToTravel -= maxMove;
2696 taskRect.top -= maxMove;
2697 taskRect.bottom -= maxMove;
2698 }
2699 taskResize(taskId, taskRect, delay_ms, false);
2700 }
2701 }
2702 // Return the remaining distance we didn't travel because we reached the target location.
2703 return maxToTravel;
2704 }
2705
2706 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) {
2707 int stepSize = 0;
2708 if (greaterThanTarget && target < current) {
2709 current -= inStepSize;
2710 stepSize = inStepSize;
2711 if (target > current) {
2712 stepSize -= (target - current);
2713 }
2714 }
2715 if (!greaterThanTarget && target > current) {
2716 current += inStepSize;
2717 stepSize = inStepSize;
2718 if (target < current) {
2719 stepSize += (current - target);
2720 }
2721 }
2722 return stepSize;
2723 }
2724
David Stevensee9e2772017-02-09 16:30:27 -08002725 int runTaskFocus(PrintWriter pw) throws RemoteException {
2726 final int taskId = Integer.parseInt(getNextArgRequired());
2727 pw.println("Setting focus to task " + taskId);
2728 mInterface.setFocusedTask(taskId);
2729 return 0;
2730 }
2731
Dianne Hackborn331084d2016-10-07 17:57:00 -07002732 int runWrite(PrintWriter pw) {
2733 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2734 "registerUidObserver()");
Winson Chung3f0e59a2017-10-25 10:19:05 -07002735 mInternal.getRecentTasks().flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002736 pw.println("All tasks persisted.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002737 return 0;
2738 }
2739
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002740 int runAttachAgent(PrintWriter pw) {
2741 // TODO: revisit the permissions required for attaching agents
2742 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2743 "attach-agent");
2744 String process = getNextArgRequired();
2745 String agent = getNextArgRequired();
2746 String opt;
2747 if ((opt = getNextArg()) != null) {
2748 pw.println("Error: Unknown option: " + opt);
2749 return -1;
2750 }
2751 mInternal.attachAgent(process, agent);
2752 return 0;
2753 }
2754
Michael Kwan94438b72016-11-03 15:30:34 -07002755 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
Matthew Ng626e0cc2016-12-07 17:25:53 -08002756 final Resources res = getResources(pw);
2757 if (res == null) {
2758 return -1;
2759 }
Erik Wolsheimer9be3a062017-05-31 14:59:57 -07002760 pw.println(ActivityManager.supportsMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002761 return 0;
2762 }
2763
2764 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException {
2765 final Resources res = getResources(pw);
2766 if (res == null) {
2767 return -1;
2768 }
Erik Wolsheimer9be3a062017-05-31 14:59:57 -07002769 pw.println(ActivityManager.supportsSplitScreenMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002770 return 0;
2771 }
2772
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002773 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
2774 int userid = UserHandle.parseUserArg(getNextArgRequired());
2775 ArrayList<String> packages = new ArrayList<>();
2776 packages.add(getNextArgRequired());
2777 String packageName;
2778 while ((packageName = getNextArg()) != null) {
2779 packages.add(packageName);
2780 }
2781 mInternal.scheduleApplicationInfoChanged(packages, userid);
2782 pw.println("Packages updated with most recent ApplicationInfos.");
2783 return 0;
2784 }
2785
Arthur Hsuf3f3a602017-02-21 14:01:53 -08002786 int runNoHomeScreen(PrintWriter pw) throws RemoteException {
2787 final Resources res = getResources(pw);
2788 if (res == null) {
2789 return -1;
2790 }
2791 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen));
2792 return 0;
2793 }
2794
Jeff Sharkeyfd658132017-05-03 11:38:01 -06002795 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
2796 mInternal.waitForBroadcastIdle(pw);
2797 return 0;
2798 }
2799
Matthew Ng626e0cc2016-12-07 17:25:53 -08002800 private Resources getResources(PrintWriter pw) throws RemoteException {
Michael Kwan94438b72016-11-03 15:30:34 -07002801 // system resources does not contain all the device configuration, construct it manually.
2802 Configuration config = mInterface.getConfiguration();
2803 if (config == null) {
2804 pw.println("Error: Activity manager has no configuration");
Matthew Ng626e0cc2016-12-07 17:25:53 -08002805 return null;
Michael Kwan94438b72016-11-03 15:30:34 -07002806 }
2807
2808 final DisplayMetrics metrics = new DisplayMetrics();
2809 metrics.setToDefaults();
2810
Matthew Ng626e0cc2016-12-07 17:25:53 -08002811 return new Resources(AssetManager.getSystem(), metrics, config);
Michael Kwan94438b72016-11-03 15:30:34 -07002812 }
2813
Dianne Hackborn2e441072015-10-28 18:00:57 -07002814 @Override
2815 public void onHelp() {
2816 PrintWriter pw = getOutPrintWriter();
2817 dumpHelp(pw, mDumping);
2818 }
2819
2820 static void dumpHelp(PrintWriter pw, boolean dumping) {
2821 if (dumping) {
2822 pw.println("Activity manager dump options:");
2823 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
2824 pw.println(" WHAT may be one of:");
2825 pw.println(" a[ctivities]: activity stack state");
2826 pw.println(" r[recents]: recent activities state");
2827 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002828 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002829 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
2830 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
2831 pw.println(" o[om]: out of memory management");
2832 pw.println(" perm[issions]: URI permission grant state");
2833 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
2834 pw.println(" provider [COMP_SPEC]: provider client-side state");
2835 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
2836 pw.println(" as[sociations]: tracked app associations");
Dianne Hackborn0ef403e2017-01-24 18:22:15 -08002837 pw.println(" settings: currently applied config settings");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002838 pw.println(" service [COMP_SPEC]: service client-side state");
2839 pw.println(" package [PACKAGE_NAME]: all state related to given package");
2840 pw.println(" all: dump all activities");
2841 pw.println(" top: dump the top activity");
2842 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
2843 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
2844 pw.println(" a partial substring in a component name, a");
2845 pw.println(" hex object identifier.");
2846 pw.println(" -a: include all available server state.");
2847 pw.println(" -c: include client state.");
2848 pw.println(" -p: limit output to given package.");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002849 pw.println(" --checkin: output checkin format, resetting data.");
2850 pw.println(" --C: output checkin format, not resetting data.");
Steven Timotius4346f0a2017-09-12 11:07:21 -07002851 pw.println(" --proto: output dump in protocol buffer format.");
Felipe Leme42260332018-08-15 08:44:12 -07002852 pw.println(" --autofill: dump just the autofill-related state of an activity");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002853 } else {
2854 pw.println("Activity manager (activity) commands:");
2855 pw.println(" help");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002856 pw.println(" Print this help text.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002857 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002858 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002859 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002860 pw.println(" Start an Activity. Options are:");
2861 pw.println(" -D: enable debugging");
2862 pw.println(" -N: enable native debugging");
2863 pw.println(" -W: wait for launch to complete");
2864 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>");
2865 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2866 pw.println(" between samples (use with --start-profiler)");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002867 pw.println(" --streaming: stream the profiling output to the specified file");
2868 pw.println(" (use with --start-profiler)");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002869 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
Andreas Gampe83085bb2017-06-26 17:54:11 -07002870 pw.println(" --attach-agent <agent>: attach the given agent before binding");
Andreas Gampeab8a63b2018-01-05 13:55:15 -08002871 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002872 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
2873 pw.println(" the top activity will be finished.");
2874 pw.println(" -S: force stop the target app before starting the activity");
2875 pw.println(" --track-allocation: enable tracking of object allocations");
2876 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2877 pw.println(" specified then run as the current user.");
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002878 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into.");
2879 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002880 pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
2881 pw.println(" Start a Service. Options are:");
2882 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2883 pw.println(" specified then run as the current user.");
Jaewan Kim329b35f2017-04-11 11:19:49 +09002884 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
2885 pw.println(" Start a foreground Service. Options are:");
2886 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2887 pw.println(" specified then run as the current user.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002888 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
2889 pw.println(" Stop a Service. Options are:");
2890 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2891 pw.println(" specified then run as the current user.");
2892 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>");
2893 pw.println(" Send a broadcast Intent. Options are:");
2894 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not");
2895 pw.println(" specified then send to all users.");
2896 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002897 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
David Brazdild5d42172018-02-14 19:39:03 +00002898 pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
Dianne Hackborn28824062016-10-18 13:19:20 -07002899 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
2900 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
2901 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
2902 pw.println(" is only one instrumentation. Options are:");
2903 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with");
2904 pw.println(" [-e perf true] to generate raw output for performance measurements.");
2905 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a");
2906 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]].");
2907 pw.println(" -p <FILE>: write profiling data to <FILE>");
Mike Mad2239822017-10-31 12:30:42 -07002908 pw.println(" -m: Write output as protobuf to stdout (machine readable)");
2909 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine");
2910 pw.println(" readable). If path is not specified, default directory and file name will");
2911 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto");
Dianne Hackborn28824062016-10-18 13:19:20 -07002912 pw.println(" -w: wait for instrumentation to finish before returning. Required for");
2913 pw.println(" test runners.");
2914 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
2915 pw.println(" current user if not specified.");
David Brazdild5d42172018-02-14 19:39:03 +00002916 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002917 pw.println(" --no-window-animation: turn off window animations while running.");
2918 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
2919 pw.println(" This assumes that the process supports the selected ABI.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002920 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]");
2921 pw.println(" Trace IPC transactions.");
2922 pw.println(" start: start tracing IPC transactions.");
2923 pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
2924 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
2925 pw.println(" profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002926 pw.println(" [--streaming] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002927 pw.println(" Start and stop profiler on a process. The given <PROCESS> argument");
2928 pw.println(" may be either a process name or pid. Options are:");
2929 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2930 pw.println(" specify user of process to profile; uses current user if not specified.");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002931 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2932 pw.println(" between samples");
2933 pw.println(" --streaming: stream the profiling output to the specified file");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002934 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002935 pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
2936 pw.println(" be either a process name or pid. Options are:");
2937 pw.println(" -n: dump native heap instead of managed heap");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002938 pw.println(" -g: force GC before dumping the heap");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002939 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2940 pw.println(" specify user of process to dump; uses current user if not specified.");
2941 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>");
2942 pw.println(" Set application <PACKAGE> to debug. Options are:");
2943 pw.println(" -w: wait for debugger when application starts");
2944 pw.println(" --persistent: retain this value");
2945 pw.println(" clear-debug-app");
2946 pw.println(" Clear the previously set-debug-app.");
2947 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>");
2948 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or");
2949 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
2950 pw.println(" clear-watch-heap");
2951 pw.println(" Clear the previously set-watch-heap.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002952 pw.println(" bug-report [--progress | --telephony]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002953 pw.println(" Request bug report generation; will launch a notification");
2954 pw.println(" when done to select where it should be delivered. Options are:");
2955 pw.println(" --progress: will launch a notification right away to show its progress.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002956 pw.println(" --telephony: will dump only telephony sections.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002957 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002958 pw.println(" Completely stop the given application package.");
Christopher Tate8aa8fe12017-01-20 17:50:32 -08002959 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>");
2960 pw.println(" Induce a VM crash in the specified package or process");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002961 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
Makoto Onuki6569c362018-02-27 15:52:01 -08002962 pw.println(" Kill all background processes associated with the given application.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002963 pw.println(" kill-all");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002964 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn85e35642017-01-12 15:10:57 -08002965 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
2966 pw.println(" If the given application's uid is in the background and waiting to");
2967 pw.println(" become idle (not allowing background services), do that now.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002968 pw.println(" monitor [--gdb <port>]");
2969 pw.println(" Start monitoring for crashes or ANRs.");
2970 pw.println(" --gdb: start gdbserv on the given port at crash/ANR");
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07002971 pw.println(" watch-uids [--oom <uid>]");
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01002972 pw.println(" Start watching for and reporting uid state changes.");
Dianne Hackborne51505a2017-08-07 17:13:52 -07002973 pw.println(" --oom: specify a uid for which to report detailed change messages.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002974 pw.println(" hang [--allow-restart]");
2975 pw.println(" Hang the system.");
2976 pw.println(" --allow-restart: allow watchdog to perform normal system restart");
2977 pw.println(" restart");
2978 pw.println(" Restart the user-space system.");
2979 pw.println(" idle-maintenance");
2980 pw.println(" Perform idle maintenance now.");
2981 pw.println(" screen-compat [on|off] <PACKAGE>");
2982 pw.println(" Control screen compatibility mode of <PACKAGE>.");
2983 pw.println(" package-importance <PACKAGE>");
2984 pw.println(" Print current importance of <PACKAGE>.");
2985 pw.println(" to-uri [INTENT]");
2986 pw.println(" Print the given Intent specification as a URI.");
2987 pw.println(" to-intent-uri [INTENT]");
2988 pw.println(" Print the given Intent specification as an intent: URI.");
2989 pw.println(" to-app-uri [INTENT]");
2990 pw.println(" Print the given Intent specification as an android-app: URI.");
2991 pw.println(" switch-user <USER_ID>");
2992 pw.println(" Switch to put USER_ID in the foreground, starting");
2993 pw.println(" execution of that user if it is currently stopped.");
2994 pw.println(" get-current-user");
2995 pw.println(" Returns id of the current foreground user.");
2996 pw.println(" start-user <USER_ID>");
2997 pw.println(" Start USER_ID in background if it is currently stopped;");
2998 pw.println(" use switch-user if you want to start the user in foreground");
2999 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]");
3000 pw.println(" Attempt to unlock the given user using the given authorization token.");
3001 pw.println(" stop-user [-w] [-f] <USER_ID>");
3002 pw.println(" Stop execution of USER_ID, not allowing it to run any");
3003 pw.println(" code until a later explicit start or switch to it.");
3004 pw.println(" -w: wait for stop-user to complete.");
3005 pw.println(" -f: force stop even if there are related users that cannot be stopped.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003006 pw.println(" is-user-stopped <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003007 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07003008 pw.println(" get-started-user-state <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003009 pw.println(" Gets the current state of the given started user.");
3010 pw.println(" track-associations");
3011 pw.println(" Enable association tracking.");
3012 pw.println(" untrack-associations");
3013 pw.println(" Disable and clear association tracking.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003014 pw.println(" get-uid-state <UID>");
3015 pw.println(" Gets the process state of an app given its <UID>.");
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07003016 pw.println(" attach-agent <PROCESS> <FILE>");
3017 pw.println(" Attach an agent to the specified <PROCESS>, which may be either a process name or a PID.");
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08003018 pw.println(" get-config [--days N] [--device] [--proto]");
3019 pw.println(" Retrieve the configuration and any recent configurations of the device.");
3020 pw.println(" --days: also return last N days of configurations that have been seen.");
3021 pw.println(" --device: also output global device configuration info.");
3022 pw.println(" --proto: return result as a proto; does not include --days info.");
Michael Kwan94438b72016-11-03 15:30:34 -07003023 pw.println(" supports-multiwindow");
3024 pw.println(" Returns true if the device supports multiwindow.");
Matthew Ng626e0cc2016-12-07 17:25:53 -08003025 pw.println(" supports-split-screen-multi-window");
3026 pw.println(" Returns true if the device supports split screen multiwindow.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003027 pw.println(" suppress-resize-config-changes <true|false>");
3028 pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
3029 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
3030 pw.println(" Sets the inactive state of an app.");
3031 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
3032 pw.println(" Returns the inactive state of an app.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003033 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
Amith Yamasani17fffee2017-09-29 13:17:43 -07003034 pw.println(" Puts an app in the standby bucket.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003035 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
3036 pw.println(" Returns the standby bucket of an app.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003037 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
3038 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003039 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 -07003040 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays.");
3041 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>");
3042 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003043 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
3044 pw.println(" start <DISPLAY_ID> <INTENT>");
3045 pw.println(" Start a new activity on <DISPLAY_ID> using <INTENT>");
Andrii Kulian839def92016-11-02 10:58:58 -07003046 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003047 pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
3048 pw.println(" bottom (false) of <STACK_ID>.");
3049 pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3050 pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.");
3051 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3052 pw.println(" Same as resize, but allow animation.");
3053 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
3054 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
3055 pw.println(" and supplying temporary different task bounds indicated by");
3056 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003057 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3058 pw.println(" Moves the top activity from");
3059 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
3060 pw.println(" bounds of the pinned stack.");
3061 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>");
3062 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
3063 pw.println(" list");
3064 pw.println(" List all of the activity stacks and their sizes.");
Wale Ogunwale68278562017-09-23 17:13:55 -07003065 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
3066 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003067 pw.println(" remove <STACK_ID>");
3068 pw.println(" Remove stack <STACK_ID>.");
3069 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
3070 pw.println(" lock <TASK_ID>");
3071 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run.");
3072 pw.println(" lock stop");
3073 pw.println(" End the current task lock.");
3074 pw.println(" resizeable <TASK_ID> [0|1|2|3]");
3075 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:");
3076 pw.println(" 0: unresizeable");
3077 pw.println(" 1: crop_windows");
3078 pw.println(" 2: resizeable");
3079 pw.println(" 3: resizeable_and_pipable");
3080 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3081 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
3082 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
3083 pw.println(" has the specified bounds.");
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01003084 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
3085 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
3086 pw.println(" without restarting any processes.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003087 pw.println(" write");
3088 pw.println(" Write all pending state to storage.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003089 pw.println();
3090 Intent.printIntentArgsHelp(pw, "");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003091 }
3092 }
3093}