blob: b03628930dd6d82fb847d9cd35b8818d2f3331f3 [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 }
Dianne Hackborn354736e2016-08-22 17:00:05 -0700561 if (result.totalTime >= 0) {
562 pw.println("TotalTime: " + result.totalTime);
563 }
564 pw.println("WaitTime: " + (endTime-startTime));
565 pw.println("Complete");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700566 pw.flush();
Dianne Hackborn354736e2016-08-22 17:00:05 -0700567 }
568 mRepeat--;
569 if (mRepeat > 0) {
570 mInterface.unhandledBack();
571 }
572 } while (mRepeat > 0);
573 return 0;
574 }
575
Christopher Tate7e1368d2017-03-30 17:20:12 -0700576 int runStartService(PrintWriter pw, boolean asForeground) throws RemoteException {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700577 final PrintWriter err = getErrPrintWriter();
578 Intent intent;
579 try {
580 intent = makeIntent(UserHandle.USER_CURRENT);
581 } catch (URISyntaxException e) {
582 throw new RuntimeException(e.getMessage(), e);
583 }
584 if (mUserId == UserHandle.USER_ALL) {
585 err.println("Error: Can't start activity with user 'all'");
586 return -1;
587 }
588 pw.println("Starting service: " + intent);
589 pw.flush();
590 ComponentName cn = mInterface.startService(null, intent, intent.getType(),
Christopher Tate242ba3e92017-04-14 15:07:06 -0700591 asForeground, SHELL_PACKAGE_NAME, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700592 if (cn == null) {
593 err.println("Error: Not found; no service started.");
594 return -1;
595 } else if (cn.getPackageName().equals("!")) {
596 err.println("Error: Requires permission " + cn.getClassName());
597 return -1;
598 } else if (cn.getPackageName().equals("!!")) {
599 err.println("Error: " + cn.getClassName());
600 return -1;
Dianne Hackborn85e35642017-01-12 15:10:57 -0800601 } else if (cn.getPackageName().equals("?")) {
602 err.println("Error: " + cn.getClassName());
603 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700604 }
605 return 0;
606 }
607
608 int runStopService(PrintWriter pw) throws RemoteException {
609 final PrintWriter err = getErrPrintWriter();
610 Intent intent;
611 try {
612 intent = makeIntent(UserHandle.USER_CURRENT);
613 } catch (URISyntaxException e) {
614 throw new RuntimeException(e.getMessage(), e);
615 }
616 if (mUserId == UserHandle.USER_ALL) {
617 err.println("Error: Can't stop activity with user 'all'");
618 return -1;
619 }
620 pw.println("Stopping service: " + intent);
621 pw.flush();
622 int result = mInterface.stopService(null, intent, intent.getType(), mUserId);
623 if (result == 0) {
624 err.println("Service not stopped: was not running.");
625 return -1;
626 } else if (result == 1) {
627 err.println("Service stopped");
628 return -1;
629 } else if (result == -1) {
630 err.println("Error stopping service");
631 return -1;
632 }
633 return 0;
634 }
635
636 final static class IntentReceiver extends IIntentReceiver.Stub {
637 private final PrintWriter mPw;
638 private boolean mFinished = false;
639
640 IntentReceiver(PrintWriter pw) {
641 mPw = pw;
642 }
643
644 @Override
645 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
646 boolean ordered, boolean sticky, int sendingUser) {
647 String line = "Broadcast completed: result=" + resultCode;
648 if (data != null) line = line + ", data=\"" + data + "\"";
649 if (extras != null) line = line + ", extras: " + extras;
650 mPw.println(line);
651 mPw.flush();
652 synchronized (this) {
653 mFinished = true;
654 notifyAll();
655 }
656 }
657
658 public synchronized void waitForFinish() {
659 try {
660 while (!mFinished) wait();
661 } catch (InterruptedException e) {
662 throw new IllegalStateException(e);
663 }
664 }
665 }
666
667 int runSendBroadcast(PrintWriter pw) throws RemoteException {
668 Intent intent;
669 try {
670 intent = makeIntent(UserHandle.USER_CURRENT);
671 } catch (URISyntaxException e) {
672 throw new RuntimeException(e.getMessage(), e);
673 }
Jeff Sharkey6a34e562016-12-21 09:56:00 -0700674 intent.addFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700675 IntentReceiver receiver = new IntentReceiver(pw);
676 String[] requiredPermissions = mReceiverPermission == null ? null
677 : new String[] {mReceiverPermission};
678 pw.println("Broadcasting: " + intent);
679 pw.flush();
680 mInterface.broadcastIntent(null, intent, null, receiver, 0, null, null, requiredPermissions,
681 android.app.AppOpsManager.OP_NONE, null, true, false, mUserId);
682 receiver.waitForFinish();
683 return 0;
684 }
685
Dianne Hackborn331084d2016-10-07 17:57:00 -0700686 int runTraceIpc(PrintWriter pw) throws RemoteException {
687 String op = getNextArgRequired();
688 if (op.equals("start")) {
689 return runTraceIpcStart(pw);
690 } else if (op.equals("stop")) {
691 return runTraceIpcStop(pw);
692 } else {
693 getErrPrintWriter().println("Error: unknown trace ipc command '" + op + "'");
694 return -1;
695 }
696 }
697
698 int runTraceIpcStart(PrintWriter pw) throws RemoteException {
699 pw.println("Starting IPC tracing.");
700 pw.flush();
701 mInterface.startBinderTracking();
702 return 0;
703 }
704
705 int runTraceIpcStop(PrintWriter pw) throws RemoteException {
706 final PrintWriter err = getErrPrintWriter();
707 String opt;
708 String filename = null;
709 while ((opt=getNextOption()) != null) {
710 if (opt.equals("--dump-file")) {
711 filename = getNextArgRequired();
712 } else {
713 err.println("Error: Unknown option: " + opt);
714 return -1;
715 }
716 }
717 if (filename == null) {
718 err.println("Error: Specify filename to dump logs to.");
719 return -1;
720 }
721
722 File file = new File(filename);
723 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700724 ParcelFileDescriptor fd = openFileForSystem(filename, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700725 if (fd == null) {
726 return -1;
727 }
728
729 ;
730 if (!mInterface.stopBinderTrackingAndDump(fd)) {
731 err.println("STOP TRACE FAILED.");
732 return -1;
733 }
734
735 pw.println("Stopped IPC tracing. Dumping logs to: " + filename);
736 return 0;
737 }
738
739 static void removeWallOption() {
740 String props = SystemProperties.get("dalvik.vm.extra-opts");
741 if (props != null && props.contains("-Xprofile:wallclock")) {
742 props = props.replace("-Xprofile:wallclock", "");
743 props = props.trim();
744 SystemProperties.set("dalvik.vm.extra-opts", props);
745 }
746 }
747
748 private int runProfile(PrintWriter pw) throws RemoteException {
749 final PrintWriter err = getErrPrintWriter();
750 String profileFile = null;
751 boolean start = false;
752 boolean wall = false;
753 int userId = UserHandle.USER_CURRENT;
754 int profileType = 0;
755 mSamplingInterval = 0;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800756 mStreaming = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700757
758 String process = null;
759
760 String cmd = getNextArgRequired();
761
762 if ("start".equals(cmd)) {
763 start = true;
764 String opt;
765 while ((opt=getNextOption()) != null) {
766 if (opt.equals("--user")) {
767 userId = UserHandle.parseUserArg(getNextArgRequired());
768 } else if (opt.equals("--wall")) {
769 wall = true;
Shukang Zhou6ffd4f92017-01-25 16:07:57 -0800770 } else if (opt.equals("--streaming")) {
771 mStreaming = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700772 } else if (opt.equals("--sampling")) {
773 mSamplingInterval = Integer.parseInt(getNextArgRequired());
774 } else {
775 err.println("Error: Unknown option: " + opt);
776 return -1;
777 }
778 }
779 process = getNextArgRequired();
780 } else if ("stop".equals(cmd)) {
781 String opt;
782 while ((opt=getNextOption()) != null) {
783 if (opt.equals("--user")) {
784 userId = UserHandle.parseUserArg(getNextArgRequired());
785 } else {
786 err.println("Error: Unknown option: " + opt);
787 return -1;
788 }
789 }
790 process = getNextArg();
791 } else {
792 // Compatibility with old syntax: process is specified first.
793 process = cmd;
794 cmd = getNextArgRequired();
795 if ("start".equals(cmd)) {
796 start = true;
797 } else if (!"stop".equals(cmd)) {
798 throw new IllegalArgumentException("Profile command " + process + " not valid");
799 }
800 }
801
802 if (userId == UserHandle.USER_ALL) {
803 err.println("Error: Can't profile with user 'all'");
804 return -1;
805 }
806
807 ParcelFileDescriptor fd = null;
808 ProfilerInfo profilerInfo = null;
809
810 if (start) {
811 profileFile = getNextArgRequired();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700812 fd = openFileForSystem(profileFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700813 if (fd == null) {
814 return -1;
815 }
Andreas Gampe83085bb2017-06-26 17:54:11 -0700816 profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming,
Andreas Gampeab8a63b2018-01-05 13:55:15 -0800817 null, false);
Dianne Hackborn331084d2016-10-07 17:57:00 -0700818 }
819
820 try {
821 if (wall) {
822 // XXX doesn't work -- this needs to be set before booting.
823 String props = SystemProperties.get("dalvik.vm.extra-opts");
824 if (props == null || !props.contains("-Xprofile:wallclock")) {
825 props = props + " -Xprofile:wallclock";
826 //SystemProperties.set("dalvik.vm.extra-opts", props);
827 }
828 } else if (start) {
829 //removeWallOption();
830 }
831 if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) {
832 wall = false;
833 err.println("PROFILE FAILED on process " + process);
834 return -1;
835 }
836 } finally {
837 if (!wall) {
838 //removeWallOption();
839 }
840 }
841 return 0;
842 }
843
844 int runDumpHeap(PrintWriter pw) throws RemoteException {
845 final PrintWriter err = getErrPrintWriter();
846 boolean managed = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700847 boolean mallocInfo = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700848 int userId = UserHandle.USER_CURRENT;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700849 boolean runGc = false;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700850
851 String opt;
852 while ((opt=getNextOption()) != null) {
853 if (opt.equals("--user")) {
854 userId = UserHandle.parseUserArg(getNextArgRequired());
855 if (userId == UserHandle.USER_ALL) {
856 err.println("Error: Can't dump heap with user 'all'");
857 return -1;
858 }
859 } else if (opt.equals("-n")) {
860 managed = false;
Makoto Onuki4556b7b2017-07-07 14:58:58 -0700861 } else if (opt.equals("-g")) {
862 runGc = true;
Christopher Ferris8d652f82017-04-11 16:29:18 -0700863 } else if (opt.equals("-m")) {
864 managed = false;
865 mallocInfo = true;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700866 } else {
867 err.println("Error: Unknown option: " + opt);
868 return -1;
869 }
870 }
871 String process = getNextArgRequired();
872 String heapFile = getNextArgRequired();
873
874 File file = new File(heapFile);
875 file.delete();
Dianne Hackbornca3872c2017-10-30 14:19:32 -0700876 ParcelFileDescriptor fd = openFileForSystem(heapFile, "w");
Dianne Hackborn331084d2016-10-07 17:57:00 -0700877 if (fd == null) {
878 return -1;
879 }
880
Christopher Ferris8d652f82017-04-11 16:29:18 -0700881 if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd)) {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700882 err.println("HEAP DUMP FAILED on process " + process);
883 return -1;
884 }
885 return 0;
886 }
887
888 int runSetDebugApp(PrintWriter pw) throws RemoteException {
889 boolean wait = false;
890 boolean persistent = false;
891
892 String opt;
893 while ((opt=getNextOption()) != null) {
894 if (opt.equals("-w")) {
895 wait = true;
896 } else if (opt.equals("--persistent")) {
897 persistent = true;
898 } else {
899 getErrPrintWriter().println("Error: Unknown option: " + opt);
900 return -1;
901 }
902 }
903
904 String pkg = getNextArgRequired();
905 mInterface.setDebugApp(pkg, wait, persistent);
906 return 0;
907 }
908
Andreas Gampe5b495d52018-01-22 15:15:54 -0800909 int runSetAgentApp(PrintWriter pw) throws RemoteException {
910 String pkg = getNextArgRequired();
911 String agent = getNextArg();
912 mInterface.setAgentApp(pkg, agent);
913 return 0;
914 }
915
Dianne Hackborn331084d2016-10-07 17:57:00 -0700916 int runClearDebugApp(PrintWriter pw) throws RemoteException {
917 mInterface.setDebugApp(null, false, true);
918 return 0;
919 }
920
921 int runSetWatchHeap(PrintWriter pw) throws RemoteException {
922 String proc = getNextArgRequired();
923 String limit = getNextArgRequired();
924 mInterface.setDumpHeapDebugLimit(proc, 0, Long.parseLong(limit), null);
925 return 0;
926 }
927
928 int runClearWatchHeap(PrintWriter pw) throws RemoteException {
929 String proc = getNextArgRequired();
930 mInterface.setDumpHeapDebugLimit(proc, 0, -1, null);
931 return 0;
932 }
933
934 int runBugReport(PrintWriter pw) throws RemoteException {
935 String opt;
936 int bugreportType = ActivityManager.BUGREPORT_OPTION_FULL;
937 while ((opt=getNextOption()) != null) {
938 if (opt.equals("--progress")) {
939 bugreportType = ActivityManager.BUGREPORT_OPTION_INTERACTIVE;
Felipe Leme9606c3b2017-01-05 14:57:12 -0800940 } else if (opt.equals("--telephony")) {
941 bugreportType = ActivityManager.BUGREPORT_OPTION_TELEPHONY;
Dianne Hackborn331084d2016-10-07 17:57:00 -0700942 } else {
943 getErrPrintWriter().println("Error: Unknown option: " + opt);
944 return -1;
945 }
946 }
947 mInterface.requestBugReport(bugreportType);
948 pw.println("Your lovely bug report is being created; please be patient.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -0800949 return 0;
950 }
951
Dianne Hackborn2e441072015-10-28 18:00:57 -0700952 int runForceStop(PrintWriter pw) throws RemoteException {
953 int userId = UserHandle.USER_ALL;
954
955 String opt;
956 while ((opt = getNextOption()) != null) {
957 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -0800958 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -0700959 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -0700960 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -0700961 return -1;
962 }
963 }
964 mInterface.forceStopPackage(getNextArgRequired(), userId);
965 return 0;
966 }
967
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800968 int runCrash(PrintWriter pw) throws RemoteException {
969 int userId = UserHandle.USER_ALL;
970
971 String opt;
972 while ((opt=getNextOption()) != null) {
973 if (opt.equals("--user")) {
974 userId = UserHandle.parseUserArg(getNextArgRequired());
975 } else {
976 getErrPrintWriter().println("Error: Unknown option: " + opt);
977 return -1;
978 }
979 }
980
981 int pid = -1;
982 String packageName = null;
983 final String arg = getNextArgRequired();
984 // The argument is either a pid or a package name
985 try {
986 pid = Integer.parseInt(arg);
987 } catch (NumberFormatException e) {
988 packageName = arg;
989 }
990 mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash");
991 return 0;
992 }
993
Dianne Hackborn2e441072015-10-28 18:00:57 -0700994 int runKill(PrintWriter pw) throws RemoteException {
995 int userId = UserHandle.USER_ALL;
996
997 String opt;
998 while ((opt=getNextOption()) != null) {
999 if (opt.equals("--user")) {
Dianne Hackborn3cdb56e2015-11-11 12:45:44 -08001000 userId = UserHandle.parseUserArg(getNextArgRequired());
Dianne Hackborn2e441072015-10-28 18:00:57 -07001001 } else {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001002 getErrPrintWriter().println("Error: Unknown option: " + opt);
Dianne Hackborn2e441072015-10-28 18:00:57 -07001003 return -1;
1004 }
1005 }
1006 mInterface.killBackgroundProcesses(getNextArgRequired(), userId);
1007 return 0;
1008 }
1009
1010 int runKillAll(PrintWriter pw) throws RemoteException {
1011 mInterface.killAllBackgroundProcesses();
1012 return 0;
1013 }
1014
Dianne Hackborne07641d2016-11-09 15:07:23 -08001015 int runMakeIdle(PrintWriter pw) throws RemoteException {
1016 int userId = UserHandle.USER_ALL;
1017
1018 String opt;
1019 while ((opt = getNextOption()) != null) {
1020 if (opt.equals("--user")) {
1021 userId = UserHandle.parseUserArg(getNextArgRequired());
1022 } else {
1023 getErrPrintWriter().println("Error: Unknown option: " + opt);
1024 return -1;
1025 }
1026 }
1027 mInterface.makePackageIdle(getNextArgRequired(), userId);
1028 return 0;
1029 }
1030
Dianne Hackborn331084d2016-10-07 17:57:00 -07001031 static final class MyActivityController extends IActivityController.Stub {
1032 final IActivityManager mInterface;
1033 final PrintWriter mPw;
1034 final InputStream mInput;
1035 final String mGdbPort;
1036 final boolean mMonkey;
1037
1038 static final int STATE_NORMAL = 0;
1039 static final int STATE_CRASHED = 1;
1040 static final int STATE_EARLY_ANR = 2;
1041 static final int STATE_ANR = 3;
1042
1043 int mState;
1044
1045 static final int RESULT_DEFAULT = 0;
1046
1047 static final int RESULT_CRASH_DIALOG = 0;
1048 static final int RESULT_CRASH_KILL = 1;
1049
1050 static final int RESULT_EARLY_ANR_CONTINUE = 0;
1051 static final int RESULT_EARLY_ANR_KILL = 1;
1052
1053 static final int RESULT_ANR_DIALOG = 0;
1054 static final int RESULT_ANR_KILL = 1;
1055 static final int RESULT_ANR_WAIT = 1;
1056
1057 int mResult;
1058
1059 Process mGdbProcess;
1060 Thread mGdbThread;
1061 boolean mGotGdbPrint;
1062
1063 MyActivityController(IActivityManager iam, PrintWriter pw, InputStream input,
1064 String gdbPort, boolean monkey) {
1065 mInterface = iam;
1066 mPw = pw;
1067 mInput = input;
1068 mGdbPort = gdbPort;
1069 mMonkey = monkey;
1070 }
1071
1072 @Override
1073 public boolean activityResuming(String pkg) {
1074 synchronized (this) {
1075 mPw.println("** Activity resuming: " + pkg);
1076 mPw.flush();
1077 }
1078 return true;
1079 }
1080
1081 @Override
1082 public boolean activityStarting(Intent intent, String pkg) {
1083 synchronized (this) {
1084 mPw.println("** Activity starting: " + pkg);
1085 mPw.flush();
1086 }
1087 return true;
1088 }
1089
1090 @Override
1091 public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg,
1092 long timeMillis, String stackTrace) {
1093 synchronized (this) {
1094 mPw.println("** ERROR: PROCESS CRASHED");
1095 mPw.println("processName: " + processName);
1096 mPw.println("processPid: " + pid);
1097 mPw.println("shortMsg: " + shortMsg);
1098 mPw.println("longMsg: " + longMsg);
1099 mPw.println("timeMillis: " + timeMillis);
1100 mPw.println("stack:");
1101 mPw.print(stackTrace);
1102 mPw.println("#");
1103 mPw.flush();
1104 int result = waitControllerLocked(pid, STATE_CRASHED);
1105 return result == RESULT_CRASH_KILL ? false : true;
1106 }
1107 }
1108
1109 @Override
1110 public int appEarlyNotResponding(String processName, int pid, String annotation) {
1111 synchronized (this) {
1112 mPw.println("** ERROR: EARLY PROCESS NOT RESPONDING");
1113 mPw.println("processName: " + processName);
1114 mPw.println("processPid: " + pid);
1115 mPw.println("annotation: " + annotation);
1116 mPw.flush();
1117 int result = waitControllerLocked(pid, STATE_EARLY_ANR);
1118 if (result == RESULT_EARLY_ANR_KILL) return -1;
1119 return 0;
1120 }
1121 }
1122
1123 @Override
1124 public int appNotResponding(String processName, int pid, String processStats) {
1125 synchronized (this) {
1126 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1127 mPw.println("processName: " + processName);
1128 mPw.println("processPid: " + pid);
1129 mPw.println("processStats:");
1130 mPw.print(processStats);
1131 mPw.println("#");
1132 mPw.flush();
1133 int result = waitControllerLocked(pid, STATE_ANR);
1134 if (result == RESULT_ANR_KILL) return -1;
1135 if (result == RESULT_ANR_WAIT) return 1;
1136 return 0;
1137 }
1138 }
1139
1140 @Override
1141 public int systemNotResponding(String message) {
1142 synchronized (this) {
1143 mPw.println("** ERROR: PROCESS NOT RESPONDING");
1144 mPw.println("message: " + message);
1145 mPw.println("#");
1146 mPw.println("Allowing system to die.");
1147 mPw.flush();
1148 return -1;
1149 }
1150 }
1151
1152 void killGdbLocked() {
1153 mGotGdbPrint = false;
1154 if (mGdbProcess != null) {
1155 mPw.println("Stopping gdbserver");
1156 mPw.flush();
1157 mGdbProcess.destroy();
1158 mGdbProcess = null;
1159 }
1160 if (mGdbThread != null) {
1161 mGdbThread.interrupt();
1162 mGdbThread = null;
1163 }
1164 }
1165
1166 int waitControllerLocked(int pid, int state) {
1167 if (mGdbPort != null) {
1168 killGdbLocked();
1169
1170 try {
1171 mPw.println("Starting gdbserver on port " + mGdbPort);
1172 mPw.println("Do the following:");
1173 mPw.println(" adb forward tcp:" + mGdbPort + " tcp:" + mGdbPort);
1174 mPw.println(" gdbclient app_process :" + mGdbPort);
1175 mPw.flush();
1176
1177 mGdbProcess = Runtime.getRuntime().exec(new String[] {
1178 "gdbserver", ":" + mGdbPort, "--attach", Integer.toString(pid)
1179 });
1180 final InputStreamReader converter = new InputStreamReader(
1181 mGdbProcess.getInputStream());
1182 mGdbThread = new Thread() {
1183 @Override
1184 public void run() {
1185 BufferedReader in = new BufferedReader(converter);
1186 String line;
1187 int count = 0;
1188 while (true) {
1189 synchronized (MyActivityController.this) {
1190 if (mGdbThread == null) {
1191 return;
1192 }
1193 if (count == 2) {
1194 mGotGdbPrint = true;
1195 MyActivityController.this.notifyAll();
1196 }
1197 }
1198 try {
1199 line = in.readLine();
1200 if (line == null) {
1201 return;
1202 }
1203 mPw.println("GDB: " + line);
1204 mPw.flush();
1205 count++;
1206 } catch (IOException e) {
1207 return;
1208 }
1209 }
1210 }
1211 };
1212 mGdbThread.start();
1213
1214 // Stupid waiting for .5s. Doesn't matter if we end early.
1215 try {
1216 this.wait(500);
1217 } catch (InterruptedException e) {
1218 }
1219
1220 } catch (IOException e) {
1221 mPw.println("Failure starting gdbserver: " + e);
1222 mPw.flush();
1223 killGdbLocked();
1224 }
1225 }
1226 mState = state;
1227 mPw.println("");
1228 printMessageForState();
1229 mPw.flush();
1230
1231 while (mState != STATE_NORMAL) {
1232 try {
1233 wait();
1234 } catch (InterruptedException e) {
1235 }
1236 }
1237
1238 killGdbLocked();
1239
1240 return mResult;
1241 }
1242
1243 void resumeController(int result) {
1244 synchronized (this) {
1245 mState = STATE_NORMAL;
1246 mResult = result;
1247 notifyAll();
1248 }
1249 }
1250
1251 void printMessageForState() {
1252 switch (mState) {
1253 case STATE_NORMAL:
1254 mPw.println("Monitoring activity manager... available commands:");
1255 break;
1256 case STATE_CRASHED:
1257 mPw.println("Waiting after crash... available commands:");
1258 mPw.println("(c)ontinue: show crash dialog");
1259 mPw.println("(k)ill: immediately kill app");
1260 break;
1261 case STATE_EARLY_ANR:
1262 mPw.println("Waiting after early ANR... available commands:");
1263 mPw.println("(c)ontinue: standard ANR processing");
1264 mPw.println("(k)ill: immediately kill app");
1265 break;
1266 case STATE_ANR:
1267 mPw.println("Waiting after ANR... available commands:");
1268 mPw.println("(c)ontinue: show ANR dialog");
1269 mPw.println("(k)ill: immediately kill app");
1270 mPw.println("(w)ait: wait some more");
1271 break;
1272 }
1273 mPw.println("(q)uit: finish monitoring");
1274 }
1275
1276 void run() throws RemoteException {
1277 try {
1278 printMessageForState();
1279 mPw.flush();
1280
1281 mInterface.setActivityController(this, mMonkey);
1282 mState = STATE_NORMAL;
1283
1284 InputStreamReader converter = new InputStreamReader(mInput);
1285 BufferedReader in = new BufferedReader(converter);
1286 String line;
1287
1288 while ((line = in.readLine()) != null) {
1289 boolean addNewline = true;
1290 if (line.length() <= 0) {
1291 addNewline = false;
1292 } else if ("q".equals(line) || "quit".equals(line)) {
1293 resumeController(RESULT_DEFAULT);
1294 break;
1295 } else if (mState == STATE_CRASHED) {
1296 if ("c".equals(line) || "continue".equals(line)) {
1297 resumeController(RESULT_CRASH_DIALOG);
1298 } else if ("k".equals(line) || "kill".equals(line)) {
1299 resumeController(RESULT_CRASH_KILL);
1300 } else {
1301 mPw.println("Invalid command: " + line);
1302 }
1303 } else if (mState == STATE_ANR) {
1304 if ("c".equals(line) || "continue".equals(line)) {
1305 resumeController(RESULT_ANR_DIALOG);
1306 } else if ("k".equals(line) || "kill".equals(line)) {
1307 resumeController(RESULT_ANR_KILL);
1308 } else if ("w".equals(line) || "wait".equals(line)) {
1309 resumeController(RESULT_ANR_WAIT);
1310 } else {
1311 mPw.println("Invalid command: " + line);
1312 }
1313 } else if (mState == STATE_EARLY_ANR) {
1314 if ("c".equals(line) || "continue".equals(line)) {
1315 resumeController(RESULT_EARLY_ANR_CONTINUE);
1316 } else if ("k".equals(line) || "kill".equals(line)) {
1317 resumeController(RESULT_EARLY_ANR_KILL);
1318 } else {
1319 mPw.println("Invalid command: " + line);
1320 }
1321 } else {
1322 mPw.println("Invalid command: " + line);
1323 }
1324
1325 synchronized (this) {
1326 if (addNewline) {
1327 mPw.println("");
1328 }
1329 printMessageForState();
1330 mPw.flush();
1331 }
1332 }
1333
1334 } catch (IOException e) {
1335 e.printStackTrace(mPw);
1336 mPw.flush();
1337 } finally {
1338 mInterface.setActivityController(null, mMonkey);
1339 }
1340 }
1341 }
1342
1343 int runMonitor(PrintWriter pw) throws RemoteException {
1344 String opt;
1345 String gdbPort = null;
1346 boolean monkey = false;
1347 while ((opt=getNextOption()) != null) {
1348 if (opt.equals("--gdb")) {
1349 gdbPort = getNextArgRequired();
1350 } else if (opt.equals("-m")) {
1351 monkey = true;
1352 } else {
1353 getErrPrintWriter().println("Error: Unknown option: " + opt);
1354 return -1;
1355 }
1356 }
1357
1358 MyActivityController controller = new MyActivityController(mInterface, pw,
1359 getRawInputStream(), gdbPort, monkey);
1360 controller.run();
1361 return 0;
1362 }
1363
Dianne Hackborne51505a2017-08-07 17:13:52 -07001364 static final class MyUidObserver extends IUidObserver.Stub
1365 implements ActivityManagerService.OomAdjObserver {
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001366 final IActivityManager mInterface;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001367 final ActivityManagerService mInternal;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001368 final PrintWriter mPw;
1369 final InputStream mInput;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001370 final int mUid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001371
1372 static final int STATE_NORMAL = 0;
1373
1374 int mState;
1375
Dianne Hackborne51505a2017-08-07 17:13:52 -07001376 MyUidObserver(ActivityManagerService service, PrintWriter pw, InputStream input, int uid) {
1377 mInterface = service;
1378 mInternal = service;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001379 mPw = pw;
1380 mInput = input;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001381 mUid = uid;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001382 }
1383
1384 @Override
1385 public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException {
1386 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001387 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1388 try {
1389 mPw.print(uid);
1390 mPw.print(" procstate ");
1391 mPw.print(ProcessList.makeProcStateString(procState));
1392 mPw.print(" seq ");
1393 mPw.println(procStateSeq);
1394 mPw.flush();
1395 } finally {
1396 StrictMode.setThreadPolicy(oldPolicy);
1397 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001398 }
1399 }
1400
1401 @Override
1402 public void onUidGone(int uid, boolean disabled) throws RemoteException {
1403 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001404 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1405 try {
1406 mPw.print(uid);
1407 mPw.print(" gone");
1408 if (disabled) {
1409 mPw.print(" disabled");
1410 }
1411 mPw.println();
1412 mPw.flush();
1413 } finally {
1414 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001415 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001416 }
1417 }
1418
1419 @Override
1420 public void onUidActive(int uid) throws RemoteException {
1421 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001422 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1423 try {
1424 mPw.print(uid);
1425 mPw.println(" active");
1426 mPw.flush();
1427 } finally {
1428 StrictMode.setThreadPolicy(oldPolicy);
1429 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001430 }
1431 }
1432
1433 @Override
1434 public void onUidIdle(int uid, boolean disabled) throws RemoteException {
1435 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001436 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1437 try {
1438 mPw.print(uid);
1439 mPw.print(" idle");
1440 if (disabled) {
1441 mPw.print(" disabled");
1442 }
1443 mPw.println();
1444 mPw.flush();
1445 } finally {
1446 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001447 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001448 }
1449 }
1450
1451 @Override
1452 public void onUidCachedChanged(int uid, boolean cached) throws RemoteException {
1453 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001454 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1455 try {
1456 mPw.print(uid);
1457 mPw.println(cached ? " cached" : " uncached");
1458 mPw.flush();
1459 } finally {
1460 StrictMode.setThreadPolicy(oldPolicy);
1461 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001462 }
1463 }
1464
Dianne Hackborne51505a2017-08-07 17:13:52 -07001465 @Override
1466 public void onOomAdjMessage(String msg) {
1467 synchronized (this) {
Dianne Hackborn5c3296a2017-12-13 17:52:26 -08001468 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
1469 try {
1470 mPw.print("# ");
1471 mPw.println(msg);
1472 mPw.flush();
1473 } finally {
1474 StrictMode.setThreadPolicy(oldPolicy);
1475 }
Dianne Hackborne51505a2017-08-07 17:13:52 -07001476 }
1477 }
1478
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001479 void printMessageForState() {
1480 switch (mState) {
1481 case STATE_NORMAL:
1482 mPw.println("Watching uid states... available commands:");
1483 break;
1484 }
1485 mPw.println("(q)uit: finish watching");
1486 }
1487
1488 void run() throws RemoteException {
1489 try {
1490 printMessageForState();
1491 mPw.flush();
1492
1493 mInterface.registerUidObserver(this, ActivityManager.UID_OBSERVER_ACTIVE
1494 | ActivityManager.UID_OBSERVER_GONE | ActivityManager.UID_OBSERVER_PROCSTATE
1495 | ActivityManager.UID_OBSERVER_IDLE | ActivityManager.UID_OBSERVER_CACHED,
1496 ActivityManager.PROCESS_STATE_UNKNOWN, null);
Dianne Hackborne51505a2017-08-07 17:13:52 -07001497 if (mUid >= 0) {
1498 mInternal.setOomAdjObserver(mUid, this);
1499 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001500 mState = STATE_NORMAL;
1501
1502 InputStreamReader converter = new InputStreamReader(mInput);
1503 BufferedReader in = new BufferedReader(converter);
1504 String line;
1505
1506 while ((line = in.readLine()) != null) {
1507 boolean addNewline = true;
1508 if (line.length() <= 0) {
1509 addNewline = false;
1510 } else if ("q".equals(line) || "quit".equals(line)) {
1511 break;
1512 } else {
1513 mPw.println("Invalid command: " + line);
1514 }
1515
1516 synchronized (this) {
1517 if (addNewline) {
1518 mPw.println("");
1519 }
1520 printMessageForState();
1521 mPw.flush();
1522 }
1523 }
1524
1525 } catch (IOException e) {
1526 e.printStackTrace(mPw);
1527 mPw.flush();
1528 } finally {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001529 if (mUid >= 0) {
1530 mInternal.clearOomAdjObserver();
1531 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001532 mInterface.unregisterUidObserver(this);
1533 }
1534 }
1535 }
1536
1537 int runWatchUids(PrintWriter pw) throws RemoteException {
1538 String opt;
Dianne Hackborne51505a2017-08-07 17:13:52 -07001539 int uid = -1;
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001540 while ((opt=getNextOption()) != null) {
Dianne Hackborne51505a2017-08-07 17:13:52 -07001541 if (opt.equals("--oom")) {
1542 uid = Integer.parseInt(getNextArgRequired());
1543 } else {
1544 getErrPrintWriter().println("Error: Unknown option: " + opt);
1545 return -1;
1546
1547 }
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001548 }
1549
Dianne Hackborne51505a2017-08-07 17:13:52 -07001550 MyUidObserver controller = new MyUidObserver(mInternal, pw, getRawInputStream(), uid);
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01001551 controller.run();
1552 return 0;
1553 }
1554
Dianne Hackborn331084d2016-10-07 17:57:00 -07001555 int runHang(PrintWriter pw) throws RemoteException {
1556 String opt;
1557 boolean allowRestart = false;
1558 while ((opt=getNextOption()) != null) {
1559 if (opt.equals("--allow-restart")) {
1560 allowRestart = true;
1561 } else {
1562 getErrPrintWriter().println("Error: Unknown option: " + opt);
1563 return -1;
1564 }
1565 }
1566
1567 pw.println("Hanging the system...");
1568 pw.flush();
1569 mInterface.hang(new Binder(), allowRestart);
1570 return 0;
1571 }
1572
1573 int runRestart(PrintWriter pw) throws RemoteException {
1574 String opt;
1575 while ((opt=getNextOption()) != null) {
1576 getErrPrintWriter().println("Error: Unknown option: " + opt);
1577 return -1;
1578 }
1579
1580 pw.println("Restart the system...");
1581 pw.flush();
1582 mInterface.restart();
1583 return 0;
1584 }
1585
1586 int runIdleMaintenance(PrintWriter pw) throws RemoteException {
1587 String opt;
1588 while ((opt=getNextOption()) != null) {
1589 getErrPrintWriter().println("Error: Unknown option: " + opt);
1590 return -1;
1591 }
1592
1593 pw.println("Performing idle maintenance...");
1594 mInterface.sendIdleJobTrigger();
1595 return 0;
1596 }
1597
1598 int runScreenCompat(PrintWriter pw) throws RemoteException {
1599 String mode = getNextArgRequired();
1600 boolean enabled;
1601 if ("on".equals(mode)) {
1602 enabled = true;
1603 } else if ("off".equals(mode)) {
1604 enabled = false;
1605 } else {
1606 getErrPrintWriter().println("Error: enabled mode must be 'on' or 'off' at " + mode);
1607 return -1;
1608 }
1609
1610 String packageName = getNextArgRequired();
1611 do {
1612 try {
1613 mInterface.setPackageScreenCompatMode(packageName, enabled
1614 ? ActivityManager.COMPAT_MODE_ENABLED
1615 : ActivityManager.COMPAT_MODE_DISABLED);
1616 } catch (RemoteException e) {
1617 }
1618 packageName = getNextArg();
1619 } while (packageName != null);
1620 return 0;
1621 }
1622
1623 int runPackageImportance(PrintWriter pw) throws RemoteException {
1624 String packageName = getNextArgRequired();
1625 int procState = mInterface.getPackageProcessState(packageName, "com.android.shell");
1626 pw.println(ActivityManager.RunningAppProcessInfo.procStateToImportance(procState));
1627 return 0;
1628 }
1629
1630 int runToUri(PrintWriter pw, int flags) throws RemoteException {
1631 Intent intent;
1632 try {
1633 intent = makeIntent(UserHandle.USER_CURRENT);
1634 } catch (URISyntaxException e) {
1635 throw new RuntimeException(e.getMessage(), e);
1636 }
1637 pw.println(intent.toUri(flags));
1638 return 0;
1639 }
1640
1641 int runSwitchUser(PrintWriter pw) throws RemoteException {
Alex Chau5c0df232018-02-22 15:57:17 +08001642 UserManager userManager = mInternal.mContext.getSystemService(UserManager.class);
1643 if (!userManager.canSwitchUsers()) {
1644 getErrPrintWriter().println("Error: disallowed switching user");
1645 return -1;
1646 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001647 String user = getNextArgRequired();
1648 mInterface.switchUser(Integer.parseInt(user));
1649 return 0;
1650 }
1651
1652 int runGetCurrentUser(PrintWriter pw) throws RemoteException {
1653 UserInfo currentUser = Preconditions.checkNotNull(mInterface.getCurrentUser(),
1654 "Current user not set");
1655 pw.println(currentUser.id);
1656 return 0;
1657 }
1658
1659 int runStartUser(PrintWriter pw) throws RemoteException {
1660 String user = getNextArgRequired();
1661 boolean success = mInterface.startUserInBackground(Integer.parseInt(user));
1662 if (success) {
1663 pw.println("Success: user started");
1664 } else {
1665 getErrPrintWriter().println("Error: could not start user");
1666 }
1667 return 0;
1668 }
1669
1670 private static byte[] argToBytes(String arg) {
1671 if (arg.equals("!")) {
1672 return null;
1673 } else {
1674 return HexDump.hexStringToByteArray(arg);
1675 }
1676 }
1677
1678 int runUnlockUser(PrintWriter pw) throws RemoteException {
1679 int userId = Integer.parseInt(getNextArgRequired());
1680 byte[] token = argToBytes(getNextArgRequired());
1681 byte[] secret = argToBytes(getNextArgRequired());
1682 boolean success = mInterface.unlockUser(userId, token, secret, null);
1683 if (success) {
1684 pw.println("Success: user unlocked");
1685 } else {
1686 getErrPrintWriter().println("Error: could not unlock user");
1687 }
1688 return 0;
1689 }
1690
1691 static final class StopUserCallback extends IStopUserCallback.Stub {
1692 private boolean mFinished = false;
1693
1694 public synchronized void waitForFinish() {
1695 try {
1696 while (!mFinished) wait();
1697 } catch (InterruptedException e) {
1698 throw new IllegalStateException(e);
1699 }
1700 }
1701
1702 @Override
1703 public synchronized void userStopped(int userId) {
1704 mFinished = true;
1705 notifyAll();
1706 }
1707
1708 @Override
1709 public synchronized void userStopAborted(int userId) {
1710 mFinished = true;
1711 notifyAll();
1712 }
1713 }
1714
1715 int runStopUser(PrintWriter pw) throws RemoteException {
1716 boolean wait = false;
1717 boolean force = false;
1718 String opt;
1719 while ((opt = getNextOption()) != null) {
1720 if ("-w".equals(opt)) {
1721 wait = true;
1722 } else if ("-f".equals(opt)) {
1723 force = true;
1724 } else {
1725 getErrPrintWriter().println("Error: unknown option: " + opt);
1726 return -1;
1727 }
1728 }
1729 int user = Integer.parseInt(getNextArgRequired());
1730 StopUserCallback callback = wait ? new StopUserCallback() : null;
1731
1732 int res = mInterface.stopUser(user, force, callback);
1733 if (res != ActivityManager.USER_OP_SUCCESS) {
1734 String txt = "";
1735 switch (res) {
1736 case ActivityManager.USER_OP_IS_CURRENT:
1737 txt = " (Can't stop current user)";
1738 break;
1739 case ActivityManager.USER_OP_UNKNOWN_USER:
1740 txt = " (Unknown user " + user + ")";
1741 break;
1742 case ActivityManager.USER_OP_ERROR_IS_SYSTEM:
1743 txt = " (System user cannot be stopped)";
1744 break;
1745 case ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP:
1746 txt = " (Can't stop user " + user
1747 + " - one of its related users can't be stopped)";
1748 break;
1749 }
1750 getErrPrintWriter().println("Switch failed: " + res + txt);
1751 return -1;
1752 } else if (callback != null) {
1753 callback.waitForFinish();
1754 }
1755 return 0;
1756 }
1757
1758 int runIsUserStopped(PrintWriter pw) {
1759 int userId = UserHandle.parseUserArg(getNextArgRequired());
1760 boolean stopped = mInternal.isUserStopped(userId);
1761 pw.println(stopped);
1762 return 0;
1763 }
1764
1765 int runGetStartedUserState(PrintWriter pw) throws RemoteException {
1766 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1767 "runGetStartedUserState()");
1768 final int userId = Integer.parseInt(getNextArgRequired());
1769 try {
1770 pw.println(mInternal.getStartedUserState(userId));
1771 } catch (NullPointerException e) {
1772 pw.println("User is not started: " + userId);
1773 }
Dianne Hackborn2e441072015-10-28 18:00:57 -07001774 return 0;
1775 }
1776
1777 int runTrackAssociations(PrintWriter pw) {
1778 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1779 "registerUidObserver()");
1780 synchronized (mInternal) {
1781 if (!mInternal.mTrackingAssociations) {
1782 mInternal.mTrackingAssociations = true;
1783 pw.println("Association tracking started.");
1784 } else {
1785 pw.println("Association tracking already enabled.");
1786 }
1787 }
1788 return 0;
1789 }
1790
1791 int runUntrackAssociations(PrintWriter pw) {
1792 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
1793 "registerUidObserver()");
1794 synchronized (mInternal) {
1795 if (mInternal.mTrackingAssociations) {
1796 mInternal.mTrackingAssociations = false;
1797 mInternal.mAssociations.clear();
1798 pw.println("Association tracking stopped.");
1799 } else {
1800 pw.println("Association tracking not running.");
1801 }
1802 }
1803 return 0;
1804 }
1805
Felipe Leme2f1b2272016-03-25 16:15:02 -07001806 int getUidState(PrintWriter pw) throws RemoteException {
1807 mInternal.enforceCallingPermission(android.Manifest.permission.DUMP,
1808 "getUidState()");
1809 int state = mInternal.getUidState(Integer.parseInt(getNextArgRequired()));
1810 pw.print(state);
1811 pw.print(" (");
1812 pw.printf(DebugUtils.valueToString(ActivityManager.class, "PROCESS_STATE_", state));
1813 pw.println(")");
1814 return 0;
1815 }
1816
Dianne Hackborn331084d2016-10-07 17:57:00 -07001817 private List<Configuration> getRecentConfigurations(int days) {
1818 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
1819 Context.USAGE_STATS_SERVICE));
1820 final long now = System.currentTimeMillis();
1821 final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
Sudheer Shanka28537b62016-09-07 11:12:31 -07001822 try {
Dianne Hackborn331084d2016-10-07 17:57:00 -07001823 @SuppressWarnings("unchecked")
1824 ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
1825 UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
1826 if (configStatsSlice == null) {
1827 return Collections.emptyList();
1828 }
1829
1830 final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
1831 final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
1832 final int configStatsListSize = configStatsList.size();
1833 for (int i = 0; i < configStatsListSize; i++) {
1834 final ConfigurationStats stats = configStatsList.get(i);
1835 final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
1836 if (indexOfKey < 0) {
1837 recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
1838 } else {
1839 recentConfigs.setValueAt(indexOfKey,
1840 recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
1841 }
1842 }
1843
1844 final Comparator<Configuration> comparator = new Comparator<Configuration>() {
1845 @Override
1846 public int compare(Configuration a, Configuration b) {
1847 return recentConfigs.get(b).compareTo(recentConfigs.get(a));
1848 }
1849 };
1850
1851 ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
1852 configs.addAll(recentConfigs.keySet());
1853 Collections.sort(configs, comparator);
1854 return configs;
1855
1856 } catch (RemoteException e) {
1857 return Collections.emptyList();
Sudheer Shanka28537b62016-09-07 11:12:31 -07001858 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07001859 }
1860
Dianne Hackborn337e01a2018-02-27 17:16:37 -08001861 /**
1862 * Adds all supported GL extensions for a provided EGLConfig to a set by creating an EGLContext
1863 * and EGLSurface and querying extensions.
1864 *
1865 * @param egl An EGL API object
1866 * @param display An EGLDisplay to create a context and surface with
1867 * @param config The EGLConfig to get the extensions for
1868 * @param surfaceSize eglCreatePbufferSurface generic parameters
1869 * @param contextAttribs eglCreateContext generic parameters
1870 * @param glExtensions A Set<String> to add GL extensions to
1871 */
1872 private static void addExtensionsForConfig(
1873 EGL10 egl,
1874 EGLDisplay display,
1875 EGLConfig config,
1876 int[] surfaceSize,
1877 int[] contextAttribs,
1878 Set<String> glExtensions) {
1879 // Create a context.
1880 EGLContext context =
1881 egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, contextAttribs);
1882 // No-op if we can't create a context.
1883 if (context == EGL10.EGL_NO_CONTEXT) {
1884 return;
1885 }
1886
1887 // Create a surface.
1888 EGLSurface surface = egl.eglCreatePbufferSurface(display, config, surfaceSize);
1889 if (surface == EGL10.EGL_NO_SURFACE) {
1890 egl.eglDestroyContext(display, context);
1891 return;
1892 }
1893
1894 // Update the current surface and context.
1895 egl.eglMakeCurrent(display, surface, surface, context);
1896
1897 // Get the list of extensions.
1898 String extensionList = GLES10.glGetString(GLES10.GL_EXTENSIONS);
1899 if (!TextUtils.isEmpty(extensionList)) {
1900 // The list of extensions comes from the driver separated by spaces.
1901 // Split them apart and add them into a Set for deduping purposes.
1902 for (String extension : extensionList.split(" ")) {
1903 glExtensions.add(extension);
1904 }
1905 }
1906
1907 // Tear down the context and surface for this config.
1908 egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
1909 egl.eglDestroySurface(display, surface);
1910 egl.eglDestroyContext(display, context);
1911 }
1912
1913
1914 Set<String> getGlExtensionsFromDriver() {
1915 Set<String> glExtensions = new HashSet<>();
1916
1917 // Get the EGL implementation.
1918 EGL10 egl = (EGL10) EGLContext.getEGL();
1919 if (egl == null) {
1920 getErrPrintWriter().println("Warning: couldn't get EGL");
1921 return glExtensions;
1922 }
1923
1924 // Get the default display and initialize it.
1925 EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
1926 int[] version = new int[2];
1927 egl.eglInitialize(display, version);
1928
1929 // Call getConfigs() in order to find out how many there are.
1930 int[] numConfigs = new int[1];
1931 if (!egl.eglGetConfigs(display, null, 0, numConfigs)) {
1932 getErrPrintWriter().println("Warning: couldn't get EGL config count");
1933 return glExtensions;
1934 }
1935
1936 // Allocate space for all configs and ask again.
1937 EGLConfig[] configs = new EGLConfig[numConfigs[0]];
1938 if (!egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
1939 getErrPrintWriter().println("Warning: couldn't get EGL configs");
1940 return glExtensions;
1941 }
1942
1943 // Allocate surface size parameters outside of the main loop to cut down
1944 // on GC thrashing. 1x1 is enough since we are only using it to get at
1945 // the list of extensions.
1946 int[] surfaceSize =
1947 new int[] {
1948 EGL10.EGL_WIDTH, 1,
1949 EGL10.EGL_HEIGHT, 1,
1950 EGL10.EGL_NONE
1951 };
1952
1953 // For when we need to create a GLES2.0 context.
1954 final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
1955 int[] gles2 = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
1956
1957 // For getting return values from eglGetConfigAttrib
1958 int[] attrib = new int[1];
1959
1960 for (int i = 0; i < numConfigs[0]; i++) {
1961 // Get caveat for this config in order to skip slow (i.e. software) configs.
1962 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_CONFIG_CAVEAT, attrib);
1963 if (attrib[0] == EGL10.EGL_SLOW_CONFIG) {
1964 continue;
1965 }
1966
1967 // If the config does not support pbuffers we cannot do an eglMakeCurrent
1968 // on it in addExtensionsForConfig(), so skip it here. Attempting to make
1969 // it current with a pbuffer will result in an EGL_BAD_MATCH error
1970 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_SURFACE_TYPE, attrib);
1971 if ((attrib[0] & EGL10.EGL_PBUFFER_BIT) == 0) {
1972 continue;
1973 }
1974
1975 final int EGL_OPENGL_ES_BIT = 0x0001;
1976 final int EGL_OPENGL_ES2_BIT = 0x0004;
1977 egl.eglGetConfigAttrib(display, configs[i], EGL10.EGL_RENDERABLE_TYPE, attrib);
1978 if ((attrib[0] & EGL_OPENGL_ES_BIT) != 0) {
1979 addExtensionsForConfig(egl, display, configs[i], surfaceSize, null, glExtensions);
1980 }
1981 if ((attrib[0] & EGL_OPENGL_ES2_BIT) != 0) {
1982 addExtensionsForConfig(egl, display, configs[i], surfaceSize, gles2, glExtensions);
1983 }
1984 }
1985
1986 // Release all EGL resources.
1987 egl.eglTerminate(display);
1988
1989 return glExtensions;
1990 }
1991
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08001992 private void writeDeviceConfig(ProtoOutputStream protoOutputStream, long fieldId,
1993 PrintWriter pw, Configuration config, DisplayManager dm) {
1994 Point stableSize = dm.getStableDisplaySize();
1995 long token = -1;
1996 if (protoOutputStream != null) {
1997 token = protoOutputStream.start(fieldId);
1998 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_WIDTH_PX, stableSize.x);
1999 protoOutputStream.write(DeviceConfigurationProto.STABLE_SCREEN_HEIGHT_PX, stableSize.y);
2000 protoOutputStream.write(DeviceConfigurationProto.STABLE_DENSITY_DPI,
2001 DisplayMetrics.DENSITY_DEVICE_STABLE);
2002 }
2003 if (pw != null) {
2004 pw.print("stable-width-px: "); pw.println(stableSize.x);
2005 pw.print("stable-height-px: "); pw.println(stableSize.y);
2006 pw.print("stable-density-dpi: "); pw.println(DisplayMetrics.DENSITY_DEVICE_STABLE);
2007 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002008
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002009 MemInfoReader memreader = new MemInfoReader();
2010 memreader.readMemInfo();
2011 KeyguardManager kgm = mInternal.mContext.getSystemService(KeyguardManager.class);
2012 if (protoOutputStream != null) {
2013 protoOutputStream.write(DeviceConfigurationProto.TOTAL_RAM, memreader.getTotalSize());
2014 protoOutputStream.write(DeviceConfigurationProto.LOW_RAM,
2015 ActivityManager.isLowRamDeviceStatic());
2016 protoOutputStream.write(DeviceConfigurationProto.MAX_CORES,
2017 Runtime.getRuntime().availableProcessors());
2018 protoOutputStream.write(DeviceConfigurationProto.HAS_SECURE_SCREEN_LOCK,
2019 kgm.isDeviceSecure());
2020 }
2021 if (pw != null) {
2022 pw.print("total-ram: "); pw.println(memreader.getTotalSize());
2023 pw.print("low-ram: "); pw.println(ActivityManager.isLowRamDeviceStatic());
2024 pw.print("max-cores: "); pw.println(Runtime.getRuntime().availableProcessors());
2025 pw.print("has-secure-screen-lock: "); pw.println(kgm.isDeviceSecure());
2026 }
2027
2028 ConfigurationInfo configInfo = mInternal.getDeviceConfigurationInfo();
2029 if (configInfo.reqGlEsVersion != ConfigurationInfo.GL_ES_VERSION_UNDEFINED) {
2030 if (protoOutputStream != null) {
2031 protoOutputStream.write(DeviceConfigurationProto.OPENGL_VERSION,
2032 configInfo.reqGlEsVersion);
2033 }
2034 if (pw != null) {
2035 pw.print("opengl-version: 0x");
2036 pw.println(Integer.toHexString(configInfo.reqGlEsVersion));
2037 }
2038 }
2039
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002040 Set<String> glExtensionsSet = getGlExtensionsFromDriver();
2041 String[] glExtensions = new String[glExtensionsSet.size()];
2042 glExtensions = glExtensionsSet.toArray(glExtensions);
2043 Arrays.sort(glExtensions);
2044 for (int i = 0; i < glExtensions.length; i++) {
2045 if (protoOutputStream != null) {
2046 protoOutputStream.write(DeviceConfigurationProto.OPENGL_EXTENSIONS,
2047 glExtensions[i]);
2048 }
2049 if (pw != null) {
2050 pw.print("opengl-extensions: "); pw.println(glExtensions[i]);
2051 }
2052
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002053 }
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002054
2055 PackageManager pm = mInternal.mContext.getPackageManager();
2056 List<SharedLibraryInfo> slibs = pm.getSharedLibraries(0);
Dianne Hackborn337e01a2018-02-27 17:16:37 -08002057 Collections.sort(slibs, Comparator.comparing(SharedLibraryInfo::getName));
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002058 for (int i = 0; i < slibs.size(); i++) {
2059 if (protoOutputStream != null) {
2060 protoOutputStream.write(DeviceConfigurationProto.SHARED_LIBRARIES,
2061 slibs.get(i).getName());
2062 }
2063 if (pw != null) {
2064 pw.print("shared-libraries: "); pw.println(slibs.get(i).getName());
2065 }
2066 }
2067
2068 FeatureInfo[] features = pm.getSystemAvailableFeatures();
weijuncheng12030002018-10-30 14:07:53 +08002069 Arrays.sort(features, (o1, o2) -> {
2070 if (o1.name == o2.name) return 0;
2071 if (o1.name == null) return -1;
2072 if (o2.name == null) return 1;
2073 return o1.name.compareTo(o2.name);
2074 });
2075
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002076 for (int i = 0; i < features.length; i++) {
2077 if (features[i].name != null) {
2078 if (protoOutputStream != null) {
2079 protoOutputStream.write(DeviceConfigurationProto.FEATURES, features[i].name);
2080 }
2081 if (pw != null) {
2082 pw.print("features: "); pw.println(features[i].name);
2083 }
2084 }
2085 }
2086
2087 if (protoOutputStream != null) {
2088 protoOutputStream.end(token);
2089 }
2090 }
2091
2092 int runGetConfig(PrintWriter pw) throws RemoteException {
2093 int days = -1;
2094 boolean asProto = false;
2095 boolean inclDevice = false;
2096
2097 String opt;
2098 while ((opt=getNextOption()) != null) {
2099 if (opt.equals("--days")) {
2100 days = Integer.parseInt(getNextArgRequired());
2101 if (days <= 0) {
2102 throw new IllegalArgumentException("--days must be a positive integer");
2103 }
2104 } else if (opt.equals("--proto")) {
2105 asProto = true;
2106 } else if (opt.equals("--device")) {
2107 inclDevice = true;
2108 } else {
2109 getErrPrintWriter().println("Error: Unknown option: " + opt);
2110 return -1;
Dianne Hackborn331084d2016-10-07 17:57:00 -07002111 }
2112 }
2113
2114 Configuration config = mInterface.getConfiguration();
2115 if (config == null) {
2116 getErrPrintWriter().println("Activity manager has no configuration");
2117 return -1;
2118 }
2119
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002120 DisplayManager dm = mInternal.mContext.getSystemService(DisplayManager.class);
2121 Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
2122 DisplayMetrics metrics = new DisplayMetrics();
2123 display.getMetrics(metrics);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002124
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002125 if (asProto) {
2126 final ProtoOutputStream proto = new ProtoOutputStream(getOutFileDescriptor());
2127 config.writeResConfigToProto(proto, GlobalConfigurationProto.RESOURCES, metrics);
2128 if (inclDevice) {
2129 writeDeviceConfig(proto, GlobalConfigurationProto.DEVICE, null, config, dm);
2130 }
2131 proto.flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002132
Dianne Hackbornbf5ba6b2018-02-20 10:31:02 -08002133 } else {
2134 pw.println("config: " + Configuration.resourceQualifierString(config, metrics));
2135 pw.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
2136 if (inclDevice) {
2137 writeDeviceConfig(null, -1, pw, config, dm);
2138 }
2139
2140 if (days >= 0) {
2141 final List<Configuration> recentConfigs = getRecentConfigurations(days);
2142 final int recentConfigSize = recentConfigs.size();
2143 if (recentConfigSize > 0) {
2144 pw.println("recentConfigs:");
2145 for (int i = 0; i < recentConfigSize; i++) {
2146 pw.println(" config: " + Configuration.resourceQualifierString(
2147 recentConfigs.get(i)));
2148 }
2149 }
2150 }
2151
Dianne Hackborn331084d2016-10-07 17:57:00 -07002152 }
2153 return 0;
2154 }
2155
2156 int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
2157 boolean suppress = Boolean.valueOf(getNextArgRequired());
2158 mInterface.suppressResizeConfigChanges(suppress);
2159 return 0;
2160 }
2161
2162 int runSetInactive(PrintWriter pw) throws RemoteException {
2163 int userId = UserHandle.USER_CURRENT;
2164
2165 String opt;
2166 while ((opt=getNextOption()) != null) {
2167 if (opt.equals("--user")) {
2168 userId = UserHandle.parseUserArg(getNextArgRequired());
2169 } else {
2170 getErrPrintWriter().println("Error: Unknown option: " + opt);
2171 return -1;
2172 }
2173 }
2174 String packageName = getNextArgRequired();
2175 String value = getNextArgRequired();
2176
2177 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2178 Context.USAGE_STATS_SERVICE));
2179 usm.setAppInactive(packageName, Boolean.parseBoolean(value), userId);
2180 return 0;
2181 }
2182
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002183 private int bucketNameToBucketValue(String name) {
2184 String lower = name.toLowerCase();
2185 if (lower.startsWith("ac")) {
2186 return UsageStatsManager.STANDBY_BUCKET_ACTIVE;
2187 } else if (lower.startsWith("wo")) {
2188 return UsageStatsManager.STANDBY_BUCKET_WORKING_SET;
2189 } else if (lower.startsWith("fr")) {
2190 return UsageStatsManager.STANDBY_BUCKET_FREQUENT;
2191 } else if (lower.startsWith("ra")) {
2192 return UsageStatsManager.STANDBY_BUCKET_RARE;
2193 } else if (lower.startsWith("ne")) {
2194 return UsageStatsManager.STANDBY_BUCKET_NEVER;
2195 } else {
2196 try {
2197 int bucket = Integer.parseInt(lower);
2198 return bucket;
2199 } catch (NumberFormatException nfe) {
2200 getErrPrintWriter().println("Error: Unknown bucket: " + name);
2201 }
2202 }
2203 return -1;
2204 }
2205
Amith Yamasani17fffee2017-09-29 13:17:43 -07002206 int runSetStandbyBucket(PrintWriter pw) throws RemoteException {
2207 int userId = UserHandle.USER_CURRENT;
2208
2209 String opt;
2210 while ((opt=getNextOption()) != null) {
2211 if (opt.equals("--user")) {
2212 userId = UserHandle.parseUserArg(getNextArgRequired());
2213 } else {
2214 getErrPrintWriter().println("Error: Unknown option: " + opt);
2215 return -1;
2216 }
2217 }
2218 String packageName = getNextArgRequired();
2219 String value = getNextArgRequired();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002220 int bucket = bucketNameToBucketValue(value);
2221 if (bucket < 0) return -1;
Amith Yamasanie8789312017-12-10 14:34:26 -08002222 boolean multiple = peekNextArg() != null;
2223
Amith Yamasani17fffee2017-09-29 13:17:43 -07002224
2225 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2226 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002227 if (!multiple) {
2228 usm.setAppStandbyBucket(packageName, bucketNameToBucketValue(value), userId);
2229 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002230 ArrayList<AppStandbyInfo> bucketInfoList = new ArrayList<>();
2231 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002232 while ((packageName = getNextArg()) != null) {
2233 value = getNextArgRequired();
2234 bucket = bucketNameToBucketValue(value);
2235 if (bucket < 0) continue;
Suprabh Shukla868bde22018-02-20 20:59:52 -08002236 bucketInfoList.add(new AppStandbyInfo(packageName, bucket));
Amith Yamasanie8789312017-12-10 14:34:26 -08002237 }
Suprabh Shukla868bde22018-02-20 20:59:52 -08002238 ParceledListSlice<AppStandbyInfo> slice = new ParceledListSlice<>(bucketInfoList);
2239 usm.setAppStandbyBuckets(slice, userId);
Amith Yamasanie8789312017-12-10 14:34:26 -08002240 }
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002241 return 0;
2242 }
2243
2244 int runGetStandbyBucket(PrintWriter pw) throws RemoteException {
2245 int userId = UserHandle.USER_CURRENT;
2246
2247 String opt;
2248 while ((opt=getNextOption()) != null) {
2249 if (opt.equals("--user")) {
2250 userId = UserHandle.parseUserArg(getNextArgRequired());
2251 } else {
2252 getErrPrintWriter().println("Error: Unknown option: " + opt);
2253 return -1;
2254 }
2255 }
Amith Yamasanie8789312017-12-10 14:34:26 -08002256 String packageName = getNextArg();
Amith Yamasaniafbccb72017-11-27 10:44:24 -08002257
2258 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2259 Context.USAGE_STATS_SERVICE));
Amith Yamasanie8789312017-12-10 14:34:26 -08002260 if (packageName != null) {
2261 int bucket = usm.getAppStandbyBucket(packageName, null, userId);
2262 pw.println(bucket);
2263 } else {
Suprabh Shukla868bde22018-02-20 20:59:52 -08002264 ParceledListSlice<AppStandbyInfo> buckets = usm.getAppStandbyBuckets(
Amith Yamasanie8789312017-12-10 14:34:26 -08002265 SHELL_PACKAGE_NAME, userId);
Suprabh Shukla868bde22018-02-20 20:59:52 -08002266 for (AppStandbyInfo bucketInfo : buckets.getList()) {
2267 pw.print(bucketInfo.mPackageName); pw.print(": ");
2268 pw.println(bucketInfo.mStandbyBucket);
Amith Yamasanie8789312017-12-10 14:34:26 -08002269 }
2270 }
Amith Yamasani17fffee2017-09-29 13:17:43 -07002271 return 0;
2272 }
2273
Dianne Hackborn331084d2016-10-07 17:57:00 -07002274 int runGetInactive(PrintWriter pw) throws RemoteException {
2275 int userId = UserHandle.USER_CURRENT;
2276
2277 String opt;
2278 while ((opt=getNextOption()) != null) {
2279 if (opt.equals("--user")) {
2280 userId = UserHandle.parseUserArg(getNextArgRequired());
2281 } else {
2282 getErrPrintWriter().println("Error: Unknown option: " + opt);
2283 return -1;
2284 }
2285 }
2286 String packageName = getNextArgRequired();
2287
2288 IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
2289 Context.USAGE_STATS_SERVICE));
2290 boolean isIdle = usm.isAppInactive(packageName, userId);
2291 pw.println("Idle=" + isIdle);
2292 return 0;
2293 }
2294
2295 int runSendTrimMemory(PrintWriter pw) throws RemoteException {
2296 int userId = UserHandle.USER_CURRENT;
2297 String opt;
2298 while ((opt = getNextOption()) != null) {
2299 if (opt.equals("--user")) {
2300 userId = UserHandle.parseUserArg(getNextArgRequired());
2301 if (userId == UserHandle.USER_ALL) {
2302 getErrPrintWriter().println("Error: Can't use user 'all'");
2303 return -1;
2304 }
2305 } else {
2306 getErrPrintWriter().println("Error: Unknown option: " + opt);
2307 return -1;
2308 }
2309 }
2310
2311 String proc = getNextArgRequired();
2312 String levelArg = getNextArgRequired();
2313 int level;
2314 switch (levelArg) {
2315 case "HIDDEN":
2316 level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
2317 break;
2318 case "RUNNING_MODERATE":
2319 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
2320 break;
2321 case "BACKGROUND":
2322 level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
2323 break;
2324 case "RUNNING_LOW":
2325 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
2326 break;
2327 case "MODERATE":
2328 level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
2329 break;
2330 case "RUNNING_CRITICAL":
2331 level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
2332 break;
2333 case "COMPLETE":
2334 level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
2335 break;
2336 default:
Dianne Hackborne51505a2017-08-07 17:13:52 -07002337 try {
2338 level = Integer.parseInt(levelArg);
2339 } catch (NumberFormatException e) {
2340 getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
2341 return -1;
2342 }
Dianne Hackborn331084d2016-10-07 17:57:00 -07002343 }
2344 if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
2345 getErrPrintWriter().println("Unknown error: failed to set trim level");
2346 return -1;
2347 }
2348 return 0;
2349 }
2350
Andrii Kulian839def92016-11-02 10:58:58 -07002351 int runDisplay(PrintWriter pw) throws RemoteException {
2352 String op = getNextArgRequired();
2353 switch (op) {
2354 case "move-stack":
2355 return runDisplayMoveStack(pw);
2356 default:
2357 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2358 return -1;
2359 }
2360 }
2361
Dianne Hackborn331084d2016-10-07 17:57:00 -07002362 int runStack(PrintWriter pw) throws RemoteException {
2363 String op = getNextArgRequired();
2364 switch (op) {
2365 case "start":
2366 return runStackStart(pw);
Andrii Kulian839def92016-11-02 10:58:58 -07002367 case "move-task":
Dianne Hackborn331084d2016-10-07 17:57:00 -07002368 return runStackMoveTask(pw);
2369 case "resize":
2370 return runStackResize(pw);
2371 case "resize-animated":
2372 return runStackResizeAnimated(pw);
2373 case "resize-docked-stack":
2374 return runStackResizeDocked(pw);
2375 case "positiontask":
2376 return runStackPositionTask(pw);
2377 case "list":
2378 return runStackList(pw);
2379 case "info":
2380 return runStackInfo(pw);
2381 case "move-top-activity-to-pinned-stack":
2382 return runMoveTopActivityToPinnedStack(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002383 case "remove":
2384 return runStackRemove(pw);
2385 default:
2386 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2387 return -1;
2388 }
2389 }
2390
2391
2392 private Rect getBounds() {
2393 String leftStr = getNextArgRequired();
2394 int left = Integer.parseInt(leftStr);
2395 String topStr = getNextArgRequired();
2396 int top = Integer.parseInt(topStr);
2397 String rightStr = getNextArgRequired();
2398 int right = Integer.parseInt(rightStr);
2399 String bottomStr = getNextArgRequired();
2400 int bottom = Integer.parseInt(bottomStr);
2401 if (left < 0) {
2402 getErrPrintWriter().println("Error: bad left arg: " + leftStr);
2403 return null;
2404 }
2405 if (top < 0) {
2406 getErrPrintWriter().println("Error: bad top arg: " + topStr);
2407 return null;
2408 }
2409 if (right <= 0) {
2410 getErrPrintWriter().println("Error: bad right arg: " + rightStr);
2411 return null;
2412 }
2413 if (bottom <= 0) {
2414 getErrPrintWriter().println("Error: bad bottom arg: " + bottomStr);
2415 return null;
2416 }
2417 return new Rect(left, top, right, bottom);
2418 }
2419
Andrii Kulian839def92016-11-02 10:58:58 -07002420 int runDisplayMoveStack(PrintWriter pw) throws RemoteException {
2421 String stackIdStr = getNextArgRequired();
2422 int stackId = Integer.parseInt(stackIdStr);
2423 String displayIdStr = getNextArgRequired();
2424 int displayId = Integer.parseInt(displayIdStr);
2425 mInterface.moveStackToDisplay(stackId, displayId);
2426 return 0;
2427 }
2428
Dianne Hackborn331084d2016-10-07 17:57:00 -07002429 int runStackStart(PrintWriter pw) throws RemoteException {
2430 String displayIdStr = getNextArgRequired();
2431 int displayId = Integer.parseInt(displayIdStr);
2432 Intent intent;
2433 try {
2434 intent = makeIntent(UserHandle.USER_CURRENT);
2435 } catch (URISyntaxException e) {
2436 throw new RuntimeException(e.getMessage(), e);
2437 }
2438
Andrii Kulianb1cdb102017-07-13 15:33:06 -07002439 final int stackId = mInterface.createStackOnDisplay(displayId);
2440 if (stackId != INVALID_STACK_ID) {
2441 // TODO: Need proper support if this is used by test...
2442// container.startActivity(intent);
2443// ActivityOptions options = ActivityOptions.makeBasic();
2444// options.setLaunchDisplayId(displayId);
2445// options.setLaunchStackId(stackId);
2446// mInterface.startAct
2447// mInterface.startActivityAsUser(null, null, intent, mimeType,
2448// null, null, 0, mStartFlags, profilerInfo,
2449// options != null ? options.toBundle() : null, mUserId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002450 }
2451 return 0;
2452 }
2453
2454 int runStackMoveTask(PrintWriter pw) throws RemoteException {
2455 String taskIdStr = getNextArgRequired();
2456 int taskId = Integer.parseInt(taskIdStr);
2457 String stackIdStr = getNextArgRequired();
2458 int stackId = Integer.parseInt(stackIdStr);
2459 String toTopStr = getNextArgRequired();
2460 final boolean toTop;
2461 if ("true".equals(toTopStr)) {
2462 toTop = true;
2463 } else if ("false".equals(toTopStr)) {
2464 toTop = false;
2465 } else {
2466 getErrPrintWriter().println("Error: bad toTop arg: " + toTopStr);
2467 return -1;
2468 }
2469
2470 mInterface.moveTaskToStack(taskId, stackId, toTop);
2471 return 0;
2472 }
2473
2474 int runStackResize(PrintWriter pw) throws RemoteException {
2475 String stackIdStr = getNextArgRequired();
2476 int stackId = Integer.parseInt(stackIdStr);
2477 final Rect bounds = getBounds();
2478 if (bounds == null) {
2479 getErrPrintWriter().println("Error: invalid input bounds");
2480 return -1;
2481 }
2482 return resizeStack(stackId, bounds, 0);
2483 }
2484
2485 int runStackResizeAnimated(PrintWriter pw) throws RemoteException {
2486 String stackIdStr = getNextArgRequired();
2487 int stackId = Integer.parseInt(stackIdStr);
2488 final Rect bounds;
2489 if ("null".equals(peekNextArg())) {
2490 bounds = null;
2491 } else {
2492 bounds = getBounds();
2493 if (bounds == null) {
2494 getErrPrintWriter().println("Error: invalid input bounds");
2495 return -1;
2496 }
2497 }
2498 return resizeStackUnchecked(stackId, bounds, 0, true);
2499 }
2500
2501 int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate)
2502 throws RemoteException {
2503 try {
2504 mInterface.resizeStack(stackId, bounds, false, false, animate, -1);
2505 Thread.sleep(delayMs);
2506 } catch (InterruptedException e) {
2507 }
2508 return 0;
2509 }
2510
2511 int runStackResizeDocked(PrintWriter pw) throws RemoteException {
2512 final Rect bounds = getBounds();
2513 final Rect taskBounds = getBounds();
2514 if (bounds == null || taskBounds == null) {
2515 getErrPrintWriter().println("Error: invalid input bounds");
2516 return -1;
2517 }
2518 mInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
2519 return 0;
2520 }
2521
2522 int resizeStack(int stackId, Rect bounds, int delayMs) throws RemoteException {
2523 if (bounds == null) {
2524 getErrPrintWriter().println("Error: invalid input bounds");
2525 return -1;
2526 }
2527 return resizeStackUnchecked(stackId, bounds, delayMs, false);
2528 }
2529
2530 int runStackPositionTask(PrintWriter pw) throws RemoteException {
2531 String taskIdStr = getNextArgRequired();
2532 int taskId = Integer.parseInt(taskIdStr);
2533 String stackIdStr = getNextArgRequired();
2534 int stackId = Integer.parseInt(stackIdStr);
2535 String positionStr = getNextArgRequired();
2536 int position = Integer.parseInt(positionStr);
2537
2538 mInterface.positionTaskInStack(taskId, stackId, position);
2539 return 0;
2540 }
2541
2542 int runStackList(PrintWriter pw) throws RemoteException {
2543 List<ActivityManager.StackInfo> stacks = mInterface.getAllStackInfos();
2544 for (ActivityManager.StackInfo info : stacks) {
2545 pw.println(info);
2546 }
2547 return 0;
2548 }
2549
2550 int runStackInfo(PrintWriter pw) throws RemoteException {
Wale Ogunwale68278562017-09-23 17:13:55 -07002551 int windowingMode = Integer.parseInt(getNextArgRequired());
2552 int activityType = Integer.parseInt(getNextArgRequired());
2553 ActivityManager.StackInfo info = mInterface.getStackInfo(windowingMode, activityType);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002554 pw.println(info);
2555 return 0;
2556 }
2557
2558 int runStackRemove(PrintWriter pw) throws RemoteException {
2559 String stackIdStr = getNextArgRequired();
2560 int stackId = Integer.parseInt(stackIdStr);
2561 mInterface.removeStack(stackId);
2562 return 0;
2563 }
2564
2565 int runMoveTopActivityToPinnedStack(PrintWriter pw) throws RemoteException {
2566 int stackId = Integer.parseInt(getNextArgRequired());
2567 final Rect bounds = getBounds();
2568 if (bounds == null) {
2569 getErrPrintWriter().println("Error: invalid input bounds");
2570 return -1;
2571 }
2572
2573 if (!mInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
2574 getErrPrintWriter().println("Didn't move top activity to pinned stack.");
2575 return -1;
2576 }
2577 return 0;
2578 }
2579
Dianne Hackborn331084d2016-10-07 17:57:00 -07002580 void setBoundsSide(Rect bounds, String side, int value) {
2581 switch (side) {
2582 case "l":
2583 bounds.left = value;
2584 break;
2585 case "r":
2586 bounds.right = value;
2587 break;
2588 case "t":
2589 bounds.top = value;
2590 break;
2591 case "b":
2592 bounds.bottom = value;
2593 break;
2594 default:
2595 getErrPrintWriter().println("Unknown set side: " + side);
2596 break;
2597 }
2598 }
2599
2600 int runTask(PrintWriter pw) throws RemoteException {
2601 String op = getNextArgRequired();
2602 if (op.equals("lock")) {
2603 return runTaskLock(pw);
2604 } else if (op.equals("resizeable")) {
2605 return runTaskResizeable(pw);
2606 } else if (op.equals("resize")) {
2607 return runTaskResize(pw);
David Stevensee9e2772017-02-09 16:30:27 -08002608 } else if (op.equals("focus")) {
2609 return runTaskFocus(pw);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002610 } else {
2611 getErrPrintWriter().println("Error: unknown command '" + op + "'");
2612 return -1;
2613 }
2614 }
2615
2616 int runTaskLock(PrintWriter pw) throws RemoteException {
2617 String taskIdStr = getNextArgRequired();
2618 if (taskIdStr.equals("stop")) {
Benjamin Franza83859f2017-07-03 16:34:14 +01002619 mInterface.stopSystemLockTaskMode();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002620 } else {
2621 int taskId = Integer.parseInt(taskIdStr);
Winson Chungbb348802017-01-30 12:01:45 -08002622 mInterface.startSystemLockTaskMode(taskId);
Dianne Hackborn331084d2016-10-07 17:57:00 -07002623 }
2624 pw.println("Activity manager is " + (mInterface.isInLockTaskMode() ? "" : "not ") +
2625 "in lockTaskMode");
2626 return 0;
2627 }
2628
2629 int runTaskResizeable(PrintWriter pw) throws RemoteException {
2630 final String taskIdStr = getNextArgRequired();
2631 final int taskId = Integer.parseInt(taskIdStr);
2632 final String resizeableStr = getNextArgRequired();
2633 final int resizeableMode = Integer.parseInt(resizeableStr);
2634 mInterface.setTaskResizeable(taskId, resizeableMode);
2635 return 0;
2636 }
2637
2638 int runTaskResize(PrintWriter pw) throws RemoteException {
2639 final String taskIdStr = getNextArgRequired();
2640 final int taskId = Integer.parseInt(taskIdStr);
2641 final Rect bounds = getBounds();
2642 if (bounds == null) {
2643 getErrPrintWriter().println("Error: invalid input bounds");
2644 return -1;
2645 }
2646 taskResize(taskId, bounds, 0, false);
2647 return 0;
2648 }
2649
2650 void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
2651 throws RemoteException {
2652 final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
2653 mInterface.resizeTask(taskId, bounds, resizeMode);
2654 try {
2655 Thread.sleep(delay_ms);
2656 } catch (InterruptedException e) {
2657 }
2658 }
2659
Dianne Hackborn331084d2016-10-07 17:57:00 -07002660 int moveTask(int taskId, Rect taskRect, Rect stackRect, int stepSize,
2661 int maxToTravel, boolean movingForward, boolean horizontal, int delay_ms)
2662 throws RemoteException {
2663 int maxMove;
2664 if (movingForward) {
2665 while (maxToTravel > 0
2666 && ((horizontal && taskRect.right < stackRect.right)
2667 ||(!horizontal && taskRect.bottom < stackRect.bottom))) {
2668 if (horizontal) {
2669 maxMove = Math.min(stepSize, stackRect.right - taskRect.right);
2670 maxToTravel -= maxMove;
2671 taskRect.right += maxMove;
2672 taskRect.left += maxMove;
2673 } else {
2674 maxMove = Math.min(stepSize, stackRect.bottom - taskRect.bottom);
2675 maxToTravel -= maxMove;
2676 taskRect.top += maxMove;
2677 taskRect.bottom += maxMove;
2678 }
2679 taskResize(taskId, taskRect, delay_ms, false);
2680 }
2681 } else {
2682 while (maxToTravel < 0
2683 && ((horizontal && taskRect.left > stackRect.left)
2684 ||(!horizontal && taskRect.top > stackRect.top))) {
2685 if (horizontal) {
2686 maxMove = Math.min(stepSize, taskRect.left - stackRect.left);
2687 maxToTravel -= maxMove;
2688 taskRect.right -= maxMove;
2689 taskRect.left -= maxMove;
2690 } else {
2691 maxMove = Math.min(stepSize, taskRect.top - stackRect.top);
2692 maxToTravel -= maxMove;
2693 taskRect.top -= maxMove;
2694 taskRect.bottom -= maxMove;
2695 }
2696 taskResize(taskId, taskRect, delay_ms, false);
2697 }
2698 }
2699 // Return the remaining distance we didn't travel because we reached the target location.
2700 return maxToTravel;
2701 }
2702
2703 int getStepSize(int current, int target, int inStepSize, boolean greaterThanTarget) {
2704 int stepSize = 0;
2705 if (greaterThanTarget && target < current) {
2706 current -= inStepSize;
2707 stepSize = inStepSize;
2708 if (target > current) {
2709 stepSize -= (target - current);
2710 }
2711 }
2712 if (!greaterThanTarget && target > current) {
2713 current += inStepSize;
2714 stepSize = inStepSize;
2715 if (target < current) {
2716 stepSize += (current - target);
2717 }
2718 }
2719 return stepSize;
2720 }
2721
David Stevensee9e2772017-02-09 16:30:27 -08002722 int runTaskFocus(PrintWriter pw) throws RemoteException {
2723 final int taskId = Integer.parseInt(getNextArgRequired());
2724 pw.println("Setting focus to task " + taskId);
2725 mInterface.setFocusedTask(taskId);
2726 return 0;
2727 }
2728
Dianne Hackborn331084d2016-10-07 17:57:00 -07002729 int runWrite(PrintWriter pw) {
2730 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2731 "registerUidObserver()");
Winson Chung3f0e59a2017-10-25 10:19:05 -07002732 mInternal.getRecentTasks().flush();
Dianne Hackborn331084d2016-10-07 17:57:00 -07002733 pw.println("All tasks persisted.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07002734 return 0;
2735 }
2736
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07002737 int runAttachAgent(PrintWriter pw) {
2738 // TODO: revisit the permissions required for attaching agents
2739 mInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
2740 "attach-agent");
2741 String process = getNextArgRequired();
2742 String agent = getNextArgRequired();
2743 String opt;
2744 if ((opt = getNextArg()) != null) {
2745 pw.println("Error: Unknown option: " + opt);
2746 return -1;
2747 }
2748 mInternal.attachAgent(process, agent);
2749 return 0;
2750 }
2751
Michael Kwan94438b72016-11-03 15:30:34 -07002752 int runSupportsMultiwindow(PrintWriter pw) throws RemoteException {
Matthew Ng626e0cc2016-12-07 17:25:53 -08002753 final Resources res = getResources(pw);
2754 if (res == null) {
2755 return -1;
2756 }
Erik Wolsheimer9be3a062017-05-31 14:59:57 -07002757 pw.println(ActivityManager.supportsMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002758 return 0;
2759 }
2760
2761 int runSupportsSplitScreenMultiwindow(PrintWriter pw) throws RemoteException {
2762 final Resources res = getResources(pw);
2763 if (res == null) {
2764 return -1;
2765 }
Erik Wolsheimer9be3a062017-05-31 14:59:57 -07002766 pw.println(ActivityManager.supportsSplitScreenMultiWindow(mInternal.mContext));
Matthew Ng626e0cc2016-12-07 17:25:53 -08002767 return 0;
2768 }
2769
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01002770 int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
2771 int userid = UserHandle.parseUserArg(getNextArgRequired());
2772 ArrayList<String> packages = new ArrayList<>();
2773 packages.add(getNextArgRequired());
2774 String packageName;
2775 while ((packageName = getNextArg()) != null) {
2776 packages.add(packageName);
2777 }
2778 mInternal.scheduleApplicationInfoChanged(packages, userid);
2779 pw.println("Packages updated with most recent ApplicationInfos.");
2780 return 0;
2781 }
2782
Arthur Hsuf3f3a602017-02-21 14:01:53 -08002783 int runNoHomeScreen(PrintWriter pw) throws RemoteException {
2784 final Resources res = getResources(pw);
2785 if (res == null) {
2786 return -1;
2787 }
2788 pw.println(res.getBoolean(com.android.internal.R.bool.config_noHomeScreen));
2789 return 0;
2790 }
2791
Jeff Sharkeyfd658132017-05-03 11:38:01 -06002792 int runWaitForBroadcastIdle(PrintWriter pw) throws RemoteException {
2793 mInternal.waitForBroadcastIdle(pw);
2794 return 0;
2795 }
2796
Matthew Ng626e0cc2016-12-07 17:25:53 -08002797 private Resources getResources(PrintWriter pw) throws RemoteException {
Michael Kwan94438b72016-11-03 15:30:34 -07002798 // system resources does not contain all the device configuration, construct it manually.
2799 Configuration config = mInterface.getConfiguration();
2800 if (config == null) {
2801 pw.println("Error: Activity manager has no configuration");
Matthew Ng626e0cc2016-12-07 17:25:53 -08002802 return null;
Michael Kwan94438b72016-11-03 15:30:34 -07002803 }
2804
2805 final DisplayMetrics metrics = new DisplayMetrics();
2806 metrics.setToDefaults();
2807
Matthew Ng626e0cc2016-12-07 17:25:53 -08002808 return new Resources(AssetManager.getSystem(), metrics, config);
Michael Kwan94438b72016-11-03 15:30:34 -07002809 }
2810
Dianne Hackborn2e441072015-10-28 18:00:57 -07002811 @Override
2812 public void onHelp() {
2813 PrintWriter pw = getOutPrintWriter();
2814 dumpHelp(pw, mDumping);
2815 }
2816
2817 static void dumpHelp(PrintWriter pw, boolean dumping) {
2818 if (dumping) {
2819 pw.println("Activity manager dump options:");
2820 pw.println(" [-a] [-c] [-p PACKAGE] [-h] [WHAT] ...");
2821 pw.println(" WHAT may be one of:");
2822 pw.println(" a[ctivities]: activity stack state");
2823 pw.println(" r[recents]: recent activities state");
2824 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002825 pw.println(" broadcast-stats [PACKAGE_NAME]: aggregated broadcast statistics");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002826 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
2827 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
2828 pw.println(" o[om]: out of memory management");
2829 pw.println(" perm[issions]: URI permission grant state");
2830 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
2831 pw.println(" provider [COMP_SPEC]: provider client-side state");
2832 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
2833 pw.println(" as[sociations]: tracked app associations");
Dianne Hackborn0ef403e2017-01-24 18:22:15 -08002834 pw.println(" settings: currently applied config settings");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002835 pw.println(" service [COMP_SPEC]: service client-side state");
2836 pw.println(" package [PACKAGE_NAME]: all state related to given package");
2837 pw.println(" all: dump all activities");
2838 pw.println(" top: dump the top activity");
2839 pw.println(" WHAT may also be a COMP_SPEC to dump activities.");
2840 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
2841 pw.println(" a partial substring in a component name, a");
2842 pw.println(" hex object identifier.");
2843 pw.println(" -a: include all available server state.");
2844 pw.println(" -c: include client state.");
2845 pw.println(" -p: limit output to given package.");
Dianne Hackbornbc02a392016-06-02 17:15:08 -07002846 pw.println(" --checkin: output checkin format, resetting data.");
2847 pw.println(" --C: output checkin format, not resetting data.");
Steven Timotius4346f0a2017-09-12 11:07:21 -07002848 pw.println(" --proto: output dump in protocol buffer format.");
Felipe Leme42260332018-08-15 08:44:12 -07002849 pw.println(" --autofill: dump just the autofill-related state of an activity");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002850 } else {
2851 pw.println("Activity manager (activity) commands:");
2852 pw.println(" help");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002853 pw.println(" Print this help text.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002854 pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002855 pw.println(" [--sampling INTERVAL] [--streaming] [-R COUNT] [-S]");
Dianne Hackborn354736e2016-08-22 17:00:05 -07002856 pw.println(" [--track-allocation] [--user <USER_ID> | current] <INTENT>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002857 pw.println(" Start an Activity. Options are:");
2858 pw.println(" -D: enable debugging");
2859 pw.println(" -N: enable native debugging");
2860 pw.println(" -W: wait for launch to complete");
2861 pw.println(" --start-profiler <FILE>: start profiler and send results to <FILE>");
2862 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2863 pw.println(" between samples (use with --start-profiler)");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002864 pw.println(" --streaming: stream the profiling output to the specified file");
2865 pw.println(" (use with --start-profiler)");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002866 pw.println(" -P <FILE>: like above, but profiling stops when app goes idle");
Andreas Gampe83085bb2017-06-26 17:54:11 -07002867 pw.println(" --attach-agent <agent>: attach the given agent before binding");
Andreas Gampeab8a63b2018-01-05 13:55:15 -08002868 pw.println(" --attach-agent-bind <agent>: attach the given agent during binding");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002869 pw.println(" -R: repeat the activity launch <COUNT> times. Prior to each repeat,");
2870 pw.println(" the top activity will be finished.");
2871 pw.println(" -S: force stop the target app before starting the activity");
2872 pw.println(" --track-allocation: enable tracking of object allocations");
2873 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2874 pw.println(" specified then run as the current user.");
Wale Ogunwale0568aed2017-09-08 13:29:37 -07002875 pw.println(" --windowingMode <WINDOWING_MODE>: The windowing mode to launch the activity into.");
2876 pw.println(" --activityType <ACTIVITY_TYPE>: The activity type to launch the activity as.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002877 pw.println(" start-service [--user <USER_ID> | current] <INTENT>");
2878 pw.println(" Start a Service. Options are:");
2879 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2880 pw.println(" specified then run as the current user.");
Jaewan Kim329b35f2017-04-11 11:19:49 +09002881 pw.println(" start-foreground-service [--user <USER_ID> | current] <INTENT>");
2882 pw.println(" Start a foreground Service. Options are:");
2883 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2884 pw.println(" specified then run as the current user.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002885 pw.println(" stop-service [--user <USER_ID> | current] <INTENT>");
2886 pw.println(" Stop a Service. Options are:");
2887 pw.println(" --user <USER_ID> | current: Specify which user to run as; if not");
2888 pw.println(" specified then run as the current user.");
2889 pw.println(" broadcast [--user <USER_ID> | all | current] <INTENT>");
2890 pw.println(" Send a broadcast Intent. Options are:");
2891 pw.println(" --user <USER_ID> | all | current: Specify which user to send to; if not");
2892 pw.println(" specified then send to all users.");
2893 pw.println(" --receiver-permission <PERMISSION>: Require receiver to hold permission.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002894 pw.println(" instrument [-r] [-e <NAME> <VALUE>] [-p <FILE>] [-w]");
David Brazdild5d42172018-02-14 19:39:03 +00002895 pw.println(" [--user <USER_ID> | current] [--no-hidden-api-checks]");
Dianne Hackborn28824062016-10-18 13:19:20 -07002896 pw.println(" [--no-window-animation] [--abi <ABI>] <COMPONENT>");
2897 pw.println(" Start an Instrumentation. Typically this target <COMPONENT> is in the");
2898 pw.println(" form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
2899 pw.println(" is only one instrumentation. Options are:");
2900 pw.println(" -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with");
2901 pw.println(" [-e perf true] to generate raw output for performance measurements.");
2902 pw.println(" -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a");
2903 pw.println(" common form is [-e <testrunner_flag> <value>[,<value>...]].");
2904 pw.println(" -p <FILE>: write profiling data to <FILE>");
Mike Mad2239822017-10-31 12:30:42 -07002905 pw.println(" -m: Write output as protobuf to stdout (machine readable)");
2906 pw.println(" -f <Optional PATH/TO/FILE>: Write output as protobuf to a file (machine");
2907 pw.println(" readable). If path is not specified, default directory and file name will");
2908 pw.println(" be used: /sdcard/instrument-logs/log-yyyyMMdd-hhmmss-SSS.instrumentation_data_proto");
Dianne Hackborn28824062016-10-18 13:19:20 -07002909 pw.println(" -w: wait for instrumentation to finish before returning. Required for");
2910 pw.println(" test runners.");
2911 pw.println(" --user <USER_ID> | current: Specify user instrumentation runs in;");
2912 pw.println(" current user if not specified.");
David Brazdild5d42172018-02-14 19:39:03 +00002913 pw.println(" --no-hidden-api-checks: disable restrictions on use of hidden API.");
Dianne Hackborn28824062016-10-18 13:19:20 -07002914 pw.println(" --no-window-animation: turn off window animations while running.");
2915 pw.println(" --abi <ABI>: Launch the instrumented process with the selected ABI.");
2916 pw.println(" This assumes that the process supports the selected ABI.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002917 pw.println(" trace-ipc [start|stop] [--dump-file <FILE>]");
2918 pw.println(" Trace IPC transactions.");
2919 pw.println(" start: start tracing IPC transactions.");
2920 pw.println(" stop: stop tracing IPC transactions and dump the results to file.");
2921 pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to.");
2922 pw.println(" profile [start|stop] [--user <USER_ID> current] [--sampling INTERVAL]");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002923 pw.println(" [--streaming] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002924 pw.println(" Start and stop profiler on a process. The given <PROCESS> argument");
2925 pw.println(" may be either a process name or pid. Options are:");
2926 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2927 pw.println(" specify user of process to profile; uses current user if not specified.");
Shukang Zhou6ffd4f92017-01-25 16:07:57 -08002928 pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds");
2929 pw.println(" between samples");
2930 pw.println(" --streaming: stream the profiling output to the specified file");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002931 pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002932 pw.println(" Dump the heap of a process. The given <PROCESS> argument may");
2933 pw.println(" be either a process name or pid. Options are:");
2934 pw.println(" -n: dump native heap instead of managed heap");
Makoto Onuki4556b7b2017-07-07 14:58:58 -07002935 pw.println(" -g: force GC before dumping the heap");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002936 pw.println(" --user <USER_ID> | current: When supplying a process name,");
2937 pw.println(" specify user of process to dump; uses current user if not specified.");
2938 pw.println(" set-debug-app [-w] [--persistent] <PACKAGE>");
2939 pw.println(" Set application <PACKAGE> to debug. Options are:");
2940 pw.println(" -w: wait for debugger when application starts");
2941 pw.println(" --persistent: retain this value");
2942 pw.println(" clear-debug-app");
2943 pw.println(" Clear the previously set-debug-app.");
2944 pw.println(" set-watch-heap <PROCESS> <MEM-LIMIT>");
2945 pw.println(" Start monitoring pss size of <PROCESS>, if it is at or");
2946 pw.println(" above <HEAP-LIMIT> then a heap dump is collected for the user to report.");
2947 pw.println(" clear-watch-heap");
2948 pw.println(" Clear the previously set-watch-heap.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002949 pw.println(" bug-report [--progress | --telephony]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002950 pw.println(" Request bug report generation; will launch a notification");
2951 pw.println(" when done to select where it should be delivered. Options are:");
2952 pw.println(" --progress: will launch a notification right away to show its progress.");
Felipe Leme9606c3b2017-01-05 14:57:12 -08002953 pw.println(" --telephony: will dump only telephony sections.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002954 pw.println(" force-stop [--user <USER_ID> | all | current] <PACKAGE>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002955 pw.println(" Completely stop the given application package.");
Christopher Tate8aa8fe12017-01-20 17:50:32 -08002956 pw.println(" crash [--user <USER_ID>] <PACKAGE|PID>");
2957 pw.println(" Induce a VM crash in the specified package or process");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002958 pw.println(" kill [--user <USER_ID> | all | current] <PACKAGE>");
Makoto Onuki6569c362018-02-27 15:52:01 -08002959 pw.println(" Kill all background processes associated with the given application.");
Dianne Hackborn2e441072015-10-28 18:00:57 -07002960 pw.println(" kill-all");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002961 pw.println(" Kill all processes that are safe to kill (cached, etc).");
Dianne Hackborn85e35642017-01-12 15:10:57 -08002962 pw.println(" make-uid-idle [--user <USER_ID> | all | current] <PACKAGE>");
2963 pw.println(" If the given application's uid is in the background and waiting to");
2964 pw.println(" become idle (not allowing background services), do that now.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002965 pw.println(" monitor [--gdb <port>]");
2966 pw.println(" Start monitoring for crashes or ANRs.");
2967 pw.println(" --gdb: start gdbserv on the given port at crash/ANR");
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07002968 pw.println(" watch-uids [--oom <uid>]");
Dianne Hackbornffae1cb2017-07-10 17:22:32 +01002969 pw.println(" Start watching for and reporting uid state changes.");
Dianne Hackborne51505a2017-08-07 17:13:52 -07002970 pw.println(" --oom: specify a uid for which to report detailed change messages.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07002971 pw.println(" hang [--allow-restart]");
2972 pw.println(" Hang the system.");
2973 pw.println(" --allow-restart: allow watchdog to perform normal system restart");
2974 pw.println(" restart");
2975 pw.println(" Restart the user-space system.");
2976 pw.println(" idle-maintenance");
2977 pw.println(" Perform idle maintenance now.");
2978 pw.println(" screen-compat [on|off] <PACKAGE>");
2979 pw.println(" Control screen compatibility mode of <PACKAGE>.");
2980 pw.println(" package-importance <PACKAGE>");
2981 pw.println(" Print current importance of <PACKAGE>.");
2982 pw.println(" to-uri [INTENT]");
2983 pw.println(" Print the given Intent specification as a URI.");
2984 pw.println(" to-intent-uri [INTENT]");
2985 pw.println(" Print the given Intent specification as an intent: URI.");
2986 pw.println(" to-app-uri [INTENT]");
2987 pw.println(" Print the given Intent specification as an android-app: URI.");
2988 pw.println(" switch-user <USER_ID>");
2989 pw.println(" Switch to put USER_ID in the foreground, starting");
2990 pw.println(" execution of that user if it is currently stopped.");
2991 pw.println(" get-current-user");
2992 pw.println(" Returns id of the current foreground user.");
2993 pw.println(" start-user <USER_ID>");
2994 pw.println(" Start USER_ID in background if it is currently stopped;");
2995 pw.println(" use switch-user if you want to start the user in foreground");
2996 pw.println(" unlock-user <USER_ID> [TOKEN_HEX]");
2997 pw.println(" Attempt to unlock the given user using the given authorization token.");
2998 pw.println(" stop-user [-w] [-f] <USER_ID>");
2999 pw.println(" Stop execution of USER_ID, not allowing it to run any");
3000 pw.println(" code until a later explicit start or switch to it.");
3001 pw.println(" -w: wait for stop-user to complete.");
3002 pw.println(" -f: force stop even if there are related users that cannot be stopped.");
Suprabh Shukla09a88f52015-12-02 14:36:31 -08003003 pw.println(" is-user-stopped <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003004 pw.println(" Returns whether <USER_ID> has been stopped or not.");
Sudheer Shanka28537b62016-09-07 11:12:31 -07003005 pw.println(" get-started-user-state <USER_ID>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003006 pw.println(" Gets the current state of the given started user.");
3007 pw.println(" track-associations");
3008 pw.println(" Enable association tracking.");
3009 pw.println(" untrack-associations");
3010 pw.println(" Disable and clear association tracking.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003011 pw.println(" get-uid-state <UID>");
3012 pw.println(" Gets the process state of an app given its <UID>.");
Leonard Mosescuf3409ce2016-10-06 17:32:05 -07003013 pw.println(" attach-agent <PROCESS> <FILE>");
3014 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 -08003015 pw.println(" get-config [--days N] [--device] [--proto]");
3016 pw.println(" Retrieve the configuration and any recent configurations of the device.");
3017 pw.println(" --days: also return last N days of configurations that have been seen.");
3018 pw.println(" --device: also output global device configuration info.");
3019 pw.println(" --proto: return result as a proto; does not include --days info.");
Michael Kwan94438b72016-11-03 15:30:34 -07003020 pw.println(" supports-multiwindow");
3021 pw.println(" Returns true if the device supports multiwindow.");
Matthew Ng626e0cc2016-12-07 17:25:53 -08003022 pw.println(" supports-split-screen-multi-window");
3023 pw.println(" Returns true if the device supports split screen multiwindow.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003024 pw.println(" suppress-resize-config-changes <true|false>");
3025 pw.println(" Suppresses configuration changes due to user resizing an activity/task.");
3026 pw.println(" set-inactive [--user <USER_ID>] <PACKAGE> true|false");
3027 pw.println(" Sets the inactive state of an app.");
3028 pw.println(" get-inactive [--user <USER_ID>] <PACKAGE>");
3029 pw.println(" Returns the inactive state of an app.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003030 pw.println(" set-standby-bucket [--user <USER_ID>] <PACKAGE> active|working_set|frequent|rare");
Amith Yamasani17fffee2017-09-29 13:17:43 -07003031 pw.println(" Puts an app in the standby bucket.");
Amith Yamasaniafbccb72017-11-27 10:44:24 -08003032 pw.println(" get-standby-bucket [--user <USER_ID>] <PACKAGE>");
3033 pw.println(" Returns the standby bucket of an app.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003034 pw.println(" send-trim-memory [--user <USER_ID>] <PROCESS>");
3035 pw.println(" [HIDDEN|RUNNING_MODERATE|BACKGROUND|RUNNING_LOW|MODERATE|RUNNING_CRITICAL|COMPLETE]");
Dianne Hackborne51505a2017-08-07 17:13:52 -07003036 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 -07003037 pw.println(" display [COMMAND] [...]: sub-commands for operating on displays.");
3038 pw.println(" move-stack <STACK_ID> <DISPLAY_ID>");
3039 pw.println(" Move <STACK_ID> from its current display to <DISPLAY_ID>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003040 pw.println(" stack [COMMAND] [...]: sub-commands for operating on activity stacks.");
3041 pw.println(" start <DISPLAY_ID> <INTENT>");
3042 pw.println(" Start a new activity on <DISPLAY_ID> using <INTENT>");
Andrii Kulian839def92016-11-02 10:58:58 -07003043 pw.println(" move-task <TASK_ID> <STACK_ID> [true|false]");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003044 pw.println(" Move <TASK_ID> from its current stack to the top (true) or");
3045 pw.println(" bottom (false) of <STACK_ID>.");
3046 pw.println(" resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3047 pw.println(" Change <STACK_ID> size and position to <LEFT,TOP,RIGHT,BOTTOM>.");
3048 pw.println(" resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3049 pw.println(" Same as resize, but allow animation.");
3050 pw.println(" resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]");
3051 pw.println(" Change docked stack to <LEFT,TOP,RIGHT,BOTTOM>");
3052 pw.println(" and supplying temporary different task bounds indicated by");
3053 pw.println(" <TASK_LEFT,TOP,RIGHT,BOTTOM>");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003054 pw.println(" move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3055 pw.println(" Moves the top activity from");
3056 pw.println(" <STACK_ID> to the pinned stack using <LEFT,TOP,RIGHT,BOTTOM> for the");
3057 pw.println(" bounds of the pinned stack.");
3058 pw.println(" positiontask <TASK_ID> <STACK_ID> <POSITION>");
3059 pw.println(" Place <TASK_ID> in <STACK_ID> at <POSITION>");
3060 pw.println(" list");
3061 pw.println(" List all of the activity stacks and their sizes.");
Wale Ogunwale68278562017-09-23 17:13:55 -07003062 pw.println(" info <WINDOWING_MODE> <ACTIVITY_TYPE>");
3063 pw.println(" Display the information about activity stack in <WINDOWING_MODE> and <ACTIVITY_TYPE>.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003064 pw.println(" remove <STACK_ID>");
3065 pw.println(" Remove stack <STACK_ID>.");
3066 pw.println(" task [COMMAND] [...]: sub-commands for operating on activity tasks.");
3067 pw.println(" lock <TASK_ID>");
3068 pw.println(" Bring <TASK_ID> to the front and don't allow other tasks to run.");
3069 pw.println(" lock stop");
3070 pw.println(" End the current task lock.");
3071 pw.println(" resizeable <TASK_ID> [0|1|2|3]");
3072 pw.println(" Change resizeable mode of <TASK_ID> to one of the following:");
3073 pw.println(" 0: unresizeable");
3074 pw.println(" 1: crop_windows");
3075 pw.println(" 2: resizeable");
3076 pw.println(" 3: resizeable_and_pipable");
3077 pw.println(" resize <TASK_ID> <LEFT,TOP,RIGHT,BOTTOM>");
3078 pw.println(" Makes sure <TASK_ID> is in a stack with the specified bounds.");
3079 pw.println(" Forces the task to be resizeable and creates a stack if no existing stack");
3080 pw.println(" has the specified bounds.");
MÃ¥rten Kongstad49a4a1d2017-01-12 08:36:37 +01003081 pw.println(" update-appinfo <USER_ID> <PACKAGE_NAME> [<PACKAGE_NAME>...]");
3082 pw.println(" Update the ApplicationInfo objects of the listed packages for <USER_ID>");
3083 pw.println(" without restarting any processes.");
Dianne Hackborn331084d2016-10-07 17:57:00 -07003084 pw.println(" write");
3085 pw.println(" Write all pending state to storage.");
Dianne Hackborn354736e2016-08-22 17:00:05 -07003086 pw.println();
3087 Intent.printIntentArgsHelp(pw, "");
Dianne Hackborn2e441072015-10-28 18:00:57 -07003088 }
3089 }
3090}