blob: dceed28d4c0867785701926c02308a9f95c6c633 [file] [log] [blame]
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001/*
2 * Copyright (C) 2018 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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070018
19import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
Louis Chang77ce34d2019-01-03 15:45:12 +080020import static android.os.Build.VERSION_CODES.Q;
Yunfan Chen79b96062018-10-17 12:45:23 -070021import static android.view.Display.INVALID_DISPLAY;
Yunfan Chen75157d72018-07-27 14:47:21 +090022
Wale Ogunwalee2172292018-10-25 10:11:10 -070023import static com.android.server.am.ActivityManagerService.MY_PID;
Wale Ogunwale59507092018-10-29 09:00:30 -070024import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
25import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
26import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
27import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
28import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
29import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
30import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
31import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
32import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
33import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
34import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
35import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Louis Chang77ce34d2019-01-03 15:45:12 +080036import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale59507092018-10-29 09:00:30 -070037import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
38import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070039
Louis Chang77ce34d2019-01-03 15:45:12 +080040import android.annotation.NonNull;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070041import android.app.Activity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070042import android.app.ActivityThread;
43import android.app.IApplicationThread;
Wale Ogunwale9c103022018-10-18 07:44:54 -070044import android.app.ProfilerInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +090045import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070046import android.content.Intent;
47import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +090048import android.content.res.Configuration;
Yohei Yukawae2fa39e2018-09-22 13:13:10 -070049import android.os.Message;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070050import android.os.RemoteException;
51import android.util.ArraySet;
52import android.util.Log;
53import android.util.Slog;
Wale Ogunwale51cc98a2018-10-15 10:41:05 -070054import android.util.proto.ProtoOutputStream;
Yunfan Chen79b96062018-10-17 12:45:23 -070055
Yunfan Chenb29cbfd2019-01-24 17:30:33 +090056import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070057import com.android.internal.app.HeavyWeightSwitcherActivity;
58import com.android.internal.util.function.pooled.PooledLambda;
Wale Ogunwalee2172292018-10-25 10:11:10 -070059import com.android.server.Watchdog;
Riddle Hsua0536432019-02-16 00:38:59 +080060import com.android.server.wm.ActivityTaskManagerService.HotPath;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070061
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -080062import java.io.IOException;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070063import java.io.PrintWriter;
64import java.util.ArrayList;
65
66/**
67 * The Activity Manager (AM) package manages the lifecycle of processes in the system through
Wale Ogunwale59507092018-10-29 09:00:30 -070068 * ProcessRecord. However, it is important for the Window Manager (WM) package to be aware
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070069 * of the processes and their state since it affects how WM manages windows and activities. This
Wale Ogunwale59507092018-10-29 09:00:30 -070070 * class that allows the ProcessRecord object in the AM package to communicate important
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070071 * changes to its state to the WM package in a structured way. WM package also uses
72 * {@link WindowProcessListener} to request changes to the process state on the AM side.
73 * Note that public calls into this class are assumed to be originating from outside the
74 * window manager so the window manager lock is held and appropriate permissions are checked before
75 * calls are allowed to proceed.
76 */
Yunfan Chen79b96062018-10-17 12:45:23 -070077public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
78 implements ConfigurationContainerListener {
Wale Ogunwale98875612018-10-12 07:53:02 -070079 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070080 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
Yunfan Chen75157d72018-07-27 14:47:21 +090081 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070082
83 // all about the first app in the process
84 final ApplicationInfo mInfo;
85 final String mName;
86 final int mUid;
87 // The process of this application; 0 if none
88 private volatile int mPid;
89 // user of process.
90 final int mUserId;
91 // The owner of this window process controller object. Mainly for identification when we
92 // communicate back to the activity manager side.
93 public final Object mOwner;
94 // List of packages running in the process
95 final ArraySet<String> mPkgList = new ArraySet<>();
96 private final WindowProcessListener mListener;
97 private final ActivityTaskManagerService mAtm;
98 // The actual proc... may be null only if 'persistent' is true (in which case we are in the
99 // process of launching the app)
100 private volatile IApplicationThread mThread;
101 // Currently desired scheduling class
102 private volatile int mCurSchedGroup;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700103 // Currently computed process state
104 private volatile int mCurProcState = PROCESS_STATE_NONEXISTENT;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700105 // Last reported process state;
106 private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT;
107 // are we in the process of crashing?
108 private volatile boolean mCrashing;
109 // does the app have a not responding dialog?
110 private volatile boolean mNotResponding;
111 // always keep this application running?
112 private volatile boolean mPersistent;
113 // The ABI this process was launched with
114 private volatile String mRequiredAbi;
115 // Running any services that are foreground?
116 private volatile boolean mHasForegroundServices;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700117 // Running any activities that are foreground?
118 private volatile boolean mHasForegroundActivities;
119 // Are there any client services with activities?
120 private volatile boolean mHasClientActivities;
121 // Is this process currently showing a non-activity UI that the user is interacting with?
122 // E.g. The status bar when it is expanded, but not when it is minimized. When true the process
123 // will be set to use the ProcessList#SCHED_GROUP_TOP_APP scheduling group to boost performance.
124 private volatile boolean mHasTopUi;
125 // Is the process currently showing a non-activity UI that overlays on-top of activity UIs on
126 // screen. E.g. display a window of type
127 // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY When true the process will
128 // oom adj score will be set to ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
129 // of the process getting killed.
130 private volatile boolean mHasOverlayUi;
131 // Want to clean up resources from showing UI?
132 private volatile boolean mPendingUiClean;
133 // The time we sent the last interaction event
134 private volatile long mInteractionEventTime;
135 // When we became foreground for interaction purposes
136 private volatile long mFgInteractionTime;
137 // When (uptime) the process last became unimportant
138 private volatile long mWhenUnimportant;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700139 // was app launched for debugging?
140 private volatile boolean mDebugging;
141 // Active instrumentation running in process?
142 private volatile boolean mInstrumenting;
Michal Karpinskidaef80f2019-01-29 16:50:51 +0000143 // Active instrumentation with background activity starts privilege running in process?
144 private volatile boolean mInstrumentingWithBackgroundActivityStartPrivileges;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700145 // This process it perceptible by the user.
146 private volatile boolean mPerceptible;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700147 // Set to true when process was launched with a wrapper attached
148 private volatile boolean mUsingWrapper;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000149 // Set to true if this process is currently temporarily whitelisted to start activities even if
150 // it's not in the foreground
151 private volatile boolean mAllowBackgroundActivityStarts;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700152
153 // Thread currently set for VR scheduling
154 int mVrThreadTid;
155
156 // all activities running in the process
157 private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
158 // any tasks this process had run root activities in
159 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>();
Louis Chang77ce34d2019-01-03 15:45:12 +0800160 // The most recent top-most activity that was resumed in the process for pre-Q app.
161 private ActivityRecord mPreQTopResumedActivity = null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700162
Yunfan Chen75157d72018-07-27 14:47:21 +0900163 // Last configuration that was reported to the process.
164 private final Configuration mLastReportedConfiguration;
Yunfan Chen79b96062018-10-17 12:45:23 -0700165 // Registered display id as a listener to override config change
166 private int mDisplayId;
Yunfan Chen75157d72018-07-27 14:47:21 +0900167
Wale Ogunwale59507092018-10-29 09:00:30 -0700168 public WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info,
169 String name, int uid, int userId, Object owner, WindowProcessListener listener) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700170 mInfo = info;
171 mName = name;
172 mUid = uid;
173 mUserId = userId;
174 mOwner = owner;
175 mListener = listener;
176 mAtm = atm;
Yunfan Chen75157d72018-07-27 14:47:21 +0900177 mLastReportedConfiguration = new Configuration();
Yunfan Chen79b96062018-10-17 12:45:23 -0700178 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700179 if (atm != null) {
180 onConfigurationChanged(atm.getGlobalConfiguration());
Yunfan Chen75157d72018-07-27 14:47:21 +0900181 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700182 }
183
184 public void setPid(int pid) {
185 mPid = pid;
186 }
187
Wale Ogunwale59507092018-10-29 09:00:30 -0700188 public int getPid() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700189 return mPid;
190 }
191
192 public void setThread(IApplicationThread thread) {
193 mThread = thread;
194 }
195
196 IApplicationThread getThread() {
197 return mThread;
198 }
199
200 boolean hasThread() {
201 return mThread != null;
202 }
203
204 public void setCurrentSchedulingGroup(int curSchedGroup) {
205 mCurSchedGroup = curSchedGroup;
206 }
207
208 int getCurrentSchedulingGroup() {
209 return mCurSchedGroup;
210 }
211
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700212 public void setCurrentProcState(int curProcState) {
213 mCurProcState = curProcState;
214 }
215
216 int getCurrentProcState() {
217 return mCurProcState;
218 }
219
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700220 public void setReportedProcState(int repProcState) {
221 mRepProcState = repProcState;
222 }
223
224 int getReportedProcState() {
225 return mRepProcState;
226 }
227
228 public void setCrashing(boolean crashing) {
229 mCrashing = crashing;
230 }
231
232 boolean isCrashing() {
233 return mCrashing;
234 }
235
236 public void setNotResponding(boolean notResponding) {
237 mNotResponding = notResponding;
238 }
239
240 boolean isNotResponding() {
241 return mNotResponding;
242 }
243
244 public void setPersistent(boolean persistent) {
245 mPersistent = persistent;
246 }
247
248 boolean isPersistent() {
249 return mPersistent;
250 }
251
252 public void setHasForegroundServices(boolean hasForegroundServices) {
253 mHasForegroundServices = hasForegroundServices;
254 }
255
256 boolean hasForegroundServices() {
257 return mHasForegroundServices;
258 }
259
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700260 public void setHasForegroundActivities(boolean hasForegroundActivities) {
261 mHasForegroundActivities = hasForegroundActivities;
262 }
263
264 boolean hasForegroundActivities() {
265 return mHasForegroundActivities;
266 }
267
268 public void setHasClientActivities(boolean hasClientActivities) {
269 mHasClientActivities = hasClientActivities;
270 }
271
272 boolean hasClientActivities() {
273 return mHasClientActivities;
274 }
275
276 public void setHasTopUi(boolean hasTopUi) {
277 mHasTopUi = hasTopUi;
278 }
279
280 boolean hasTopUi() {
281 return mHasTopUi;
282 }
283
284 public void setHasOverlayUi(boolean hasOverlayUi) {
285 mHasOverlayUi = hasOverlayUi;
286 }
287
288 boolean hasOverlayUi() {
289 return mHasOverlayUi;
290 }
291
292 public void setPendingUiClean(boolean hasPendingUiClean) {
293 mPendingUiClean = hasPendingUiClean;
294 }
295
296 boolean hasPendingUiClean() {
297 return mPendingUiClean;
298 }
299
300 void postPendingUiCleanMsg(boolean pendingUiClean) {
301 if (mListener == null) return;
302 // Posting on handler so WM lock isn't held when we call into AM.
303 final Message m = PooledLambda.obtainMessage(
304 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
305 mAtm.mH.sendMessage(m);
306 }
307
308 public void setInteractionEventTime(long interactionEventTime) {
309 mInteractionEventTime = interactionEventTime;
310 }
311
312 long getInteractionEventTime() {
313 return mInteractionEventTime;
314 }
315
316 public void setFgInteractionTime(long fgInteractionTime) {
317 mFgInteractionTime = fgInteractionTime;
318 }
319
320 long getFgInteractionTime() {
321 return mFgInteractionTime;
322 }
323
324 public void setWhenUnimportant(long whenUnimportant) {
325 mWhenUnimportant = whenUnimportant;
326 }
327
328 long getWhenUnimportant() {
329 return mWhenUnimportant;
330 }
331
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700332 public void setRequiredAbi(String requiredAbi) {
333 mRequiredAbi = requiredAbi;
334 }
335
336 String getRequiredAbi() {
337 return mRequiredAbi;
338 }
339
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900340 /** Returns ID of display overriding the configuration for this process, or
341 * INVALID_DISPLAY if no display is overriding. */
342 @VisibleForTesting
343 int getDisplayId() {
344 return mDisplayId;
345 }
346
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700347 public void setDebugging(boolean debugging) {
348 mDebugging = debugging;
349 }
350
351 boolean isDebugging() {
352 return mDebugging;
353 }
354
355 public void setUsingWrapper(boolean usingWrapper) {
356 mUsingWrapper = usingWrapper;
357 }
358
359 boolean isUsingWrapper() {
360 return mUsingWrapper;
361 }
362
Michal Karpinskiac116df2018-12-10 17:51:42 +0000363 public void setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts) {
364 mAllowBackgroundActivityStarts = allowBackgroundActivityStarts;
365 }
366
367 public boolean areBackgroundActivityStartsAllowed() {
368 return mAllowBackgroundActivityStarts;
369 }
370
Michal Karpinski4bc56492019-01-31 12:07:33 +0000371 public void setInstrumenting(boolean instrumenting,
372 boolean hasBackgroundActivityStartPrivileges) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700373 mInstrumenting = instrumenting;
Michal Karpinski4bc56492019-01-31 12:07:33 +0000374 mInstrumentingWithBackgroundActivityStartPrivileges = hasBackgroundActivityStartPrivileges;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700375 }
376
377 boolean isInstrumenting() {
378 return mInstrumenting;
379 }
380
Michal Karpinskidaef80f2019-01-29 16:50:51 +0000381 /**
Michal Karpinskidaef80f2019-01-29 16:50:51 +0000382 * @return true if the instrumentation was started by a holder of
383 * START_ACTIVITIES_FROM_BACKGROUND permission
384 */
385 boolean isInstrumentingWithBackgroundActivityStartPrivileges() {
386 return mInstrumentingWithBackgroundActivityStartPrivileges;
387 }
388
Wale Ogunwale31913b52018-10-13 08:29:31 -0700389 public void setPerceptible(boolean perceptible) {
390 mPerceptible = perceptible;
391 }
392
393 boolean isPerceptible() {
394 return mPerceptible;
395 }
396
Yunfan Chen75157d72018-07-27 14:47:21 +0900397 @Override
398 protected int getChildCount() {
399 return 0;
400 }
401
402 @Override
403 protected ConfigurationContainer getChildAt(int index) {
404 return null;
405 }
406
407 @Override
408 protected ConfigurationContainer getParent() {
409 return null;
410 }
411
Riddle Hsua0536432019-02-16 00:38:59 +0800412 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700413 public void addPackage(String packageName) {
Riddle Hsud7088f82019-01-30 13:04:50 +0800414 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700415 mPkgList.add(packageName);
416 }
417 }
418
Riddle Hsua0536432019-02-16 00:38:59 +0800419 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700420 public void clearPackageList() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800421 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700422 mPkgList.clear();
423 }
424 }
425
426 void addActivityIfNeeded(ActivityRecord r) {
427 if (mActivities.contains(r)) {
428 return;
429 }
430 mActivities.add(r);
431 }
432
433 void removeActivity(ActivityRecord r) {
434 mActivities.remove(r);
435 }
436
Riddle Hsuaaef7312019-01-24 19:00:58 +0800437 void makeFinishingForProcessRemoved() {
438 for (int i = mActivities.size() - 1; i >= 0; --i) {
439 mActivities.get(i).makeFinishingLocked();
440 }
441 }
442
Riddle Hsud7088f82019-01-30 13:04:50 +0800443 void clearActivities() {
444 mActivities.clear();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700445 }
446
Riddle Hsua0536432019-02-16 00:38:59 +0800447 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700448 public boolean hasActivities() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800449 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700450 return !mActivities.isEmpty();
451 }
452 }
453
Riddle Hsua0536432019-02-16 00:38:59 +0800454 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700455 public boolean hasVisibleActivities() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800456 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700457 for (int i = mActivities.size() - 1; i >= 0; --i) {
458 final ActivityRecord r = mActivities.get(i);
459 if (r.visible) {
460 return true;
461 }
462 }
463 }
464 return false;
465 }
466
Riddle Hsua0536432019-02-16 00:38:59 +0800467 @HotPath(caller = HotPath.LRU_UPDATE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700468 public boolean hasActivitiesOrRecentTasks() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800469 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700470 return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
471 }
472 }
473
Louis Chang77ce34d2019-01-03 15:45:12 +0800474 /**
475 * Update the top resuming activity in process for pre-Q apps, only the top-most visible
476 * activities are allowed to be resumed per process.
477 * @return {@code true} if the activity is allowed to be resumed by compatibility
478 * restrictions, which the activity was the topmost visible activity in process or the app is
479 * targeting after Q.
480 */
481 boolean updateTopResumingActivityInProcessIfNeeded(@NonNull ActivityRecord activity) {
482 if (mInfo.targetSdkVersion >= Q || mPreQTopResumedActivity == activity) {
483 return true;
484 }
485
486 final ActivityDisplay display = activity.getDisplay();
487 if (display == null) {
488 // No need to update if the activity hasn't attach to any display.
489 return false;
490 }
491
492 boolean canUpdate = false;
493 final ActivityDisplay topDisplay =
494 mPreQTopResumedActivity != null ? mPreQTopResumedActivity.getDisplay() : null;
495 // Update the topmost activity if current top activity was not on any display or no
496 // longer visible.
497 if (topDisplay == null || !mPreQTopResumedActivity.visible) {
498 canUpdate = true;
499 }
500
501 // Update the topmost activity if the current top activity wasn't on top of the other one.
502 if (!canUpdate && topDisplay.mDisplayContent.compareTo(display.mDisplayContent) < 0) {
503 canUpdate = true;
504 }
505
506 // Compare the z-order of ActivityStacks if both activities landed on same display.
507 if (display == topDisplay
508 && mPreQTopResumedActivity.getActivityStack().mTaskStack.compareTo(
509 activity.getActivityStack().mTaskStack) <= 0) {
510 canUpdate = true;
511 }
512
513 if (canUpdate) {
514 // Make sure the previous top activity in the process no longer be resumed.
515 if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) {
516 final ActivityStack stack = mPreQTopResumedActivity.getActivityStack();
517 if (stack != null) {
518 stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
519 null /* resuming */, false /* pauseImmediately */);
520 }
521 }
522 mPreQTopResumedActivity = activity;
523 }
524 return canUpdate;
525 }
526
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700527 public void stopFreezingActivities() {
528 synchronized (mAtm.mGlobalLock) {
529 int i = mActivities.size();
530 while (i > 0) {
531 i--;
532 mActivities.get(i).stopFreezingScreenLocked(true);
533 }
534 }
535 }
536
Riddle Hsud7088f82019-01-30 13:04:50 +0800537 void finishActivities() {
538 ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities);
539 for (int i = 0; i < activities.size(); i++) {
540 final ActivityRecord r = activities.get(i);
541 if (!r.finishing && r.isInStackLocked()) {
542 r.getActivityStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
543 null, "finish-heavy", true);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700544 }
545 }
546 }
547
548 public boolean isInterestingToUser() {
549 synchronized (mAtm.mGlobalLock) {
550 final int size = mActivities.size();
551 for (int i = 0; i < size; i++) {
552 ActivityRecord r = mActivities.get(i);
553 if (r.isInterestingToUserLocked()) {
554 return true;
555 }
556 }
557 }
558 return false;
559 }
560
561 public boolean hasRunningActivity(String packageName) {
562 synchronized (mAtm.mGlobalLock) {
563 for (int i = mActivities.size() - 1; i >= 0; --i) {
564 final ActivityRecord r = mActivities.get(i);
565 if (packageName.equals(r.packageName)) {
566 return true;
567 }
568 }
569 }
570 return false;
571 }
572
573 public void clearPackagePreferredForHomeActivities() {
574 synchronized (mAtm.mGlobalLock) {
575 for (int i = mActivities.size() - 1; i >= 0; --i) {
576 final ActivityRecord r = mActivities.get(i);
577 if (r.isActivityTypeHome()) {
578 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
579 try {
580 ActivityThread.getPackageManager()
581 .clearPackagePreferredActivities(r.packageName);
582 } catch (RemoteException c) {
583 // pm is in same process, this will never happen.
584 }
585 }
586 }
587 }
588 }
589
590 boolean hasStartedActivity(ActivityRecord launchedActivity) {
591 for (int i = mActivities.size() - 1; i >= 0; i--) {
592 final ActivityRecord activity = mActivities.get(i);
593 if (launchedActivity == activity) {
594 continue;
595 }
596 if (!activity.stopped) {
597 return true;
598 }
599 }
600 return false;
601 }
602
603
Riddle Hsud7088f82019-01-30 13:04:50 +0800604 void updateIntentForHeavyWeightActivity(Intent intent) {
605 if (mActivities.isEmpty()) {
606 return;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700607 }
Riddle Hsud7088f82019-01-30 13:04:50 +0800608 ActivityRecord hist = mActivities.get(0);
609 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
610 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTaskRecord().taskId);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700611 }
612
613 boolean shouldKillProcessForRemovedTask(TaskRecord tr) {
614 for (int k = 0; k < mActivities.size(); k++) {
Yunfan Chenafc15832018-07-26 16:34:28 +0900615 final ActivityRecord activity = mActivities.get(k);
616 if (!activity.stopped) {
617 // Don't kill process(es) that has an activity not stopped.
618 return false;
619 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800620 final TaskRecord otherTask = activity.getTaskRecord();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700621 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
622 // Don't kill process(es) that has an activity in a different task that is
623 // also in recents.
624 return false;
625 }
626 }
627 return true;
628 }
629
630 ArraySet<TaskRecord> getReleaseSomeActivitiesTasks() {
631 // Examine all activities currently running in the process.
632 TaskRecord firstTask = null;
633 // Tasks is non-null only if two or more tasks are found.
634 ArraySet<TaskRecord> tasks = null;
635 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this);
636 for (int i = 0; i < mActivities.size(); i++) {
637 final ActivityRecord r = mActivities.get(i);
638 // First, if we find an activity that is in the process of being destroyed,
639 // then we just aren't going to do anything for now; we want things to settle
640 // down before we try to prune more activities.
641 if (r.finishing || r.isState(DESTROYING, DESTROYED)) {
642 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
643 return null;
644 }
645 // Don't consider any activies that are currently not in a state where they
646 // can be destroyed.
647 if (r.visible || !r.stopped || !r.haveState
648 || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) {
649 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
650 continue;
651 }
652
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800653 final TaskRecord task = r.getTaskRecord();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700654 if (task != null) {
655 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task
656 + " from " + r);
657 if (firstTask == null) {
658 firstTask = task;
659 } else if (firstTask != task) {
660 if (tasks == null) {
661 tasks = new ArraySet<>();
662 tasks.add(firstTask);
663 }
664 tasks.add(task);
665 }
666 }
667 }
668
669 return tasks;
670 }
671
672 public interface ComputeOomAdjCallback {
673 void onVisibleActivity();
674 void onPausedActivity();
675 void onStoppingActivity(boolean finishing);
676 void onOtherActivity();
677 }
678
Riddle Hsua0536432019-02-16 00:38:59 +0800679 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700680 public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
Riddle Hsud7088f82019-01-30 13:04:50 +0800681 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700682 final int activitiesSize = mActivities.size();
683 for (int j = 0; j < activitiesSize; j++) {
684 final ActivityRecord r = mActivities.get(j);
685 if (r.app != this) {
686 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
687 + " instead of expected " + this);
688 if (r.app == null || (r.app.mUid == mUid)) {
689 // Only fix things up when they look sane
690 r.setProcess(this);
691 } else {
692 continue;
693 }
694 }
695 if (r.visible) {
696 callback.onVisibleActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800697 final TaskRecord task = r.getTaskRecord();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700698 if (task != null && minTaskLayer > 0) {
699 final int layer = task.mLayerRank;
700 if (layer >= 0 && minTaskLayer > layer) {
701 minTaskLayer = layer;
702 }
703 }
704 break;
705 } else if (r.isState(PAUSING, PAUSED)) {
706 callback.onPausedActivity();
707 } else if (r.isState(STOPPING)) {
708 callback.onStoppingActivity(r.finishing);
709 } else {
710 callback.onOtherActivity();
711 }
712 }
713 }
714
715 return minTaskLayer;
716 }
717
Wale Ogunwale59507092018-10-29 09:00:30 -0700718 public int computeRelaunchReason() {
Garfield Tan2746ab52018-07-25 12:33:01 -0700719 synchronized (mAtm.mGlobalLock) {
720 final int activitiesSize = mActivities.size();
721 for (int i = activitiesSize - 1; i >= 0; i--) {
722 final ActivityRecord r = mActivities.get(i);
Wale Ogunwale64258362018-10-16 15:13:37 -0700723 if (r.mRelaunchReason != RELAUNCH_REASON_NONE) {
Garfield Tan2746ab52018-07-25 12:33:01 -0700724 return r.mRelaunchReason;
725 }
726 }
727 }
Wale Ogunwale64258362018-10-16 15:13:37 -0700728 return RELAUNCH_REASON_NONE;
Garfield Tan2746ab52018-07-25 12:33:01 -0700729 }
730
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700731 public long getInputDispatchingTimeout() {
732 synchronized (mAtm.mGlobalLock) {
733 return isInstrumenting() || isUsingWrapper()
734 ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS;
735 }
736 }
737
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700738 void clearProfilerIfNeeded() {
739 if (mListener == null) return;
740 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700741 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
742 WindowProcessListener::clearProfilerIfNeeded, mListener));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700743 }
744
745 void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
746 boolean activityChange, boolean updateOomAdj) {
747 if (mListener == null) return;
748 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700749 final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700750 mListener, updateServiceConnectionActivities, updateLru, activityChange,
751 updateOomAdj);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700752 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700753 }
754
755 void updateServiceConnectionActivities() {
756 if (mListener == null) return;
757 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700758 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
759 WindowProcessListener::updateServiceConnectionActivities, mListener));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700760 }
761
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700762 void setPendingUiCleanAndForceProcessStateUpTo(int newState) {
763 if (mListener == null) return;
764 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700765 final Message m = PooledLambda.obtainMessage(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700766 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo,
767 mListener, newState);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700768 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700769 }
770
Riddle Hsuaaef7312019-01-24 19:00:58 +0800771 boolean isRemoved() {
772 return mListener == null ? false : mListener.isRemoved();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700773 }
774
Wale Ogunwale9c103022018-10-18 07:44:54 -0700775 void clearWaitingToKill() {
776 if (mListener == null) return;
777 // Posting on handler so WM lock isn't held when we call into AM.
778 final Message m = PooledLambda.obtainMessage(
779 WindowProcessListener::clearWaitingToKill, mListener);
780 mAtm.mH.sendMessage(m);
781 }
782
783 void addPackage(String pkg, long versionCode) {
Wale Ogunwale9c103022018-10-18 07:44:54 -0700784 if (mListener == null) return;
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800785 // Posting on handler so WM lock isn't held when we call into AM.
786 final Message m = PooledLambda.obtainMessage(
787 WindowProcessListener::addPackage, mListener, pkg, versionCode);
788 mAtm.mH.sendMessage(m);
Wale Ogunwale9c103022018-10-18 07:44:54 -0700789 }
790
791 ProfilerInfo onStartActivity(int topProcessState) {
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800792 ProfilerInfo profilerInfo = null;
793 boolean setProfileProc = false;
794 if (mAtm.mProfileApp != null
795 && mAtm.mProfileApp.equals(mName)) {
796 if (mAtm.mProfileProc == null || mAtm.mProfileProc == this) {
797 setProfileProc = true;
798 final ProfilerInfo profilerInfoSvc = mAtm.mProfilerInfo;
799 if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
800 if (profilerInfoSvc.profileFd != null) {
801 try {
802 profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
803 } catch (IOException e) {
804 profilerInfoSvc.closeFd();
805 }
806 }
807
808 profilerInfo = new ProfilerInfo(profilerInfoSvc);
809 }
810 }
811 }
812
813
814 if (mListener != null) {
815 // Posting on handler so WM lock isn't held when we call into AM.
816 final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
817 mListener, topProcessState, setProfileProc);
818 mAtm.mH.sendMessage(m);
819 }
820
821 return profilerInfo;
Wale Ogunwale9c103022018-10-18 07:44:54 -0700822 }
823
824 public void appDied() {
Wale Ogunwale9c103022018-10-18 07:44:54 -0700825 if (mListener == null) return;
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800826 // Posting on handler so WM lock isn't held when we call into AM.
827 final Message m = PooledLambda.obtainMessage(
828 WindowProcessListener::appDied, mListener);
829 mAtm.mH.sendMessage(m);
Wale Ogunwale9c103022018-10-18 07:44:54 -0700830 }
831
Yunfan Chen79b96062018-10-17 12:45:23 -0700832 void registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay) {
833 if (activityDisplay == null) {
834 return;
835 }
836 // A process can only register to one display to listener to the override configuration
837 // change. Unregister existing listener if it has one before register the new one.
838 unregisterDisplayConfigurationListenerLocked();
839 mDisplayId = activityDisplay.mDisplayId;
840 activityDisplay.registerConfigurationChangeListener(this);
841 }
842
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900843 @VisibleForTesting
844 void unregisterDisplayConfigurationListenerLocked() {
Yunfan Chen79b96062018-10-17 12:45:23 -0700845 if (mDisplayId == INVALID_DISPLAY) {
846 return;
847 }
848 final ActivityDisplay activityDisplay =
Wale Ogunwaled32da472018-11-16 07:19:28 -0800849 mAtm.mRootActivityContainer.getActivityDisplay(mDisplayId);
Yunfan Chen79b96062018-10-17 12:45:23 -0700850 if (activityDisplay != null) {
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900851 activityDisplay.unregisterConfigurationChangeListener(this);
Yunfan Chen79b96062018-10-17 12:45:23 -0700852 }
853 mDisplayId = INVALID_DISPLAY;
854 }
855
Yunfan Chen75157d72018-07-27 14:47:21 +0900856 @Override
857 public void onConfigurationChanged(Configuration newGlobalConfig) {
858 super.onConfigurationChanged(newGlobalConfig);
859 updateConfiguration();
860 }
861
862 @Override
Evan Roskydfe3da72018-10-26 17:21:06 -0700863 public void onRequestedOverrideConfigurationChanged(Configuration newOverrideConfig) {
864 super.onRequestedOverrideConfigurationChanged(newOverrideConfig);
Yunfan Chen75157d72018-07-27 14:47:21 +0900865 updateConfiguration();
866 }
867
868 private void updateConfiguration() {
869 final Configuration config = getConfiguration();
870 if (mLastReportedConfiguration.diff(config) == 0) {
871 // Nothing changed.
872 return;
873 }
874
875 try {
876 if (mThread == null) {
877 return;
878 }
879 if (DEBUG_CONFIGURATION) {
880 Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName
881 + " new config " + config);
882 }
883 config.seq = mAtm.increaseConfigurationSeqLocked();
884 mAtm.getLifecycleManager().scheduleTransaction(mThread,
885 ConfigurationChangeItem.obtain(config));
886 setLastReportedConfiguration(config);
887 } catch (Exception e) {
888 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
889 }
890 }
891
892 private void setLastReportedConfiguration(Configuration config) {
893 mLastReportedConfiguration.setTo(config);
894 }
895
896 Configuration getLastReportedConfiguration() {
897 return mLastReportedConfiguration;
898 }
899
Wale Ogunwale86b74462018-07-02 08:42:43 -0700900 /** Returns the total time (in milliseconds) spent executing in both user and system code. */
901 public long getCpuTime() {
902 return (mListener != null) ? mListener.getCpuTime() : 0;
903 }
904
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700905 void addRecentTask(TaskRecord task) {
906 mRecentTasks.add(task);
907 }
908
909 void removeRecentTask(TaskRecord task) {
910 mRecentTasks.remove(task);
911 }
912
Riddle Hsua0536432019-02-16 00:38:59 +0800913 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700914 public boolean hasRecentTasks() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800915 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700916 return !mRecentTasks.isEmpty();
917 }
918 }
919
Riddle Hsud7088f82019-01-30 13:04:50 +0800920 void clearRecentTasks() {
921 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
922 mRecentTasks.get(i).clearRootProcess();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700923 }
Riddle Hsud7088f82019-01-30 13:04:50 +0800924 mRecentTasks.clear();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700925 }
926
Wale Ogunwalee2172292018-10-25 10:11:10 -0700927 public void appEarlyNotResponding(String annotation, Runnable killAppCallback) {
928 synchronized (mAtm.mGlobalLock) {
929 if (mAtm.mController == null) {
930 return;
931 }
932
933 try {
934 // 0 == continue, -1 = kill process immediately
935 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation);
936 if (res < 0 && mPid != MY_PID) {
937 killAppCallback.run();
938 }
939 } catch (RemoteException e) {
940 mAtm.mController = null;
941 Watchdog.getInstance().setActivityController(null);
942 }
943 }
944 }
945
946 public boolean appNotResponding(String info, Runnable killAppCallback,
947 Runnable serviceTimeoutCallback) {
Jeff Changed2f5bc2019-01-24 19:33:28 +0800948 Runnable targetRunnable = null;
Wale Ogunwalee2172292018-10-25 10:11:10 -0700949 synchronized (mAtm.mGlobalLock) {
950 if (mAtm.mController == null) {
951 return false;
952 }
953
954 try {
955 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
956 int res = mAtm.mController.appNotResponding(mName, mPid, info);
957 if (res != 0) {
958 if (res < 0 && mPid != MY_PID) {
Jeff Changed2f5bc2019-01-24 19:33:28 +0800959 targetRunnable = killAppCallback;
Wale Ogunwalee2172292018-10-25 10:11:10 -0700960 } else {
Jeff Changed2f5bc2019-01-24 19:33:28 +0800961 targetRunnable = serviceTimeoutCallback;
Wale Ogunwalee2172292018-10-25 10:11:10 -0700962 }
Wale Ogunwalee2172292018-10-25 10:11:10 -0700963 }
964 } catch (RemoteException e) {
965 mAtm.mController = null;
966 Watchdog.getInstance().setActivityController(null);
Jeff Changed2f5bc2019-01-24 19:33:28 +0800967 return false;
Wale Ogunwalee2172292018-10-25 10:11:10 -0700968 }
Wale Ogunwalee2172292018-10-25 10:11:10 -0700969 }
Jeff Changed2f5bc2019-01-24 19:33:28 +0800970 if (targetRunnable != null) {
971 targetRunnable.run();
972 return true;
973 }
974 return false;
Wale Ogunwalee2172292018-10-25 10:11:10 -0700975 }
976
Riddle Hsua0536432019-02-16 00:38:59 +0800977 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalee2172292018-10-25 10:11:10 -0700978 public void onTopProcChanged() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800979 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwalee2172292018-10-25 10:11:10 -0700980 mAtm.mVrController.onTopProcChangedLocked(this);
981 }
982 }
983
Riddle Hsua0536432019-02-16 00:38:59 +0800984 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwaled4d67d02018-10-25 18:09:39 -0700985 public boolean isHomeProcess() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800986 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwaled4d67d02018-10-25 18:09:39 -0700987 return this == mAtm.mHomeProcess;
988 }
989 }
990
Riddle Hsua0536432019-02-16 00:38:59 +0800991 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwaled4d67d02018-10-25 18:09:39 -0700992 public boolean isPreviousProcess() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800993 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwaled4d67d02018-10-25 18:09:39 -0700994 return this == mAtm.mPreviousProcess;
995 }
996 }
997
Wale Ogunwale2a47d122018-11-19 16:49:40 -0800998 @Override
999 public String toString() {
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001000 return mOwner != null ? mOwner.toString() : null;
Wale Ogunwale2a47d122018-11-19 16:49:40 -08001001 }
1002
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001003 public void dump(PrintWriter pw, String prefix) {
1004 synchronized (mAtm.mGlobalLock) {
1005 if (mActivities.size() > 0) {
1006 pw.print(prefix); pw.println("Activities:");
1007 for (int i = 0; i < mActivities.size(); i++) {
1008 pw.print(prefix); pw.print(" - "); pw.println(mActivities.get(i));
1009 }
1010 }
1011
1012 if (mRecentTasks.size() > 0) {
1013 pw.println(prefix + "Recent Tasks:");
1014 for (int i = 0; i < mRecentTasks.size(); i++) {
1015 pw.println(prefix + " - " + mRecentTasks.get(i));
1016 }
1017 }
1018
1019 if (mVrThreadTid != 0) {
1020 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid);
1021 }
1022 }
Yunfan Chen75157d72018-07-27 14:47:21 +09001023 pw.println(prefix + " Configuration=" + getConfiguration());
Evan Roskydfe3da72018-10-26 17:21:06 -07001024 pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
Yunfan Chen75157d72018-07-27 14:47:21 +09001025 pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001026 }
1027
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07001028 void writeToProto(ProtoOutputStream proto, long fieldId) {
1029 if (mListener != null) {
1030 mListener.writeToProto(proto, fieldId);
1031 }
1032 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001033}