blob: 4cb546f107c76c82a740c9f0d4995fc30b16e960 [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;
Alan Stokesac9a1292019-04-18 13:41:58 +010026import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
Wale Ogunwale59507092018-10-29 09:00:30 -070027import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
28import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
29import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
30import 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.Activity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070044import android.app.ActivityThread;
45import android.app.IApplicationThread;
Wale Ogunwale9c103022018-10-18 07:44:54 -070046import android.app.ProfilerInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +090047import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070048import android.content.Intent;
Riddle Hsu17e38422019-04-12 16:55:11 +080049import android.content.pm.ActivityInfo;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070050import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +090051import android.content.res.Configuration;
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
163 // all activities running in the process
164 private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
165 // any tasks this process had run root activities in
166 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>();
Louis Chang77ce34d2019-01-03 15:45:12 +0800167 // The most recent top-most activity that was resumed in the process for pre-Q app.
168 private ActivityRecord mPreQTopResumedActivity = null;
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100169 // The last time an activity was launched in the process
170 private long mLastActivityLaunchTime;
171 // The last time an activity was finished in the process while the process participated
172 // in a visible task
173 private long mLastActivityFinishTime;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700174
Yunfan Chen75157d72018-07-27 14:47:21 +0900175 // Last configuration that was reported to the process.
176 private final Configuration mLastReportedConfiguration;
Yunfan Chen79b96062018-10-17 12:45:23 -0700177 // Registered display id as a listener to override config change
178 private int mDisplayId;
Yunfan Chen75157d72018-07-27 14:47:21 +0900179
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200180 /** Whether our process is currently running a {@link RecentsAnimation} */
181 private boolean mRunningRecentsAnimation;
182
183 /** Whether our process is currently running a {@link IRemoteAnimationRunner} */
184 private boolean mRunningRemoteAnimation;
185
Wale Ogunwale59507092018-10-29 09:00:30 -0700186 public WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info,
187 String name, int uid, int userId, Object owner, WindowProcessListener listener) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700188 mInfo = info;
189 mName = name;
190 mUid = uid;
191 mUserId = userId;
192 mOwner = owner;
193 mListener = listener;
194 mAtm = atm;
Yunfan Chen75157d72018-07-27 14:47:21 +0900195 mLastReportedConfiguration = new Configuration();
Yunfan Chen79b96062018-10-17 12:45:23 -0700196 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700197 if (atm != null) {
198 onConfigurationChanged(atm.getGlobalConfiguration());
Yunfan Chen75157d72018-07-27 14:47:21 +0900199 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700200 }
201
202 public void setPid(int pid) {
203 mPid = pid;
204 }
205
Wale Ogunwale59507092018-10-29 09:00:30 -0700206 public int getPid() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700207 return mPid;
208 }
209
Louis Chang4221d792019-04-17 17:15:01 +0800210 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700211 public void setThread(IApplicationThread thread) {
Louis Chang4221d792019-04-17 17:15:01 +0800212 synchronized (mAtm.mGlobalLockWithoutBoost) {
213 mThread = thread;
214 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700215 }
216
217 IApplicationThread getThread() {
218 return mThread;
219 }
220
221 boolean hasThread() {
222 return mThread != null;
223 }
224
225 public void setCurrentSchedulingGroup(int curSchedGroup) {
226 mCurSchedGroup = curSchedGroup;
227 }
228
229 int getCurrentSchedulingGroup() {
230 return mCurSchedGroup;
231 }
232
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700233 public void setCurrentProcState(int curProcState) {
234 mCurProcState = curProcState;
235 }
236
237 int getCurrentProcState() {
238 return mCurProcState;
239 }
240
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700241 public void setReportedProcState(int repProcState) {
242 mRepProcState = repProcState;
243 }
244
245 int getReportedProcState() {
246 return mRepProcState;
247 }
248
249 public void setCrashing(boolean crashing) {
250 mCrashing = crashing;
251 }
252
253 boolean isCrashing() {
254 return mCrashing;
255 }
256
257 public void setNotResponding(boolean notResponding) {
258 mNotResponding = notResponding;
259 }
260
261 boolean isNotResponding() {
262 return mNotResponding;
263 }
264
265 public void setPersistent(boolean persistent) {
266 mPersistent = persistent;
267 }
268
269 boolean isPersistent() {
270 return mPersistent;
271 }
272
273 public void setHasForegroundServices(boolean hasForegroundServices) {
274 mHasForegroundServices = hasForegroundServices;
275 }
276
277 boolean hasForegroundServices() {
278 return mHasForegroundServices;
279 }
280
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700281 public void setHasForegroundActivities(boolean hasForegroundActivities) {
282 mHasForegroundActivities = hasForegroundActivities;
283 }
284
285 boolean hasForegroundActivities() {
286 return mHasForegroundActivities;
287 }
288
289 public void setHasClientActivities(boolean hasClientActivities) {
290 mHasClientActivities = hasClientActivities;
291 }
292
293 boolean hasClientActivities() {
294 return mHasClientActivities;
295 }
296
297 public void setHasTopUi(boolean hasTopUi) {
298 mHasTopUi = hasTopUi;
299 }
300
301 boolean hasTopUi() {
302 return mHasTopUi;
303 }
304
305 public void setHasOverlayUi(boolean hasOverlayUi) {
306 mHasOverlayUi = hasOverlayUi;
307 }
308
309 boolean hasOverlayUi() {
310 return mHasOverlayUi;
311 }
312
313 public void setPendingUiClean(boolean hasPendingUiClean) {
314 mPendingUiClean = hasPendingUiClean;
315 }
316
317 boolean hasPendingUiClean() {
318 return mPendingUiClean;
319 }
320
Yunfan Chenb4fe58c2019-03-27 18:35:06 +0900321 /** @return {@code true} if the process registered to a display as a config listener. */
322 boolean registeredForDisplayConfigChanges() {
323 return mDisplayId != INVALID_DISPLAY;
324 }
325
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700326 void postPendingUiCleanMsg(boolean pendingUiClean) {
327 if (mListener == null) return;
328 // Posting on handler so WM lock isn't held when we call into AM.
329 final Message m = PooledLambda.obtainMessage(
330 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
331 mAtm.mH.sendMessage(m);
332 }
333
334 public void setInteractionEventTime(long interactionEventTime) {
335 mInteractionEventTime = interactionEventTime;
336 }
337
338 long getInteractionEventTime() {
339 return mInteractionEventTime;
340 }
341
342 public void setFgInteractionTime(long fgInteractionTime) {
343 mFgInteractionTime = fgInteractionTime;
344 }
345
346 long getFgInteractionTime() {
347 return mFgInteractionTime;
348 }
349
350 public void setWhenUnimportant(long whenUnimportant) {
351 mWhenUnimportant = whenUnimportant;
352 }
353
354 long getWhenUnimportant() {
355 return mWhenUnimportant;
356 }
357
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700358 public void setRequiredAbi(String requiredAbi) {
359 mRequiredAbi = requiredAbi;
360 }
361
362 String getRequiredAbi() {
363 return mRequiredAbi;
364 }
365
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900366 /** Returns ID of display overriding the configuration for this process, or
367 * INVALID_DISPLAY if no display is overriding. */
368 @VisibleForTesting
369 int getDisplayId() {
370 return mDisplayId;
371 }
372
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700373 public void setDebugging(boolean debugging) {
374 mDebugging = debugging;
375 }
376
377 boolean isDebugging() {
378 return mDebugging;
379 }
380
381 public void setUsingWrapper(boolean usingWrapper) {
382 mUsingWrapper = usingWrapper;
383 }
384
385 boolean isUsingWrapper() {
386 return mUsingWrapper;
387 }
388
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100389 void setLastActivityLaunchTime(long launchTime) {
390 if (launchTime <= mLastActivityLaunchTime) {
391 return;
392 }
393 mLastActivityLaunchTime = launchTime;
394 }
395
396 void setLastActivityFinishTimeIfNeeded(long finishTime) {
397 if (finishTime <= mLastActivityFinishTime || !hasActivityInVisibleTask()) {
398 return;
399 }
400 mLastActivityFinishTime = finishTime;
401 }
402
Michal Karpinskiac116df2018-12-10 17:51:42 +0000403 public void setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts) {
404 mAllowBackgroundActivityStarts = allowBackgroundActivityStarts;
405 }
406
Michal Karpinski2e0aad22019-04-12 16:22:55 +0100407 boolean areBackgroundActivityStartsAllowed() {
408 // allow if the whitelisting flag was explicitly set
409 if (mAllowBackgroundActivityStarts) {
410 return true;
411 }
Ricky Wai906af482019-06-03 17:25:28 +0100412 // allow if any activity in the caller has either started or finished very recently, and
413 // it must be started or finished after last stop app switches time.
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100414 final long now = SystemClock.uptimeMillis();
415 if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
416 || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
Ricky Wai906af482019-06-03 17:25:28 +0100417 // if activity is started and finished before stop app switch time, we should not
418 // let app to be able to start background activity even it's in grace period.
419 if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
420 || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
421 return true;
422 }
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100423 }
Michal Karpinski2e0aad22019-04-12 16:22:55 +0100424 // allow if the proc is instrumenting with background activity starts privs
425 if (mInstrumentingWithBackgroundActivityStartPrivileges) {
426 return true;
427 }
428 // allow if the caller has an activity in any foreground task
429 if (hasActivityInVisibleTask()) {
430 return true;
431 }
432 // allow if the caller is bound by a UID that's currently foreground
433 if (isBoundByForegroundUid()) {
434 return true;
435 }
436 return false;
437 }
438
439 private boolean isBoundByForegroundUid() {
440 for (int i = mBoundClientUids.size() - 1; i >= 0; --i) {
441 if (mAtm.isUidForeground(mBoundClientUids.valueAt(i))) {
442 return true;
443 }
444 }
445 return false;
Michal Karpinskiac116df2018-12-10 17:51:42 +0000446 }
447
Michal Karpinskib7daac22019-03-25 10:12:41 +0000448 public void setBoundClientUids(ArraySet<Integer> boundClientUids) {
449 mBoundClientUids = boundClientUids;
450 }
451
Michal Karpinski4bc56492019-01-31 12:07:33 +0000452 public void setInstrumenting(boolean instrumenting,
453 boolean hasBackgroundActivityStartPrivileges) {
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700454 mInstrumenting = instrumenting;
Michal Karpinski4bc56492019-01-31 12:07:33 +0000455 mInstrumentingWithBackgroundActivityStartPrivileges = hasBackgroundActivityStartPrivileges;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700456 }
457
458 boolean isInstrumenting() {
459 return mInstrumenting;
460 }
461
Wale Ogunwale31913b52018-10-13 08:29:31 -0700462 public void setPerceptible(boolean perceptible) {
463 mPerceptible = perceptible;
464 }
465
466 boolean isPerceptible() {
467 return mPerceptible;
468 }
469
Yunfan Chen75157d72018-07-27 14:47:21 +0900470 @Override
471 protected int getChildCount() {
472 return 0;
473 }
474
475 @Override
476 protected ConfigurationContainer getChildAt(int index) {
477 return null;
478 }
479
480 @Override
481 protected ConfigurationContainer getParent() {
Andrii Kulian859f0a52019-05-20 12:18:09 +0000482 return null;
Yunfan Chen75157d72018-07-27 14:47:21 +0900483 }
484
Riddle Hsua0536432019-02-16 00:38:59 +0800485 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700486 public void addPackage(String packageName) {
Riddle Hsud7088f82019-01-30 13:04:50 +0800487 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700488 mPkgList.add(packageName);
489 }
490 }
491
Riddle Hsua0536432019-02-16 00:38:59 +0800492 @HotPath(caller = HotPath.PROCESS_CHANGE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700493 public void clearPackageList() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800494 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700495 mPkgList.clear();
496 }
497 }
498
499 void addActivityIfNeeded(ActivityRecord r) {
Michal Karpinskifc6872e2019-05-21 15:18:44 +0100500 // even if we already track this activity, note down that it has been launched
501 setLastActivityLaunchTime(r.lastLaunchTime);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700502 if (mActivities.contains(r)) {
503 return;
504 }
505 mActivities.add(r);
506 }
507
508 void removeActivity(ActivityRecord r) {
509 mActivities.remove(r);
510 }
511
Riddle Hsuaaef7312019-01-24 19:00:58 +0800512 void makeFinishingForProcessRemoved() {
513 for (int i = mActivities.size() - 1; i >= 0; --i) {
514 mActivities.get(i).makeFinishingLocked();
515 }
516 }
517
Riddle Hsud7088f82019-01-30 13:04:50 +0800518 void clearActivities() {
519 mActivities.clear();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700520 }
521
Riddle Hsua0536432019-02-16 00:38:59 +0800522 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700523 public boolean hasActivities() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800524 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700525 return !mActivities.isEmpty();
526 }
527 }
528
Riddle Hsua0536432019-02-16 00:38:59 +0800529 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700530 public boolean hasVisibleActivities() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800531 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700532 for (int i = mActivities.size() - 1; i >= 0; --i) {
533 final ActivityRecord r = mActivities.get(i);
534 if (r.visible) {
535 return true;
536 }
537 }
538 }
539 return false;
540 }
541
Riddle Hsua0536432019-02-16 00:38:59 +0800542 @HotPath(caller = HotPath.LRU_UPDATE)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700543 public boolean hasActivitiesOrRecentTasks() {
Riddle Hsud7088f82019-01-30 13:04:50 +0800544 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700545 return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
546 }
547 }
548
Michal Karpinski2e0aad22019-04-12 16:22:55 +0100549 private boolean hasActivityInVisibleTask() {
Michal Karpinskicb6873c2019-03-26 17:12:25 +0000550 for (int i = mActivities.size() - 1; i >= 0; --i) {
551 TaskRecord task = mActivities.get(i).getTaskRecord();
552 if (task == null) {
553 continue;
554 }
555 ActivityRecord topActivity = task.getTopActivity();
Alan Stokesac9a1292019-04-18 13:41:58 +0100556 if (topActivity == null) {
557 continue;
558 }
559 // If an activity has just been started it will not yet be visible, but
560 // is expected to be soon. We treat this as if it were already visible.
561 // This ensures a subsequent activity can be started even before this one
562 // becomes visible.
563 if (topActivity.visible || topActivity.isState(INITIALIZING)) {
Michal Karpinskicb6873c2019-03-26 17:12:25 +0000564 return true;
565 }
566 }
567 return false;
568 }
569
Louis Chang77ce34d2019-01-03 15:45:12 +0800570 /**
571 * Update the top resuming activity in process for pre-Q apps, only the top-most visible
572 * activities are allowed to be resumed per process.
573 * @return {@code true} if the activity is allowed to be resumed by compatibility
574 * restrictions, which the activity was the topmost visible activity in process or the app is
Hongwei Wangacad2442019-07-24 11:23:57 -0700575 * targeting after Q. Note that non-focusable activity, in picture-in-picture mode for instance,
576 * does not count as a topmost activity.
Louis Chang77ce34d2019-01-03 15:45:12 +0800577 */
578 boolean updateTopResumingActivityInProcessIfNeeded(@NonNull ActivityRecord activity) {
579 if (mInfo.targetSdkVersion >= Q || mPreQTopResumedActivity == activity) {
580 return true;
581 }
582
583 final ActivityDisplay display = activity.getDisplay();
584 if (display == null) {
585 // No need to update if the activity hasn't attach to any display.
586 return false;
587 }
588
589 boolean canUpdate = false;
590 final ActivityDisplay topDisplay =
591 mPreQTopResumedActivity != null ? mPreQTopResumedActivity.getDisplay() : null;
Hongwei Wangacad2442019-07-24 11:23:57 -0700592 // Update the topmost activity if current top activity is
593 // - not on any display OR
594 // - no longer visible OR
595 // - not focusable (in PiP mode for instance)
596 if (topDisplay == null
597 || !mPreQTopResumedActivity.visible
598 || !mPreQTopResumedActivity.isFocusable()) {
Louis Chang77ce34d2019-01-03 15:45:12 +0800599 canUpdate = true;
600 }
601
602 // Update the topmost activity if the current top activity wasn't on top of the other one.
603 if (!canUpdate && topDisplay.mDisplayContent.compareTo(display.mDisplayContent) < 0) {
604 canUpdate = true;
605 }
606
607 // Compare the z-order of ActivityStacks if both activities landed on same display.
608 if (display == topDisplay
609 && mPreQTopResumedActivity.getActivityStack().mTaskStack.compareTo(
610 activity.getActivityStack().mTaskStack) <= 0) {
611 canUpdate = true;
612 }
613
614 if (canUpdate) {
615 // Make sure the previous top activity in the process no longer be resumed.
616 if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) {
617 final ActivityStack stack = mPreQTopResumedActivity.getActivityStack();
618 if (stack != null) {
619 stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
620 null /* resuming */, false /* pauseImmediately */);
621 }
622 }
623 mPreQTopResumedActivity = activity;
624 }
625 return canUpdate;
626 }
627
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700628 public void stopFreezingActivities() {
629 synchronized (mAtm.mGlobalLock) {
630 int i = mActivities.size();
631 while (i > 0) {
632 i--;
633 mActivities.get(i).stopFreezingScreenLocked(true);
634 }
635 }
636 }
637
Riddle Hsud7088f82019-01-30 13:04:50 +0800638 void finishActivities() {
639 ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities);
640 for (int i = 0; i < activities.size(); i++) {
641 final ActivityRecord r = activities.get(i);
642 if (!r.finishing && r.isInStackLocked()) {
643 r.getActivityStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
Wale Ogunwale586a8ee2019-06-04 13:44:14 +0000644 null, "finish-heavy", true);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700645 }
646 }
647 }
648
649 public boolean isInterestingToUser() {
650 synchronized (mAtm.mGlobalLock) {
651 final int size = mActivities.size();
652 for (int i = 0; i < size; i++) {
653 ActivityRecord r = mActivities.get(i);
654 if (r.isInterestingToUserLocked()) {
655 return true;
656 }
657 }
658 }
659 return false;
660 }
661
662 public boolean hasRunningActivity(String packageName) {
663 synchronized (mAtm.mGlobalLock) {
664 for (int i = mActivities.size() - 1; i >= 0; --i) {
665 final ActivityRecord r = mActivities.get(i);
666 if (packageName.equals(r.packageName)) {
667 return true;
668 }
669 }
670 }
671 return false;
672 }
673
674 public void clearPackagePreferredForHomeActivities() {
675 synchronized (mAtm.mGlobalLock) {
676 for (int i = mActivities.size() - 1; i >= 0; --i) {
677 final ActivityRecord r = mActivities.get(i);
678 if (r.isActivityTypeHome()) {
679 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
680 try {
681 ActivityThread.getPackageManager()
682 .clearPackagePreferredActivities(r.packageName);
683 } catch (RemoteException c) {
684 // pm is in same process, this will never happen.
685 }
686 }
687 }
688 }
689 }
690
691 boolean hasStartedActivity(ActivityRecord launchedActivity) {
692 for (int i = mActivities.size() - 1; i >= 0; i--) {
693 final ActivityRecord activity = mActivities.get(i);
694 if (launchedActivity == activity) {
695 continue;
696 }
697 if (!activity.stopped) {
698 return true;
699 }
700 }
701 return false;
702 }
703
704
Riddle Hsud7088f82019-01-30 13:04:50 +0800705 void updateIntentForHeavyWeightActivity(Intent intent) {
706 if (mActivities.isEmpty()) {
707 return;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700708 }
Riddle Hsud7088f82019-01-30 13:04:50 +0800709 ActivityRecord hist = mActivities.get(0);
710 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
711 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTaskRecord().taskId);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700712 }
713
714 boolean shouldKillProcessForRemovedTask(TaskRecord tr) {
715 for (int k = 0; k < mActivities.size(); k++) {
Yunfan Chenafc15832018-07-26 16:34:28 +0900716 final ActivityRecord activity = mActivities.get(k);
717 if (!activity.stopped) {
718 // Don't kill process(es) that has an activity not stopped.
719 return false;
720 }
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800721 final TaskRecord otherTask = activity.getTaskRecord();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700722 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
723 // Don't kill process(es) that has an activity in a different task that is
724 // also in recents.
725 return false;
726 }
727 }
728 return true;
729 }
730
731 ArraySet<TaskRecord> getReleaseSomeActivitiesTasks() {
732 // Examine all activities currently running in the process.
733 TaskRecord firstTask = null;
734 // Tasks is non-null only if two or more tasks are found.
735 ArraySet<TaskRecord> tasks = null;
736 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this);
737 for (int i = 0; i < mActivities.size(); i++) {
738 final ActivityRecord r = mActivities.get(i);
739 // First, if we find an activity that is in the process of being destroyed,
740 // then we just aren't going to do anything for now; we want things to settle
741 // down before we try to prune more activities.
742 if (r.finishing || r.isState(DESTROYING, DESTROYED)) {
743 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
744 return null;
745 }
746 // Don't consider any activies that are currently not in a state where they
747 // can be destroyed.
748 if (r.visible || !r.stopped || !r.haveState
749 || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) {
750 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
751 continue;
752 }
753
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800754 final TaskRecord task = r.getTaskRecord();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700755 if (task != null) {
756 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task
757 + " from " + r);
758 if (firstTask == null) {
759 firstTask = task;
760 } else if (firstTask != task) {
761 if (tasks == null) {
762 tasks = new ArraySet<>();
763 tasks.add(firstTask);
764 }
765 tasks.add(task);
766 }
767 }
768 }
769
770 return tasks;
771 }
772
773 public interface ComputeOomAdjCallback {
774 void onVisibleActivity();
775 void onPausedActivity();
776 void onStoppingActivity(boolean finishing);
777 void onOtherActivity();
778 }
779
Riddle Hsua0536432019-02-16 00:38:59 +0800780 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700781 public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
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 }
796 if (r.visible) {
797 callback.onVisibleActivity();
Wale Ogunwale8b19de92018-11-29 19:58:26 -0800798 final TaskRecord task = r.getTaskRecord();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700799 if (task != null && minTaskLayer > 0) {
800 final int layer = task.mLayerRank;
801 if (layer >= 0 && minTaskLayer > layer) {
802 minTaskLayer = layer;
803 }
804 }
805 break;
806 } else if (r.isState(PAUSING, PAUSED)) {
807 callback.onPausedActivity();
808 } else if (r.isState(STOPPING)) {
809 callback.onStoppingActivity(r.finishing);
810 } else {
811 callback.onOtherActivity();
812 }
813 }
814 }
815
816 return minTaskLayer;
817 }
818
Wale Ogunwale59507092018-10-29 09:00:30 -0700819 public int computeRelaunchReason() {
Garfield Tan2746ab52018-07-25 12:33:01 -0700820 synchronized (mAtm.mGlobalLock) {
821 final int activitiesSize = mActivities.size();
822 for (int i = activitiesSize - 1; i >= 0; i--) {
823 final ActivityRecord r = mActivities.get(i);
Wale Ogunwale64258362018-10-16 15:13:37 -0700824 if (r.mRelaunchReason != RELAUNCH_REASON_NONE) {
Garfield Tan2746ab52018-07-25 12:33:01 -0700825 return r.mRelaunchReason;
826 }
827 }
828 }
Wale Ogunwale64258362018-10-16 15:13:37 -0700829 return RELAUNCH_REASON_NONE;
Garfield Tan2746ab52018-07-25 12:33:01 -0700830 }
831
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700832 public long getInputDispatchingTimeout() {
833 synchronized (mAtm.mGlobalLock) {
834 return isInstrumenting() || isUsingWrapper()
835 ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS;
836 }
837 }
838
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700839 void clearProfilerIfNeeded() {
840 if (mListener == null) return;
841 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700842 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
843 WindowProcessListener::clearProfilerIfNeeded, mListener));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700844 }
845
Riddle Hsu17e38422019-04-12 16:55:11 +0800846 void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
847 boolean updateOomAdj) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700848 if (mListener == null) return;
849 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700850 final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
Riddle Hsu17e38422019-04-12 16:55:11 +0800851 mListener, updateServiceConnectionActivities, activityChange, updateOomAdj);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700852 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700853 }
854
855 void updateServiceConnectionActivities() {
856 if (mListener == null) return;
857 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700858 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
859 WindowProcessListener::updateServiceConnectionActivities, mListener));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700860 }
861
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700862 void setPendingUiCleanAndForceProcessStateUpTo(int newState) {
863 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(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700866 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo,
867 mListener, newState);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700868 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700869 }
870
Riddle Hsuaaef7312019-01-24 19:00:58 +0800871 boolean isRemoved() {
872 return mListener == null ? false : mListener.isRemoved();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700873 }
874
Riddle Hsu17e38422019-04-12 16:55:11 +0800875 private boolean shouldSetProfileProc() {
876 return mAtm.mProfileApp != null && mAtm.mProfileApp.equals(mName)
877 && (mAtm.mProfileProc == null || mAtm.mProfileProc == this);
Wale Ogunwale9c103022018-10-18 07:44:54 -0700878 }
879
Riddle Hsu17e38422019-04-12 16:55:11 +0800880 ProfilerInfo createProfilerInfoIfNeeded() {
881 final ProfilerInfo currentProfilerInfo = mAtm.mProfilerInfo;
882 if (currentProfilerInfo == null || currentProfilerInfo.profileFile == null
883 || !shouldSetProfileProc()) {
884 return null;
885 }
886 if (currentProfilerInfo.profileFd != null) {
887 try {
888 currentProfilerInfo.profileFd = currentProfilerInfo.profileFd.dup();
889 } catch (IOException e) {
890 currentProfilerInfo.closeFd();
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800891 }
892 }
Riddle Hsu17e38422019-04-12 16:55:11 +0800893 return new ProfilerInfo(currentProfilerInfo);
894 }
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800895
Riddle Hsu17e38422019-04-12 16:55:11 +0800896 void onStartActivity(int topProcessState, ActivityInfo info) {
897 if (mListener == null) return;
898 String packageName = null;
899 if ((info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
900 || !"android".equals(info.packageName)) {
901 // Don't add this if it is a platform component that is marked to run in multiple
902 // processes, because this is actually part of the framework so doesn't make sense
903 // to track as a separate apk in the process.
904 packageName = info.packageName;
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800905 }
Riddle Hsu17e38422019-04-12 16:55:11 +0800906 // Posting the message at the front of queue so WM lock isn't held when we call into AM,
907 // and the process state of starting activity can be updated quicker which will give it a
908 // higher scheduling group.
909 final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
910 mListener, topProcessState, shouldSetProfileProc(), packageName,
911 info.applicationInfo.longVersionCode);
912 mAtm.mH.sendMessageAtFrontOfQueue(m);
Wale Ogunwale9c103022018-10-18 07:44:54 -0700913 }
914
915 public void appDied() {
Wale Ogunwale9c103022018-10-18 07:44:54 -0700916 if (mListener == null) return;
Wale Ogunwale1f5e53d2018-11-05 05:12:46 -0800917 // Posting on handler so WM lock isn't held when we call into AM.
918 final Message m = PooledLambda.obtainMessage(
919 WindowProcessListener::appDied, mListener);
920 mAtm.mH.sendMessage(m);
Wale Ogunwale9c103022018-10-18 07:44:54 -0700921 }
922
Yunfan Chen79b96062018-10-17 12:45:23 -0700923 void registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay) {
924 if (activityDisplay == null) {
925 return;
926 }
927 // A process can only register to one display to listener to the override configuration
928 // change. Unregister existing listener if it has one before register the new one.
929 unregisterDisplayConfigurationListenerLocked();
930 mDisplayId = activityDisplay.mDisplayId;
931 activityDisplay.registerConfigurationChangeListener(this);
932 }
933
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900934 @VisibleForTesting
935 void unregisterDisplayConfigurationListenerLocked() {
Yunfan Chen79b96062018-10-17 12:45:23 -0700936 if (mDisplayId == INVALID_DISPLAY) {
937 return;
938 }
939 final ActivityDisplay activityDisplay =
Wale Ogunwaled32da472018-11-16 07:19:28 -0800940 mAtm.mRootActivityContainer.getActivityDisplay(mDisplayId);
Yunfan Chen79b96062018-10-17 12:45:23 -0700941 if (activityDisplay != null) {
Yunfan Chenb29cbfd2019-01-24 17:30:33 +0900942 activityDisplay.unregisterConfigurationChangeListener(this);
Yunfan Chen79b96062018-10-17 12:45:23 -0700943 }
944 mDisplayId = INVALID_DISPLAY;
945 }
946
Yunfan Chen75157d72018-07-27 14:47:21 +0900947 @Override
948 public void onConfigurationChanged(Configuration newGlobalConfig) {
949 super.onConfigurationChanged(newGlobalConfig);
950 updateConfiguration();
951 }
952
953 @Override
Evan Roskydfe3da72018-10-26 17:21:06 -0700954 public void onRequestedOverrideConfigurationChanged(Configuration newOverrideConfig) {
955 super.onRequestedOverrideConfigurationChanged(newOverrideConfig);
Yunfan Chen75157d72018-07-27 14:47:21 +0900956 updateConfiguration();
957 }
958
959 private void updateConfiguration() {
960 final Configuration config = getConfiguration();
961 if (mLastReportedConfiguration.diff(config) == 0) {
962 // Nothing changed.
963 return;
964 }
965
966 try {
967 if (mThread == null) {
968 return;
969 }
970 if (DEBUG_CONFIGURATION) {
971 Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName
972 + " new config " + config);
973 }
974 config.seq = mAtm.increaseConfigurationSeqLocked();
975 mAtm.getLifecycleManager().scheduleTransaction(mThread,
976 ConfigurationChangeItem.obtain(config));
977 setLastReportedConfiguration(config);
978 } catch (Exception e) {
979 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
980 }
981 }
982
983 private void setLastReportedConfiguration(Configuration config) {
984 mLastReportedConfiguration.setTo(config);
985 }
986
987 Configuration getLastReportedConfiguration() {
988 return mLastReportedConfiguration;
989 }
990
Wale Ogunwale86b74462018-07-02 08:42:43 -0700991 /** Returns the total time (in milliseconds) spent executing in both user and system code. */
992 public long getCpuTime() {
993 return (mListener != null) ? mListener.getCpuTime() : 0;
994 }
995
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700996 void addRecentTask(TaskRecord task) {
997 mRecentTasks.add(task);
998 }
999
1000 void removeRecentTask(TaskRecord task) {
1001 mRecentTasks.remove(task);
1002 }
1003
Riddle Hsua0536432019-02-16 00:38:59 +08001004 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001005 public boolean hasRecentTasks() {
Riddle Hsud7088f82019-01-30 13:04:50 +08001006 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001007 return !mRecentTasks.isEmpty();
1008 }
1009 }
1010
Riddle Hsud7088f82019-01-30 13:04:50 +08001011 void clearRecentTasks() {
1012 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1013 mRecentTasks.get(i).clearRootProcess();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001014 }
Riddle Hsud7088f82019-01-30 13:04:50 +08001015 mRecentTasks.clear();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001016 }
1017
Wale Ogunwalee2172292018-10-25 10:11:10 -07001018 public void appEarlyNotResponding(String annotation, Runnable killAppCallback) {
1019 synchronized (mAtm.mGlobalLock) {
1020 if (mAtm.mController == null) {
1021 return;
1022 }
1023
1024 try {
1025 // 0 == continue, -1 = kill process immediately
1026 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation);
1027 if (res < 0 && mPid != MY_PID) {
1028 killAppCallback.run();
1029 }
1030 } catch (RemoteException e) {
1031 mAtm.mController = null;
1032 Watchdog.getInstance().setActivityController(null);
1033 }
1034 }
1035 }
1036
1037 public boolean appNotResponding(String info, Runnable killAppCallback,
1038 Runnable serviceTimeoutCallback) {
Jeff Changed2f5bc2019-01-24 19:33:28 +08001039 Runnable targetRunnable = null;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001040 synchronized (mAtm.mGlobalLock) {
1041 if (mAtm.mController == null) {
1042 return false;
1043 }
1044
1045 try {
1046 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
1047 int res = mAtm.mController.appNotResponding(mName, mPid, info);
1048 if (res != 0) {
1049 if (res < 0 && mPid != MY_PID) {
Jeff Changed2f5bc2019-01-24 19:33:28 +08001050 targetRunnable = killAppCallback;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001051 } else {
Jeff Changed2f5bc2019-01-24 19:33:28 +08001052 targetRunnable = serviceTimeoutCallback;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001053 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07001054 }
1055 } catch (RemoteException e) {
1056 mAtm.mController = null;
1057 Watchdog.getInstance().setActivityController(null);
Jeff Changed2f5bc2019-01-24 19:33:28 +08001058 return false;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001059 }
Wale Ogunwalee2172292018-10-25 10:11:10 -07001060 }
Jeff Changed2f5bc2019-01-24 19:33:28 +08001061 if (targetRunnable != null) {
1062 targetRunnable.run();
1063 return true;
1064 }
1065 return false;
Wale Ogunwalee2172292018-10-25 10:11:10 -07001066 }
1067
Riddle Hsua0536432019-02-16 00:38:59 +08001068 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwalee2172292018-10-25 10:11:10 -07001069 public void onTopProcChanged() {
Riddle Hsud7088f82019-01-30 13:04:50 +08001070 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwalee2172292018-10-25 10:11:10 -07001071 mAtm.mVrController.onTopProcChangedLocked(this);
1072 }
1073 }
1074
Riddle Hsua0536432019-02-16 00:38:59 +08001075 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07001076 public boolean isHomeProcess() {
Riddle Hsud7088f82019-01-30 13:04:50 +08001077 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07001078 return this == mAtm.mHomeProcess;
1079 }
1080 }
1081
Riddle Hsua0536432019-02-16 00:38:59 +08001082 @HotPath(caller = HotPath.OOM_ADJUSTMENT)
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07001083 public boolean isPreviousProcess() {
Riddle Hsud7088f82019-01-30 13:04:50 +08001084 synchronized (mAtm.mGlobalLockWithoutBoost) {
Wale Ogunwaled4d67d02018-10-25 18:09:39 -07001085 return this == mAtm.mPreviousProcess;
1086 }
1087 }
1088
Jorim Jaggi589c5ba2019-07-30 16:50:13 +02001089 void setRunningRecentsAnimation(boolean running) {
1090 if (mRunningRecentsAnimation == running) {
1091 return;
1092 }
1093 mRunningRecentsAnimation = running;
1094 updateRunningRemoteOrRecentsAnimation();
1095 }
1096
1097 void setRunningRemoteAnimation(boolean running) {
1098 if (mRunningRemoteAnimation == running) {
1099 return;
1100 }
1101 mRunningRemoteAnimation = running;
1102 updateRunningRemoteOrRecentsAnimation();
1103 }
1104
1105 private void updateRunningRemoteOrRecentsAnimation() {
1106
1107 // Posting on handler so WM lock isn't held when we call into AM.
1108 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
1109 WindowProcessListener::setRunningRemoteAnimation, mListener,
1110 mRunningRecentsAnimation || mRunningRemoteAnimation));
1111 }
1112
Wale Ogunwale2a47d122018-11-19 16:49:40 -08001113 @Override
1114 public String toString() {
Michal Karpinski9cbb20b2019-02-05 17:31:50 +00001115 return mOwner != null ? mOwner.toString() : null;
Wale Ogunwale2a47d122018-11-19 16:49:40 -08001116 }
1117
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001118 public void dump(PrintWriter pw, String prefix) {
1119 synchronized (mAtm.mGlobalLock) {
1120 if (mActivities.size() > 0) {
1121 pw.print(prefix); pw.println("Activities:");
1122 for (int i = 0; i < mActivities.size(); i++) {
1123 pw.print(prefix); pw.print(" - "); pw.println(mActivities.get(i));
1124 }
1125 }
1126
1127 if (mRecentTasks.size() > 0) {
1128 pw.println(prefix + "Recent Tasks:");
1129 for (int i = 0; i < mRecentTasks.size(); i++) {
1130 pw.println(prefix + " - " + mRecentTasks.get(i));
1131 }
1132 }
1133
1134 if (mVrThreadTid != 0) {
1135 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid);
1136 }
1137 }
Yunfan Chen75157d72018-07-27 14:47:21 +09001138 pw.println(prefix + " Configuration=" + getConfiguration());
Evan Roskydfe3da72018-10-26 17:21:06 -07001139 pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
Yunfan Chen75157d72018-07-27 14:47:21 +09001140 pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001141 }
1142
Wale Ogunwale51cc98a2018-10-15 10:41:05 -07001143 void writeToProto(ProtoOutputStream proto, long fieldId) {
1144 if (mListener != null) {
1145 mListener.writeToProto(proto, fieldId);
1146 }
1147 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001148}