blob: 41e88c8f763b0e691422bb0ae0c1e8f187910699 [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;
Louis Changeadb22f2019-06-19 12:09:23 +080029import static com.android.server.wm.ActivityStack.ActivityState.STARTED;
Wale Ogunwale59507092018-10-29 09:00:30 -070030import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
31import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
32import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
33import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
34import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
35import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
36import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
Michal Karpinskifc6872e2019-05-21 15:18:44 +010037import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
Louis Chang77ce34d2019-01-03 15:45:12 +080038import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale59507092018-10-29 09:00:30 -070039import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
40import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070041
Louis Chang77ce34d2019-01-03 15:45:12 +080042import android.annotation.NonNull;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070043import android.app.ActivityThread;
44import android.app.IApplicationThread;
Wale Ogunwale9c103022018-10-18 07:44:54 -070045import android.app.ProfilerInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +090046import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070047import android.content.Intent;
Riddle Hsu17e38422019-04-12 16:55:11 +080048import android.content.pm.ActivityInfo;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070049import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +090050import android.content.res.Configuration;
lumarkddc77fb2019-06-27 22:22:23 +080051import android.os.Build;
Yohei Yukawae2fa39e2018-09-22 13:13:10 -070052import android.os.Message;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070053import android.os.RemoteException;
Michal Karpinskifc6872e2019-05-21 15:18:44 +010054import android.os.SystemClock;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070055import android.util.ArraySet;
56import android.util.Log;
57import android.util.Slog;
Wale Ogunwale51cc98a2018-10-15 10:41:05 -070058import android.util.proto.ProtoOutputStream;
Jorim Jaggi589c5ba2019-07-30 16:50:13 +020059import android.view.IRemoteAnimationRunner;
Yunfan Chen79b96062018-10-17 12:45:23 -070060
Yunfan Chenb29cbfd2019-01-24 17:30:33 +090061import com.android.internal.annotations.VisibleForTesting;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070062import com.android.internal.app.HeavyWeightSwitcherActivity;
63import com.android.internal.util.function.pooled.PooledLambda;
Wale Ogunwalee2172292018-10-25 10:11:10 -070064import com.android.server.Watchdog;
Riddle Hsua0536432019-02-16 00:38:59 +080065import com.android.server.wm.ActivityTaskManagerService.HotPath;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070066
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -080067import java.io.IOException;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070068import java.io.PrintWriter;
69import java.util.ArrayList;
70
71/**
72 * The Activity Manager (AM) package manages the lifecycle of processes in the system through
Wale Ogunwale59507092018-10-29 09:00:30 -070073 * ProcessRecord. However, it is important for the Window Manager (WM) package to be aware
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070074 * of the processes and their state since it affects how WM manages windows and activities. This
Wale Ogunwale59507092018-10-29 09:00:30 -070075 * class that allows the ProcessRecord object in the AM package to communicate important
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070076 * changes to its state to the WM package in a structured way. WM package also uses
77 * {@link WindowProcessListener} to request changes to the process state on the AM side.
78 * Note that public calls into this class are assumed to be originating from outside the
79 * window manager so the window manager lock is held and appropriate permissions are checked before
80 * calls are allowed to proceed.
81 */
Yunfan Chen79b96062018-10-17 12:45:23 -070082public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
83 implements ConfigurationContainerListener {
Wale Ogunwale98875612018-10-12 07:53:02 -070084 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070085 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
Yunfan Chen75157d72018-07-27 14:47:21 +090086 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070087
88 // all about the first app in the process
89 final ApplicationInfo mInfo;
90 final String mName;
91 final int mUid;
92 // The process of this application; 0 if none
93 private volatile int mPid;
94 // user of process.
95 final int mUserId;
96 // The owner of this window process controller object. Mainly for identification when we
97 // communicate back to the activity manager side.
98 public final Object mOwner;
99 // List of packages running in the process
100 final ArraySet<String> mPkgList = new ArraySet<>();
101 private final WindowProcessListener mListener;
102 private final ActivityTaskManagerService mAtm;
103 // The actual proc... may be null only if 'persistent' is true (in which case we are in the
104 // process of launching the app)
Louis Chang4221d792019-04-17 17:15:01 +0800105 private IApplicationThread mThread;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700106 // Currently desired scheduling class
107 private volatile int mCurSchedGroup;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700108 // Currently computed process state
109 private volatile int mCurProcState = PROCESS_STATE_NONEXISTENT;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700110 // Last reported process state;
111 private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT;
112 // are we in the process of crashing?
113 private volatile boolean mCrashing;
114 // does the app have a not responding dialog?
115 private volatile boolean mNotResponding;
116 // always keep this application running?
117 private volatile boolean mPersistent;
118 // The ABI this process was launched with
119 private volatile String mRequiredAbi;
120 // Running any services that are foreground?
121 private volatile boolean mHasForegroundServices;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700122 // Running any activities that are foreground?
123 private volatile boolean mHasForegroundActivities;
124 // Are there any client services with activities?
125 private volatile boolean mHasClientActivities;
126 // Is this process currently showing a non-activity UI that the user is interacting with?
127 // E.g. The status bar when it is expanded, but not when it is minimized. When true the process
128 // will be set to use the ProcessList#SCHED_GROUP_TOP_APP scheduling group to boost performance.
129 private volatile boolean mHasTopUi;
130 // Is the process currently showing a non-activity UI that overlays on-top of activity UIs on
131 // screen. E.g. display a window of type
132 // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY When true the process will
133 // oom adj score will be set to ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
134 // of the process getting killed.
135 private volatile boolean mHasOverlayUi;
136 // Want to clean up resources from showing UI?
137 private volatile boolean mPendingUiClean;
138 // The time we sent the last interaction event
139 private volatile long mInteractionEventTime;
140 // When we became foreground for interaction purposes
141 private volatile long mFgInteractionTime;
142 // When (uptime) the process last became unimportant
143 private volatile long mWhenUnimportant;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700144 // was app launched for debugging?
145 private volatile boolean mDebugging;
146 // Active instrumentation running in process?
147 private volatile boolean mInstrumenting;
Michal Karpinskidaef80f2019-01-29 16:50:51 +0000148 // Active instrumentation with background activity starts privilege running in process?
149 private volatile boolean mInstrumentingWithBackgroundActivityStartPrivileges;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700150 // This process it perceptible by the user.
151 private volatile boolean mPerceptible;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700152 // Set to true when process was launched with a wrapper attached
153 private volatile boolean mUsingWrapper;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000154 // Set to true if this process is currently temporarily whitelisted to start activities even if
155 // it's not in the foreground
156 private volatile boolean mAllowBackgroundActivityStarts;
Michal Karpinskib7daac22019-03-25 10:12:41 +0000157 // Set of UIDs of clients currently bound to this process
158 private volatile ArraySet<Integer> mBoundClientUids = new ArraySet<Integer>();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700159
160 // Thread currently set for VR scheduling
161 int mVrThreadTid;
162
lumarkddc77fb2019-06-27 22:22:23 +0800163 boolean mIsImeProcess;
164
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700165 // all activities running in the process
166 private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
167 // any tasks this process had run root activities in
Louis Changcdec0802019-11-11 11:45:07 +0800168 private final ArrayList<Task> mRecentTasks = new ArrayList<>();
Louis Chang77ce34d2019-01-03 15:45:12 +0800169 // The most recent top-most activity that was resumed in the process for pre-Q app.
170 private ActivityRecord mPreQTopResumedActivity = null;
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100171 // The last time an activity was launched in the process
172 private long mLastActivityLaunchTime;
173 // The last time an activity was finished in the process while the process participated
174 // in a visible task
175 private long mLastActivityFinishTime;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700176
Yunfan Chen75157d72018-07-27 14:47:21 +0900177 // Last configuration that was reported to the process.
178 private final Configuration mLastReportedConfiguration;
Yunfan Chen79b96062018-10-17 12:45:23 -0700179 // Registered display id as a listener to override config change
180 private int mDisplayId;
Yunfan Chen75157d72018-07-27 14:47:21 +0900181
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200182 /** Whether our process is currently running a {@link RecentsAnimation} */
183 private boolean mRunningRecentsAnimation;
184
185 /** Whether our process is currently running a {@link IRemoteAnimationRunner} */
186 private boolean mRunningRemoteAnimation;
187
Wale Ogunwale59507092018-10-29 09:00:30 -0700188 public WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info,
189 String name, int uid, int userId, Object owner, WindowProcessListener listener) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700190 mInfo = info;
191 mName = name;
192 mUid = uid;
193 mUserId = userId;
194 mOwner = owner;
195 mListener = listener;
196 mAtm = atm;
Yunfan Chen75157d72018-07-27 14:47:21 +0900197 mLastReportedConfiguration = new Configuration();
Yunfan Chen79b96062018-10-17 12:45:23 -0700198 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700199 if (atm != null) {
200 onConfigurationChanged(atm.getGlobalConfiguration());
Yunfan Chen75157d72018-07-27 14:47:21 +0900201 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700202 }
203
204 public void setPid(int pid) {
205 mPid = pid;
206 }
207
Wale Ogunwale59507092018-10-29 09:00:30 -0700208 public int getPid() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700209 return mPid;
210 }
211
Louis Chang4221d792019-04-17 17:15:01 +0800212 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700213 public void setThread(IApplicationThread thread) {
Louis Chang4221d792019-04-17 17:15:01 +0800214 synchronized (mAtm.mGlobalLockWithoutBoost) {
215 mThread = thread;
216 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700217 }
218
219 IApplicationThread getThread() {
220 return mThread;
221 }
222
223 boolean hasThread() {
224 return mThread != null;
225 }
226
227 public void setCurrentSchedulingGroup(int curSchedGroup) {
228 mCurSchedGroup = curSchedGroup;
229 }
230
231 int getCurrentSchedulingGroup() {
232 return mCurSchedGroup;
233 }
234
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700235 public void setCurrentProcState(int curProcState) {
236 mCurProcState = curProcState;
237 }
238
239 int getCurrentProcState() {
240 return mCurProcState;
241 }
242
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700243 public void setReportedProcState(int repProcState) {
244 mRepProcState = repProcState;
245 }
246
247 int getReportedProcState() {
248 return mRepProcState;
249 }
250
251 public void setCrashing(boolean crashing) {
252 mCrashing = crashing;
253 }
254
255 boolean isCrashing() {
256 return mCrashing;
257 }
258
259 public void setNotResponding(boolean notResponding) {
260 mNotResponding = notResponding;
261 }
262
263 boolean isNotResponding() {
264 return mNotResponding;
265 }
266
267 public void setPersistent(boolean persistent) {
268 mPersistent = persistent;
269 }
270
271 boolean isPersistent() {
272 return mPersistent;
273 }
274
275 public void setHasForegroundServices(boolean hasForegroundServices) {
276 mHasForegroundServices = hasForegroundServices;
277 }
278
279 boolean hasForegroundServices() {
280 return mHasForegroundServices;
281 }
282
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700283 public void setHasForegroundActivities(boolean hasForegroundActivities) {
284 mHasForegroundActivities = hasForegroundActivities;
285 }
286
287 boolean hasForegroundActivities() {
288 return mHasForegroundActivities;
289 }
290
291 public void setHasClientActivities(boolean hasClientActivities) {
292 mHasClientActivities = hasClientActivities;
293 }
294
295 boolean hasClientActivities() {
296 return mHasClientActivities;
297 }
298
299 public void setHasTopUi(boolean hasTopUi) {
300 mHasTopUi = hasTopUi;
301 }
302
303 boolean hasTopUi() {
304 return mHasTopUi;
305 }
306
307 public void setHasOverlayUi(boolean hasOverlayUi) {
308 mHasOverlayUi = hasOverlayUi;
309 }
310
311 boolean hasOverlayUi() {
312 return mHasOverlayUi;
313 }
314
315 public void setPendingUiClean(boolean hasPendingUiClean) {
316 mPendingUiClean = hasPendingUiClean;
317 }
318
319 boolean hasPendingUiClean() {
320 return mPendingUiClean;
321 }
322
Yunfan Chenb4fe58c2019-03-27 18:35:06 +0900323 /** @return {@code true} if the process registered to a display as a config listener. */
324 boolean registeredForDisplayConfigChanges() {
325 return mDisplayId != INVALID_DISPLAY;
326 }
327
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700328 void postPendingUiCleanMsg(boolean pendingUiClean) {
329 if (mListener == null) return;
330 // Posting on handler so WM lock isn't held when we call into AM.
331 final Message m = PooledLambda.obtainMessage(
332 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
333 mAtm.mH.sendMessage(m);
334 }
335
336 public void setInteractionEventTime(long interactionEventTime) {
337 mInteractionEventTime = interactionEventTime;
338 }
339
340 long getInteractionEventTime() {
341 return mInteractionEventTime;
342 }
343
344 public void setFgInteractionTime(long fgInteractionTime) {
345 mFgInteractionTime = fgInteractionTime;
346 }
347
348 long getFgInteractionTime() {
349 return mFgInteractionTime;
350 }
351
352 public void setWhenUnimportant(long whenUnimportant) {
353 mWhenUnimportant = whenUnimportant;
354 }
355
356 long getWhenUnimportant() {
357 return mWhenUnimportant;
358 }
359
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700360 public void setRequiredAbi(String requiredAbi) {
361 mRequiredAbi = requiredAbi;
362 }
363
364 String getRequiredAbi() {
365 return mRequiredAbi;
366 }
367
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900368 /** Returns ID of display overriding the configuration for this process, or
369 * INVALID_DISPLAY if no display is overriding. */
370 @VisibleForTesting
371 int getDisplayId() {
372 return mDisplayId;
373 }
374
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700375 public void setDebugging(boolean debugging) {
376 mDebugging = debugging;
377 }
378
379 boolean isDebugging() {
380 return mDebugging;
381 }
382
383 public void setUsingWrapper(boolean usingWrapper) {
384 mUsingWrapper = usingWrapper;
385 }
386
387 boolean isUsingWrapper() {
388 return mUsingWrapper;
389 }
390
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100391 void setLastActivityLaunchTime(long launchTime) {
392 if (launchTime <= mLastActivityLaunchTime) {
393 return;
394 }
395 mLastActivityLaunchTime = launchTime;
396 }
397
398 void setLastActivityFinishTimeIfNeeded(long finishTime) {
399 if (finishTime <= mLastActivityFinishTime || !hasActivityInVisibleTask()) {
400 return;
401 }
402 mLastActivityFinishTime = finishTime;
403 }
404
Michal Karpinskiac116df2018-12-10 17:51:42 +0000405 public void setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts) {
406 mAllowBackgroundActivityStarts = allowBackgroundActivityStarts;
407 }
408
Michal Karpinski2e0aad22019-04-12 16:22:55 +0100409 boolean areBackgroundActivityStartsAllowed() {
410 // allow if the whitelisting flag was explicitly set
411 if (mAllowBackgroundActivityStarts) {
412 return true;
413 }
Ricky Wai906af482019-06-03 17:25:28 +0100414 // allow if any activity in the caller has either started or finished very recently, and
415 // it must be started or finished after last stop app switches time.
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100416 final long now = SystemClock.uptimeMillis();
417 if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
418 || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
Ricky Wai906af482019-06-03 17:25:28 +0100419 // if activity is started and finished before stop app switch time, we should not
420 // let app to be able to start background activity even it's in grace period.
421 if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
422 || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
423 return true;
424 }
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100425 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +0100426 // allow if the proc is instrumenting with background activity starts privs
427 if (mInstrumentingWithBackgroundActivityStartPrivileges) {
428 return true;
429 }
430 // allow if the caller has an activity in any foreground task
431 if (hasActivityInVisibleTask()) {
432 return true;
433 }
434 // allow if the caller is bound by a UID that's currently foreground
435 if (isBoundByForegroundUid()) {
436 return true;
437 }
438 return false;
439 }
440
441 private boolean isBoundByForegroundUid() {
442 for (int i = mBoundClientUids.size() - 1; i >= 0; --i) {
443 if (mAtm.isUidForeground(mBoundClientUids.valueAt(i))) {
444 return true;
445 }
446 }
447 return false;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000448 }
449
Michal Karpinskib7daac22019-03-25 10:12:41 +0000450 public void setBoundClientUids(ArraySet<Integer> boundClientUids) {
451 mBoundClientUids = boundClientUids;
452 }
453
Michal Karpinski4bc56492019-01-31 12:07:33 +0000454 public void setInstrumenting(boolean instrumenting,
455 boolean hasBackgroundActivityStartPrivileges) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700456 mInstrumenting = instrumenting;
Michal Karpinski4bc56492019-01-31 12:07:33 +0000457 mInstrumentingWithBackgroundActivityStartPrivileges = hasBackgroundActivityStartPrivileges;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700458 }
459
460 boolean isInstrumenting() {
461 return mInstrumenting;
462 }
463
Wale Ogunwale31913b52018-10-13 08:29:31 -0700464 public void setPerceptible(boolean perceptible) {
465 mPerceptible = perceptible;
466 }
467
468 boolean isPerceptible() {
469 return mPerceptible;
470 }
471
Yunfan Chen75157d72018-07-27 14:47:21 +0900472 @Override
473 protected int getChildCount() {
474 return 0;
475 }
476
477 @Override
478 protected ConfigurationContainer getChildAt(int index) {
479 return null;
480 }
481
482 @Override
483 protected ConfigurationContainer getParent() {
Andrii Kulian859f0a52019-05-20 12:18:09 +0000484 return null;
Yunfan Chen75157d72018-07-27 14:47:21 +0900485 }
486
Riddle Hsua0536432019-02-16 00:38:59 +0800487 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700488 public void addPackage(String packageName) {
Riddle Hsud7088f82019-01-30 13:04:50 +0800489 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700490 mPkgList.add(packageName);
491 }
492 }
493
Riddle Hsua0536432019-02-16 00:38:59 +0800494 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700495 public void clearPackageList() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800496 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700497 mPkgList.clear();
498 }
499 }
500
501 void addActivityIfNeeded(ActivityRecord r) {
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100502 // even if we already track this activity, note down that it has been launched
503 setLastActivityLaunchTime(r.lastLaunchTime);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700504 if (mActivities.contains(r)) {
505 return;
506 }
507 mActivities.add(r);
508 }
509
510 void removeActivity(ActivityRecord r) {
511 mActivities.remove(r);
512 }
513
Riddle Hsuaaef7312019-01-24 19:00:58 +0800514 void makeFinishingForProcessRemoved() {
515 for (int i = mActivities.size() - 1; i >= 0; --i) {
516 mActivities.get(i).makeFinishingLocked();
517 }
518 }
519
Riddle Hsud7088f82019-01-30 13:04:50 +0800520 void clearActivities() {
521 mActivities.clear();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700522 }
523
Riddle Hsua0536432019-02-16 00:38:59 +0800524 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700525 public boolean hasActivities() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800526 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700527 return !mActivities.isEmpty();
528 }
529 }
530
Riddle Hsua0536432019-02-16 00:38:59 +0800531 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700532 public boolean hasVisibleActivities() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800533 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700534 for (int i = mActivities.size() - 1; i >= 0; --i) {
535 final ActivityRecord r = mActivities.get(i);
Issei Suzuki430a1112019-11-14 16:20:52 +0100536 if (r.visible) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700537 return true;
538 }
539 }
540 }
541 return false;
542 }
543
Riddle Hsua0536432019-02-16 00:38:59 +0800544 @HotPath(caller = HotPath.LRU_UPDATE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700545 public boolean hasActivitiesOrRecentTasks() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800546 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700547 return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
548 }
549 }
550
Michal Karpinski2e0aad22019-04-12 16:22:55 +0100551 private boolean hasActivityInVisibleTask() {
Michal Karpinskicb6873c2019-03-26 17:12:25 +0000552 for (int i = mActivities.size() - 1; i >= 0; --i) {
Louis Changcdec0802019-11-11 11:45:07 +0800553 Task task = mActivities.get(i).getTask();
Michal Karpinskicb6873c2019-03-26 17:12:25 +0000554 if (task == null) {
555 continue;
556 }
Wale Ogunwale21e06482019-11-18 05:14:15 -0800557 ActivityRecord topActivity = task.getTopNonFinishingActivity();
Issei Suzuki430a1112019-11-14 16:20:52 +0100558 if (topActivity != null && topActivity.visible) {
Michal Karpinskicb6873c2019-03-26 17:12:25 +0000559 return true;
560 }
561 }
562 return false;
563 }
564
Louis Chang77ce34d2019-01-03 15:45:12 +0800565 /**
566 * Update the top resuming activity in process for pre-Q apps, only the top-most visible
567 * activities are allowed to be resumed per process.
568 * @return {@code true} if the activity is allowed to be resumed by compatibility
569 * restrictions, which the activity was the topmost visible activity in process or the app is
Hongwei Wangacad2442019-07-24 11:23:57 -0700570 * targeting after Q. Note that non-focusable activity, in picture-in-picture mode for instance,
571 * does not count as a topmost activity.
Louis Chang77ce34d2019-01-03 15:45:12 +0800572 */
573 boolean updateTopResumingActivityInProcessIfNeeded(@NonNull ActivityRecord activity) {
574 if (mInfo.targetSdkVersion >= Q || mPreQTopResumedActivity == activity) {
575 return true;
576 }
577
578 final ActivityDisplay display = activity.getDisplay();
579 if (display == null) {
580 // No need to update if the activity hasn't attach to any display.
581 return false;
582 }
583
584 boolean canUpdate = false;
585 final ActivityDisplay topDisplay =
586 mPreQTopResumedActivity != null ? mPreQTopResumedActivity.getDisplay() : null;
Hongwei Wangacad2442019-07-24 11:23:57 -0700587 // Update the topmost activity if current top activity is
588 // - not on any display OR
589 // - no longer visible OR
590 // - not focusable (in PiP mode for instance)
591 if (topDisplay == null
Issei Suzuki430a1112019-11-14 16:20:52 +0100592 || !mPreQTopResumedActivity.visible
Hongwei Wangacad2442019-07-24 11:23:57 -0700593 || !mPreQTopResumedActivity.isFocusable()) {
Louis Chang77ce34d2019-01-03 15:45:12 +0800594 canUpdate = true;
595 }
596
597 // Update the topmost activity if the current top activity wasn't on top of the other one.
598 if (!canUpdate && topDisplay.mDisplayContent.compareTo(display.mDisplayContent) < 0) {
599 canUpdate = true;
600 }
601
602 // Compare the z-order of ActivityStacks if both activities landed on same display.
603 if (display == topDisplay
Wale Ogunwalebebd8cd2019-10-28 15:53:31 -0700604 && mPreQTopResumedActivity.getActivityStack().compareTo(
605 activity.getActivityStack()) <= 0) {
Louis Chang77ce34d2019-01-03 15:45:12 +0800606 canUpdate = true;
607 }
608
609 if (canUpdate) {
610 // Make sure the previous top activity in the process no longer be resumed.
611 if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) {
612 final ActivityStack stack = mPreQTopResumedActivity.getActivityStack();
613 if (stack != null) {
614 stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
Louis Chang7b03ad92019-08-21 12:32:33 +0800615 activity);
Louis Chang77ce34d2019-01-03 15:45:12 +0800616 }
617 }
618 mPreQTopResumedActivity = activity;
619 }
620 return canUpdate;
621 }
622
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700623 public void stopFreezingActivities() {
624 synchronized (mAtm.mGlobalLock) {
625 int i = mActivities.size();
626 while (i > 0) {
627 i--;
628 mActivities.get(i).stopFreezingScreenLocked(true);
629 }
630 }
631 }
632
Riddle Hsud7088f82019-01-30 13:04:50 +0800633 void finishActivities() {
634 ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities);
635 for (int i = 0; i < activities.size(); i++) {
636 final ActivityRecord r = activities.get(i);
637 if (!r.finishing && r.isInStackLocked()) {
Andrii Kulian7dd39bb2019-07-22 13:11:10 -0700638 r.finishIfPossible("finish-heavy", true /* oomAdj */);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700639 }
640 }
641 }
642
643 public boolean isInterestingToUser() {
644 synchronized (mAtm.mGlobalLock) {
645 final int size = mActivities.size();
646 for (int i = 0; i < size; i++) {
647 ActivityRecord r = mActivities.get(i);
648 if (r.isInterestingToUserLocked()) {
649 return true;
650 }
651 }
652 }
653 return false;
654 }
655
656 public boolean hasRunningActivity(String packageName) {
657 synchronized (mAtm.mGlobalLock) {
658 for (int i = mActivities.size() - 1; i >= 0; --i) {
659 final ActivityRecord r = mActivities.get(i);
660 if (packageName.equals(r.packageName)) {
661 return true;
662 }
663 }
664 }
665 return false;
666 }
667
668 public void clearPackagePreferredForHomeActivities() {
669 synchronized (mAtm.mGlobalLock) {
670 for (int i = mActivities.size() - 1; i >= 0; --i) {
671 final ActivityRecord r = mActivities.get(i);
672 if (r.isActivityTypeHome()) {
673 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
674 try {
675 ActivityThread.getPackageManager()
676 .clearPackagePreferredActivities(r.packageName);
677 } catch (RemoteException c) {
678 // pm is in same process, this will never happen.
679 }
680 }
681 }
682 }
683 }
684
685 boolean hasStartedActivity(ActivityRecord launchedActivity) {
686 for (int i = mActivities.size() - 1; i >= 0; i--) {
687 final ActivityRecord activity = mActivities.get(i);
688 if (launchedActivity == activity) {
689 continue;
690 }
691 if (!activity.stopped) {
692 return true;
693 }
694 }
695 return false;
696 }
697
698
Riddle Hsud7088f82019-01-30 13:04:50 +0800699 void updateIntentForHeavyWeightActivity(Intent intent) {
700 if (mActivities.isEmpty()) {
701 return;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700702 }
Riddle Hsud7088f82019-01-30 13:04:50 +0800703 ActivityRecord hist = mActivities.get(0);
704 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
Louis Changcdec0802019-11-11 11:45:07 +0800705 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTask().mTaskId);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700706 }
707
Louis Changcdec0802019-11-11 11:45:07 +0800708 boolean shouldKillProcessForRemovedTask(Task task) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700709 for (int k = 0; k < mActivities.size(); k++) {
Yunfan Chenafc15832018-07-26 16:34:28 +0900710 final ActivityRecord activity = mActivities.get(k);
711 if (!activity.stopped) {
712 // Don't kill process(es) that has an activity not stopped.
713 return false;
714 }
Louis Changcdec0802019-11-11 11:45:07 +0800715 final Task otherTask = activity.getTask();
716 if (task.mTaskId != otherTask.mTaskId && otherTask.inRecents) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700717 // Don't kill process(es) that has an activity in a different task that is
718 // also in recents.
719 return false;
720 }
721 }
722 return true;
723 }
724
Louis Changcdec0802019-11-11 11:45:07 +0800725 ArraySet<Task> getReleaseSomeActivitiesTasks() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700726 // Examine all activities currently running in the process.
Louis Changcdec0802019-11-11 11:45:07 +0800727 Task firstTask = null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700728 // Tasks is non-null only if two or more tasks are found.
Louis Changcdec0802019-11-11 11:45:07 +0800729 ArraySet<Task> tasks = null;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700730 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this);
731 for (int i = 0; i < mActivities.size(); i++) {
732 final ActivityRecord r = mActivities.get(i);
733 // First, if we find an activity that is in the process of being destroyed,
734 // then we just aren't going to do anything for now; we want things to settle
735 // down before we try to prune more activities.
736 if (r.finishing || r.isState(DESTROYING, DESTROYED)) {
737 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
738 return null;
739 }
Louis Changeadb22f2019-06-19 12:09:23 +0800740 // Don't consider any activities that are currently not in a state where they
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700741 // can be destroyed.
Issei Suzuki430a1112019-11-14 16:20:52 +0100742 if (r.visible || !r.stopped || !r.hasSavedState()
Louis Changeadb22f2019-06-19 12:09:23 +0800743 || r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING)) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700744 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
745 continue;
746 }
747
Louis Changcdec0802019-11-11 11:45:07 +0800748 final Task task = r.getTask();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700749 if (task != null) {
750 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task
751 + " from " + r);
752 if (firstTask == null) {
753 firstTask = task;
754 } else if (firstTask != task) {
755 if (tasks == null) {
756 tasks = new ArraySet<>();
757 tasks.add(firstTask);
758 }
759 tasks.add(task);
760 }
761 }
762 }
763
764 return tasks;
765 }
766
767 public interface ComputeOomAdjCallback {
768 void onVisibleActivity();
769 void onPausedActivity();
770 void onStoppingActivity(boolean finishing);
771 void onOtherActivity();
772 }
773
Riddle Hsua0536432019-02-16 00:38:59 +0800774 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700775 public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
Jing Ji094c3ef2019-08-27 17:02:09 -0700776 // Since there could be more than one activities in a process record, we don't need to
777 // compute the OomAdj with each of them, just need to find out the activity with the
778 // "best" state, the order would be visible, pausing, stopping...
779 ActivityStack.ActivityState best = DESTROYED;
780 boolean finishing = true;
781 boolean visible = false;
Riddle Hsud7088f82019-01-30 13:04:50 +0800782 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700783 final int activitiesSize = mActivities.size();
784 for (int j = 0; j < activitiesSize; j++) {
785 final ActivityRecord r = mActivities.get(j);
786 if (r.app != this) {
787 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
788 + " instead of expected " + this);
789 if (r.app == null || (r.app.mUid == mUid)) {
790 // Only fix things up when they look sane
791 r.setProcess(this);
792 } else {
793 continue;
794 }
795 }
Issei Suzuki430a1112019-11-14 16:20:52 +0100796 if (r.visible) {
Louis Changcdec0802019-11-11 11:45:07 +0800797 final Task task = r.getTask();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700798 if (task != null && minTaskLayer > 0) {
799 final int layer = task.mLayerRank;
800 if (layer >= 0 && minTaskLayer > layer) {
801 minTaskLayer = layer;
802 }
803 }
Jing Ji094c3ef2019-08-27 17:02:09 -0700804 visible = true;
805 // continue the loop, in case there are multiple visible activities in
806 // this process, we'd find out the one with the minimal layer, thus it'll
807 // get a higher adj score.
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700808 } else {
Jing Ji094c3ef2019-08-27 17:02:09 -0700809 if (best != PAUSING && best != PAUSED) {
810 if (r.isState(PAUSING, PAUSED)) {
811 best = PAUSING;
812 } else if (r.isState(STOPPING)) {
813 best = STOPPING;
814 // Not "finishing" if any of activity isn't finishing.
815 finishing &= r.finishing;
816 }
817 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700818 }
819 }
820 }
Jing Ji094c3ef2019-08-27 17:02:09 -0700821 if (visible) {
822 callback.onVisibleActivity();
823 } else if (best == PAUSING) {
824 callback.onPausedActivity();
825 } else if (best == STOPPING) {
826 callback.onStoppingActivity(finishing);
827 } else {
828 callback.onOtherActivity();
829 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700830
831 return minTaskLayer;
832 }
833
Wale Ogunwale59507092018-10-29 09:00:30 -0700834 public int computeRelaunchReason() {
Garfield Tan2746ab52018-07-25 12:33:01 -0700835 synchronized (mAtm.mGlobalLock) {
836 final int activitiesSize = mActivities.size();
837 for (int i = activitiesSize - 1; i >= 0; i--) {
838 final ActivityRecord r = mActivities.get(i);
Wale Ogunwale64258362018-10-16 15:13:37 -0700839 if (r.mRelaunchReason != RELAUNCH_REASON_NONE) {
Garfield Tan2746ab52018-07-25 12:33:01 -0700840 return r.mRelaunchReason;
841 }
842 }
843 }
Wale Ogunwale64258362018-10-16 15:13:37 -0700844 return RELAUNCH_REASON_NONE;
Garfield Tan2746ab52018-07-25 12:33:01 -0700845 }
846
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700847 public long getInputDispatchingTimeout() {
848 synchronized (mAtm.mGlobalLock) {
849 return isInstrumenting() || isUsingWrapper()
850 ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS;
851 }
852 }
853
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700854 void clearProfilerIfNeeded() {
855 if (mListener == null) return;
856 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700857 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
858 WindowProcessListener::clearProfilerIfNeeded, mListener));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700859 }
860
Riddle Hsu17e38422019-04-12 16:55:11 +0800861 void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
862 boolean updateOomAdj) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700863 if (mListener == null) return;
864 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700865 final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
Riddle Hsu17e38422019-04-12 16:55:11 +0800866 mListener, updateServiceConnectionActivities, activityChange, updateOomAdj);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700867 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700868 }
869
870 void updateServiceConnectionActivities() {
871 if (mListener == null) return;
872 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700873 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
874 WindowProcessListener::updateServiceConnectionActivities, mListener));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700875 }
876
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700877 void setPendingUiCleanAndForceProcessStateUpTo(int newState) {
878 if (mListener == null) return;
879 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700880 final Message m = PooledLambda.obtainMessage(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700881 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo,
882 mListener, newState);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700883 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700884 }
885
Riddle Hsuaaef7312019-01-24 19:00:58 +0800886 boolean isRemoved() {
887 return mListener == null ? false : mListener.isRemoved();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700888 }
889
Riddle Hsu17e38422019-04-12 16:55:11 +0800890 private boolean shouldSetProfileProc() {
891 return mAtm.mProfileApp != null && mAtm.mProfileApp.equals(mName)
892 && (mAtm.mProfileProc == null || mAtm.mProfileProc == this);
Wale Ogunwale9c103022018-10-18 07:44:54 -0700893 }
894
Riddle Hsu17e38422019-04-12 16:55:11 +0800895 ProfilerInfo createProfilerInfoIfNeeded() {
896 final ProfilerInfo currentProfilerInfo = mAtm.mProfilerInfo;
897 if (currentProfilerInfo == null || currentProfilerInfo.profileFile == null
898 || !shouldSetProfileProc()) {
899 return null;
900 }
901 if (currentProfilerInfo.profileFd != null) {
902 try {
903 currentProfilerInfo.profileFd = currentProfilerInfo.profileFd.dup();
904 } catch (IOException e) {
905 currentProfilerInfo.closeFd();
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800906 }
907 }
Riddle Hsu17e38422019-04-12 16:55:11 +0800908 return new ProfilerInfo(currentProfilerInfo);
909 }
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800910
Riddle Hsu17e38422019-04-12 16:55:11 +0800911 void onStartActivity(int topProcessState, ActivityInfo info) {
912 if (mListener == null) return;
913 String packageName = null;
914 if ((info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
915 || !"android".equals(info.packageName)) {
916 // Don't add this if it is a platform component that is marked to run in multiple
917 // processes, because this is actually part of the framework so doesn't make sense
918 // to track as a separate apk in the process.
919 packageName = info.packageName;
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800920 }
Riddle Hsu17e38422019-04-12 16:55:11 +0800921 // Posting the message at the front of queue so WM lock isn't held when we call into AM,
922 // and the process state of starting activity can be updated quicker which will give it a
923 // higher scheduling group.
924 final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
925 mListener, topProcessState, shouldSetProfileProc(), packageName,
926 info.applicationInfo.longVersionCode);
927 mAtm.mH.sendMessageAtFrontOfQueue(m);
Wale Ogunwale9c103022018-10-18 07:44:54 -0700928 }
929
930 public void appDied() {
Wale Ogunwale9c103022018-10-18 07:44:54 -0700931 if (mListener == null) return;
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800932 // Posting on handler so WM lock isn't held when we call into AM.
933 final Message m = PooledLambda.obtainMessage(
934 WindowProcessListener::appDied, mListener);
935 mAtm.mH.sendMessage(m);
Wale Ogunwale9c103022018-10-18 07:44:54 -0700936 }
937
Yunfan Chen79b96062018-10-17 12:45:23 -0700938 void registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay) {
939 if (activityDisplay == null) {
940 return;
941 }
942 // A process can only register to one display to listener to the override configuration
943 // change. Unregister existing listener if it has one before register the new one.
944 unregisterDisplayConfigurationListenerLocked();
945 mDisplayId = activityDisplay.mDisplayId;
946 activityDisplay.registerConfigurationChangeListener(this);
947 }
948
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900949 @VisibleForTesting
950 void unregisterDisplayConfigurationListenerLocked() {
Yunfan Chen79b96062018-10-17 12:45:23 -0700951 if (mDisplayId == INVALID_DISPLAY) {
952 return;
953 }
954 final ActivityDisplay activityDisplay =
Wale Ogunwaled32da472018-11-16 07:19:28 -0800955 mAtm.mRootActivityContainer.getActivityDisplay(mDisplayId);
Yunfan Chen79b96062018-10-17 12:45:23 -0700956 if (activityDisplay != null) {
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900957 activityDisplay.unregisterConfigurationChangeListener(this);
Yunfan Chen79b96062018-10-17 12:45:23 -0700958 }
959 mDisplayId = INVALID_DISPLAY;
960 }
961
Yunfan Chen75157d72018-07-27 14:47:21 +0900962 @Override
963 public void onConfigurationChanged(Configuration newGlobalConfig) {
964 super.onConfigurationChanged(newGlobalConfig);
965 updateConfiguration();
966 }
967
968 @Override
Evan Roskydfe3da72018-10-26 17:21:06 -0700969 public void onRequestedOverrideConfigurationChanged(Configuration newOverrideConfig) {
970 super.onRequestedOverrideConfigurationChanged(newOverrideConfig);
Yunfan Chen75157d72018-07-27 14:47:21 +0900971 updateConfiguration();
972 }
973
974 private void updateConfiguration() {
975 final Configuration config = getConfiguration();
976 if (mLastReportedConfiguration.diff(config) == 0) {
977 // Nothing changed.
lumarkddc77fb2019-06-27 22:22:23 +0800978 if (Build.IS_DEBUGGABLE && mIsImeProcess) {
979 // TODO (b/135719017): Temporary log for debugging IME service.
980 Slog.w(TAG_CONFIGURATION, "Current config: " + config
981 + " unchanged for IME proc " + mName);
982 }
Yunfan Chen75157d72018-07-27 14:47:21 +0900983 return;
984 }
985
986 try {
987 if (mThread == null) {
lumarkddc77fb2019-06-27 22:22:23 +0800988 if (Build.IS_DEBUGGABLE && mIsImeProcess) {
989 // TODO (b/135719017): Temporary log for debugging IME service.
990 Slog.w(TAG_CONFIGURATION, "Unable to send config for IME proc " + mName
991 + ": no app thread");
992 }
Yunfan Chen75157d72018-07-27 14:47:21 +0900993 return;
994 }
995 if (DEBUG_CONFIGURATION) {
996 Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName
997 + " new config " + config);
998 }
lumarkddc77fb2019-06-27 22:22:23 +0800999 if (Build.IS_DEBUGGABLE && mIsImeProcess) {
1000 // TODO (b/135719017): Temporary log for debugging IME service.
1001 Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName
1002 + " new config " + config);
1003 }
Yunfan Chen75157d72018-07-27 14:47:21 +09001004 config.seq = mAtm.increaseConfigurationSeqLocked();
1005 mAtm.getLifecycleManager().scheduleTransaction(mThread,
1006 ConfigurationChangeItem.obtain(config));
1007 setLastReportedConfiguration(config);
1008 } catch (Exception e) {
1009 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
1010 }
1011 }
1012
1013 private void setLastReportedConfiguration(Configuration config) {
1014 mLastReportedConfiguration.setTo(config);
1015 }
1016
1017 Configuration getLastReportedConfiguration() {
1018 return mLastReportedConfiguration;
1019 }
1020
Wale Ogunwale86b74462018-07-02 08:42:43 -07001021 /** Returns the total time (in milliseconds) spent executing in both user and system code. */
1022 public long getCpuTime() {
1023 return (mListener != null) ? mListener.getCpuTime() : 0;
1024 }
1025
Louis Changcdec0802019-11-11 11:45:07 +08001026 void addRecentTask(Task task) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001027 mRecentTasks.add(task);
1028 }
1029
Louis Changcdec0802019-11-11 11:45:07 +08001030 void removeRecentTask(Task task) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001031 mRecentTasks.remove(task);
1032 }
1033
Riddle Hsua0536432019-02-16 00:38:59 +08001034 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001035 public boolean hasRecentTasks() {
Riddle Hsud7088f82019-01-30 13:04:50 +08001036 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001037 return !mRecentTasks.isEmpty();
1038 }
1039 }
1040
Riddle Hsud7088f82019-01-30 13:04:50 +08001041 void clearRecentTasks() {
1042 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1043 mRecentTasks.get(i).clearRootProcess();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001044 }
Riddle Hsud7088f82019-01-30 13:04:50 +08001045 mRecentTasks.clear();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001046 }
1047
Wale Ogunwalee2172292018-10-25 10:11:10 -07001048 public void appEarlyNotResponding(String annotation, Runnable killAppCallback) {
1049 synchronized (mAtm.mGlobalLock) {
1050 if (mAtm.mController == null) {
1051 return;
1052 }
1053
1054 try {
1055 // 0 == continue, -1 = kill process immediately
1056 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation);
1057 if (res < 0 && mPid != MY_PID) {
1058 killAppCallback.run();
1059 }
1060 } catch (RemoteException e) {
1061 mAtm.mController = null;
1062 Watchdog.getInstance().setActivityController(null);
1063 }
1064 }
1065 }
1066
1067 public boolean appNotResponding(String info, Runnable killAppCallback,
1068 Runnable serviceTimeoutCallback) {
Jeff Changed2f5bc2019-01-24 19:33:28 +08001069 Runnable targetRunnable = null;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001070 synchronized (mAtm.mGlobalLock) {
1071 if (mAtm.mController == null) {
1072 return false;
1073 }
1074
1075 try {
1076 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
1077 int res = mAtm.mController.appNotResponding(mName, mPid, info);
1078 if (res != 0) {
1079 if (res < 0 && mPid != MY_PID) {
Jeff Changed2f5bc2019-01-24 19:33:28 +08001080 targetRunnable = killAppCallback;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001081 } else {
Jeff Changed2f5bc2019-01-24 19:33:28 +08001082 targetRunnable = serviceTimeoutCallback;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001083 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07001084 }
1085 } catch (RemoteException e) {
1086 mAtm.mController = null;
1087 Watchdog.getInstance().setActivityController(null);
Jeff Changed2f5bc2019-01-24 19:33:28 +08001088 return false;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001089 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07001090 }
Jeff Changed2f5bc2019-01-24 19:33:28 +08001091 if (targetRunnable != null) {
1092 targetRunnable.run();
1093 return true;
1094 }
1095 return false;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001096 }
1097
Riddle Hsua0536432019-02-16 00:38:59 +08001098 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalee2172292018-10-25 10:11:10 -07001099 public void onTopProcChanged() {
Riddle Hsud7088f82019-01-30 13:04:50 +08001100 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwalee2172292018-10-25 10:11:10 -07001101 mAtm.mVrController.onTopProcChangedLocked(this);
1102 }
1103 }
1104
Riddle Hsua0536432019-02-16 00:38:59 +08001105 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07001106 public boolean isHomeProcess() {
Riddle Hsud7088f82019-01-30 13:04:50 +08001107 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07001108 return this == mAtm.mHomeProcess;
1109 }
1110 }
1111
Riddle Hsua0536432019-02-16 00:38:59 +08001112 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07001113 public boolean isPreviousProcess() {
Riddle Hsud7088f82019-01-30 13:04:50 +08001114 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07001115 return this == mAtm.mPreviousProcess;
1116 }
1117 }
1118
Jorim Jaggi589c5ba2019-07-30 16:50:13 +02001119 void setRunningRecentsAnimation(boolean running) {
1120 if (mRunningRecentsAnimation == running) {
1121 return;
1122 }
1123 mRunningRecentsAnimation = running;
1124 updateRunningRemoteOrRecentsAnimation();
1125 }
1126
1127 void setRunningRemoteAnimation(boolean running) {
1128 if (mRunningRemoteAnimation == running) {
1129 return;
1130 }
1131 mRunningRemoteAnimation = running;
1132 updateRunningRemoteOrRecentsAnimation();
1133 }
1134
1135 private void updateRunningRemoteOrRecentsAnimation() {
1136
1137 // Posting on handler so WM lock isn't held when we call into AM.
1138 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
1139 WindowProcessListener::setRunningRemoteAnimation, mListener,
1140 mRunningRecentsAnimation || mRunningRemoteAnimation));
1141 }
1142
Wale Ogunwale2a47d122018-11-19 16:49:40 -08001143 @Override
1144 public String toString() {
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001145 return mOwner != null ? mOwner.toString() : null;
Wale Ogunwale2a47d122018-11-19 16:49:40 -08001146 }
1147
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001148 public void dump(PrintWriter pw, String prefix) {
1149 synchronized (mAtm.mGlobalLock) {
1150 if (mActivities.size() > 0) {
1151 pw.print(prefix); pw.println("Activities:");
1152 for (int i = 0; i < mActivities.size(); i++) {
1153 pw.print(prefix); pw.print(" - "); pw.println(mActivities.get(i));
1154 }
1155 }
1156
1157 if (mRecentTasks.size() > 0) {
1158 pw.println(prefix + "Recent Tasks:");
1159 for (int i = 0; i < mRecentTasks.size(); i++) {
1160 pw.println(prefix + " - " + mRecentTasks.get(i));
1161 }
1162 }
1163
1164 if (mVrThreadTid != 0) {
1165 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid);
1166 }
1167 }
Yunfan Chen75157d72018-07-27 14:47:21 +09001168 pw.println(prefix + " Configuration=" + getConfiguration());
Evan Roskydfe3da72018-10-26 17:21:06 -07001169 pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
Yunfan Chen75157d72018-07-27 14:47:21 +09001170 pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001171 }
1172
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07001173 void writeToProto(ProtoOutputStream proto, long fieldId) {
1174 if (mListener != null) {
1175 mListener.writeToProto(proto, fieldId);
1176 }
1177 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001178}