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