1 /*
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 
17 package com.android.server.wm;
18 
19 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
21 import static android.os.Build.VERSION_CODES.Q;
22 import static android.view.Display.INVALID_DISPLAY;
23 
24 import static com.android.server.am.ActivityManagerService.MY_PID;
25 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
26 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
27 import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
28 import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
29 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
30 import static com.android.server.wm.ActivityStack.ActivityState.STARTED;
31 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
32 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
33 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
34 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
35 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
36 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
37 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
38 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
39 import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
40 import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
41 import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
42 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
43 
44 import android.Manifest;
45 import android.annotation.NonNull;
46 import android.annotation.Nullable;
47 import android.app.ActivityManager;
48 import android.app.ActivityThread;
49 import android.app.IApplicationThread;
50 import android.app.ProfilerInfo;
51 import android.app.servertransaction.ConfigurationChangeItem;
52 import android.content.Context;
53 import android.content.Intent;
54 import android.content.pm.ActivityInfo;
55 import android.content.pm.ApplicationInfo;
56 import android.content.pm.ServiceInfo;
57 import android.content.res.Configuration;
58 import android.os.Build;
59 import android.os.Message;
60 import android.os.Process;
61 import android.os.RemoteException;
62 import android.os.SystemClock;
63 import android.util.ArraySet;
64 import android.util.Log;
65 import android.util.Slog;
66 import android.util.proto.ProtoOutputStream;
67 import android.view.IRemoteAnimationRunner;
68 
69 import com.android.internal.annotations.VisibleForTesting;
70 import com.android.internal.app.HeavyWeightSwitcherActivity;
71 import com.android.internal.util.function.pooled.PooledLambda;
72 import com.android.server.Watchdog;
73 import com.android.server.wm.ActivityTaskManagerService.HotPath;
74 
75 import java.io.IOException;
76 import java.io.PrintWriter;
77 import java.util.ArrayList;
78 import java.util.List;
79 
80 /**
81  * The Activity Manager (AM) package manages the lifecycle of processes in the system through
82  * ProcessRecord. However, it is important for the Window Manager (WM) package to be aware
83  * of the processes and their state since it affects how WM manages windows and activities. This
84  * class that allows the ProcessRecord object in the AM package to communicate important
85  * changes to its state to the WM package in a structured way. WM package also uses
86  * {@link WindowProcessListener} to request changes to the process state on the AM side.
87  * Note that public calls into this class are assumed to be originating from outside the
88  * window manager so the window manager lock is held and appropriate permissions are checked before
89  * calls are allowed to proceed.
90  */
91 public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
92         implements ConfigurationContainerListener {
93     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM;
94     private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
95     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
96 
97     // all about the first app in the process
98     final ApplicationInfo mInfo;
99     final String mName;
100     final int mUid;
101     // The process of this application; 0 if none
102     private volatile int mPid;
103     // user of process.
104     final int mUserId;
105     // The owner of this window process controller object. Mainly for identification when we
106     // communicate back to the activity manager side.
107     public final Object mOwner;
108     // List of packages running in the process
109     final ArraySet<String> mPkgList = new ArraySet<>();
110     private final WindowProcessListener mListener;
111     private final ActivityTaskManagerService mAtm;
112     // The actual proc...  may be null only if 'persistent' is true (in which case we are in the
113     // process of launching the app)
114     private IApplicationThread mThread;
115     // Currently desired scheduling class
116     private volatile int mCurSchedGroup;
117     // Currently computed process state
118     private volatile int mCurProcState = PROCESS_STATE_NONEXISTENT;
119     // Last reported process state;
120     private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT;
121     // are we in the process of crashing?
122     private volatile boolean mCrashing;
123     // does the app have a not responding dialog?
124     private volatile boolean mNotResponding;
125     // always keep this application running?
126     private volatile boolean mPersistent;
127     // The ABI this process was launched with
128     private volatile String mRequiredAbi;
129     // Running any services that are foreground?
130     private volatile boolean mHasForegroundServices;
131     // Running any activities that are foreground?
132     private volatile boolean mHasForegroundActivities;
133     // Are there any client services with activities?
134     private volatile boolean mHasClientActivities;
135     // Is this process currently showing a non-activity UI that the user is interacting with?
136     // E.g. The status bar when it is expanded, but not when it is minimized. When true the process
137     // will be set to use the ProcessList#SCHED_GROUP_TOP_APP scheduling group to boost performance.
138     private volatile boolean mHasTopUi;
139     // Is the process currently showing a non-activity UI that overlays on-top of activity UIs on
140     // screen. E.g. display a window of type
141     // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY When true the process will
142     // oom adj score will be set to ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
143     // of the process getting killed.
144     private volatile boolean mHasOverlayUi;
145     // Want to clean up resources from showing UI?
146     private volatile boolean mPendingUiClean;
147     // The time we sent the last interaction event
148     private volatile long mInteractionEventTime;
149     // When we became foreground for interaction purposes
150     private volatile long mFgInteractionTime;
151     // When (uptime) the process last became unimportant
152     private volatile long mWhenUnimportant;
153     // was app launched for debugging?
154     private volatile boolean mDebugging;
155     // Active instrumentation running in process?
156     private volatile boolean mInstrumenting;
157     // Active instrumentation with background activity starts privilege running in process?
158     private volatile boolean mInstrumentingWithBackgroundActivityStartPrivileges;
159     // This process it perceptible by the user.
160     private volatile boolean mPerceptible;
161     // Set to true when process was launched with a wrapper attached
162     private volatile boolean mUsingWrapper;
163     // Set to true if this process is currently temporarily whitelisted to start activities even if
164     // it's not in the foreground
165     private volatile boolean mAllowBackgroundActivityStarts;
166     // Set of UIDs of clients currently bound to this process
167     private volatile ArraySet<Integer> mBoundClientUids = new ArraySet<Integer>();
168 
169     // Thread currently set for VR scheduling
170     int mVrThreadTid;
171 
172     // Whether this process has ever started a service with the BIND_INPUT_METHOD permission.
173     private volatile boolean mHasImeService;
174 
175     // all activities running in the process
176     private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
177     // any tasks this process had run root activities in
178     private final ArrayList<Task> mRecentTasks = new ArrayList<>();
179     // The most recent top-most activity that was resumed in the process for pre-Q app.
180     private ActivityRecord mPreQTopResumedActivity = null;
181     // The last time an activity was launched in the process
182     private long mLastActivityLaunchTime;
183     // The last time an activity was finished in the process while the process participated
184     // in a visible task
185     private long mLastActivityFinishTime;
186 
187     // Last configuration that was reported to the process.
188     private final Configuration mLastReportedConfiguration = new Configuration();
189     // Configuration that is waiting to be dispatched to the process.
190     private Configuration mPendingConfiguration;
191     private final Configuration mNewOverrideConfig = new Configuration();
192     // Registered display id as a listener to override config change
193     private int mDisplayId;
194     private ActivityRecord mConfigActivityRecord;
195     // Whether the activity config override is allowed for this process.
196     private volatile boolean mIsActivityConfigOverrideAllowed = true;
197     /**
198      * Activities that hosts some UI drawn by the current process. The activities live
199      * in another process. This is used to check if the process is currently showing anything
200      * visible to the user.
201      */
202     @Nullable
203     private final ArrayList<ActivityRecord> mHostActivities = new ArrayList<>();
204 
205     /** Whether our process is currently running a {@link RecentsAnimation} */
206     private boolean mRunningRecentsAnimation;
207 
208     /** Whether our process is currently running a {@link IRemoteAnimationRunner} */
209     private boolean mRunningRemoteAnimation;
210 
WindowProcessController(@onNull ActivityTaskManagerService atm, ApplicationInfo info, String name, int uid, int userId, Object owner, WindowProcessListener listener)211     public WindowProcessController(@NonNull ActivityTaskManagerService atm, ApplicationInfo info,
212             String name, int uid, int userId, Object owner, WindowProcessListener listener) {
213         mInfo = info;
214         mName = name;
215         mUid = uid;
216         mUserId = userId;
217         mOwner = owner;
218         mListener = listener;
219         mAtm = atm;
220         mDisplayId = INVALID_DISPLAY;
221 
222         boolean isSysUiPackage = info.packageName.equals(
223                 mAtm.getSysUiServiceComponentLocked().getPackageName());
224         if (isSysUiPackage || mUid == Process.SYSTEM_UID) {
225             // This is a system owned process and should not use an activity config.
226             // TODO(b/151161907): Remove after support for display-independent (raw) SysUi configs.
227             mIsActivityConfigOverrideAllowed = false;
228         }
229 
230         onConfigurationChanged(atm.getGlobalConfiguration());
231     }
232 
setPid(int pid)233     public void setPid(int pid) {
234         mPid = pid;
235     }
236 
getPid()237     public int getPid() {
238         return mPid;
239     }
240 
241     @HotPath(caller = HotPath.PROCESS_CHANGE)
setThread(IApplicationThread thread)242     public void setThread(IApplicationThread thread) {
243         synchronized (mAtm.mGlobalLockWithoutBoost) {
244             mThread = thread;
245             // In general this is called from attaching application, so the last configuration
246             // has been sent to client by {@link android.app.IApplicationThread#bindApplication}.
247             // If this process is system server, it is fine because system is booting and a new
248             // configuration will update when display is ready.
249             if (thread != null) {
250                 setLastReportedConfiguration(getConfiguration());
251             }
252         }
253     }
254 
getThread()255     IApplicationThread getThread() {
256         return mThread;
257     }
258 
hasThread()259     boolean hasThread() {
260         return mThread != null;
261     }
262 
setCurrentSchedulingGroup(int curSchedGroup)263     public void setCurrentSchedulingGroup(int curSchedGroup) {
264         mCurSchedGroup = curSchedGroup;
265     }
266 
getCurrentSchedulingGroup()267     int getCurrentSchedulingGroup() {
268         return mCurSchedGroup;
269     }
270 
setCurrentProcState(int curProcState)271     public void setCurrentProcState(int curProcState) {
272         mCurProcState = curProcState;
273     }
274 
getCurrentProcState()275     int getCurrentProcState() {
276         return mCurProcState;
277     }
278 
setReportedProcState(int repProcState)279     public void setReportedProcState(int repProcState) {
280         mRepProcState = repProcState;
281     }
282 
getReportedProcState()283     int getReportedProcState() {
284         return mRepProcState;
285     }
286 
setCrashing(boolean crashing)287     public void setCrashing(boolean crashing) {
288         mCrashing = crashing;
289     }
290 
isCrashing()291     boolean isCrashing() {
292         return mCrashing;
293     }
294 
setNotResponding(boolean notResponding)295     public void setNotResponding(boolean notResponding) {
296         mNotResponding = notResponding;
297     }
298 
isNotResponding()299     boolean isNotResponding() {
300         return mNotResponding;
301     }
302 
setPersistent(boolean persistent)303     public void setPersistent(boolean persistent) {
304         mPersistent = persistent;
305     }
306 
isPersistent()307     boolean isPersistent() {
308         return mPersistent;
309     }
310 
setHasForegroundServices(boolean hasForegroundServices)311     public void setHasForegroundServices(boolean hasForegroundServices) {
312         mHasForegroundServices = hasForegroundServices;
313     }
314 
hasForegroundServices()315     boolean hasForegroundServices() {
316         return mHasForegroundServices;
317     }
318 
setHasForegroundActivities(boolean hasForegroundActivities)319     public void setHasForegroundActivities(boolean hasForegroundActivities) {
320         mHasForegroundActivities = hasForegroundActivities;
321     }
322 
hasForegroundActivities()323     boolean hasForegroundActivities() {
324         return mHasForegroundActivities;
325     }
326 
setHasClientActivities(boolean hasClientActivities)327     public void setHasClientActivities(boolean hasClientActivities) {
328         mHasClientActivities = hasClientActivities;
329     }
330 
hasClientActivities()331     boolean hasClientActivities() {
332         return mHasClientActivities;
333     }
334 
setHasTopUi(boolean hasTopUi)335     public void setHasTopUi(boolean hasTopUi) {
336         mHasTopUi = hasTopUi;
337     }
338 
hasTopUi()339     boolean hasTopUi() {
340         return mHasTopUi;
341     }
342 
setHasOverlayUi(boolean hasOverlayUi)343     public void setHasOverlayUi(boolean hasOverlayUi) {
344         mHasOverlayUi = hasOverlayUi;
345     }
346 
hasOverlayUi()347     boolean hasOverlayUi() {
348         return mHasOverlayUi;
349     }
350 
setPendingUiClean(boolean hasPendingUiClean)351     public void setPendingUiClean(boolean hasPendingUiClean) {
352         mPendingUiClean = hasPendingUiClean;
353     }
354 
hasPendingUiClean()355     boolean hasPendingUiClean() {
356         return mPendingUiClean;
357     }
358 
359     /** @return {@code true} if the process registered to a display as a config listener. */
registeredForDisplayConfigChanges()360     boolean registeredForDisplayConfigChanges() {
361         return mDisplayId != INVALID_DISPLAY;
362     }
363 
364     /** @return {@code true} if the process registered to an activity as a config listener. */
365     @VisibleForTesting
registeredForActivityConfigChanges()366     boolean registeredForActivityConfigChanges() {
367         return mConfigActivityRecord != null;
368     }
369 
postPendingUiCleanMsg(boolean pendingUiClean)370     void postPendingUiCleanMsg(boolean pendingUiClean) {
371         if (mListener == null) return;
372         // Posting on handler so WM lock isn't held when we call into AM.
373         final Message m = PooledLambda.obtainMessage(
374                 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
375         mAtm.mH.sendMessage(m);
376     }
377 
setInteractionEventTime(long interactionEventTime)378     public void setInteractionEventTime(long interactionEventTime) {
379         mInteractionEventTime = interactionEventTime;
380     }
381 
getInteractionEventTime()382     long getInteractionEventTime() {
383         return mInteractionEventTime;
384     }
385 
setFgInteractionTime(long fgInteractionTime)386     public void setFgInteractionTime(long fgInteractionTime) {
387         mFgInteractionTime = fgInteractionTime;
388     }
389 
getFgInteractionTime()390     long getFgInteractionTime() {
391         return mFgInteractionTime;
392     }
393 
setWhenUnimportant(long whenUnimportant)394     public void setWhenUnimportant(long whenUnimportant) {
395         mWhenUnimportant = whenUnimportant;
396     }
397 
getWhenUnimportant()398     long getWhenUnimportant() {
399         return mWhenUnimportant;
400     }
401 
setRequiredAbi(String requiredAbi)402     public void setRequiredAbi(String requiredAbi) {
403         mRequiredAbi = requiredAbi;
404     }
405 
getRequiredAbi()406     String getRequiredAbi() {
407         return mRequiredAbi;
408     }
409 
410     /** Returns ID of display overriding the configuration for this process, or
411      *  INVALID_DISPLAY if no display is overriding. */
412     @VisibleForTesting
getDisplayId()413     int getDisplayId() {
414         return mDisplayId;
415     }
416 
setDebugging(boolean debugging)417     public void setDebugging(boolean debugging) {
418         mDebugging = debugging;
419     }
420 
isDebugging()421     boolean isDebugging() {
422         return mDebugging;
423     }
424 
setUsingWrapper(boolean usingWrapper)425     public void setUsingWrapper(boolean usingWrapper) {
426         mUsingWrapper = usingWrapper;
427     }
428 
isUsingWrapper()429     boolean isUsingWrapper() {
430         return mUsingWrapper;
431     }
432 
setLastActivityLaunchTime(long launchTime)433     void setLastActivityLaunchTime(long launchTime) {
434         if (launchTime <= mLastActivityLaunchTime) {
435             if (launchTime < mLastActivityLaunchTime) {
436                 Slog.w(TAG,
437                         "Tried to set launchTime (" + launchTime + ") < mLastActivityLaunchTime ("
438                                 + mLastActivityLaunchTime + ")");
439             }
440             return;
441         }
442         mLastActivityLaunchTime = launchTime;
443     }
444 
setLastActivityFinishTimeIfNeeded(long finishTime)445     void setLastActivityFinishTimeIfNeeded(long finishTime) {
446         if (finishTime <= mLastActivityFinishTime || !hasActivityInVisibleTask()) {
447             return;
448         }
449         mLastActivityFinishTime = finishTime;
450     }
451 
setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts)452     public void setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts) {
453         mAllowBackgroundActivityStarts = allowBackgroundActivityStarts;
454     }
455 
areBackgroundActivityStartsAllowed()456     boolean areBackgroundActivityStartsAllowed() {
457         // allow if the whitelisting flag was explicitly set
458         if (mAllowBackgroundActivityStarts) {
459             if (DEBUG_ACTIVITY_STARTS) {
460                 Slog.d(TAG, "[WindowProcessController(" + mPid
461                         + ")] Activity start allowed: mAllowBackgroundActivityStarts = true");
462             }
463             return true;
464         }
465         // allow if any activity in the caller has either started or finished very recently, and
466         // it must be started or finished after last stop app switches time.
467         final long now = SystemClock.uptimeMillis();
468         if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
469                 || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
470             // if activity is started and finished before stop app switch time, we should not
471             // let app to be able to start background activity even it's in grace period.
472             if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
473                     || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
474                 if (DEBUG_ACTIVITY_STARTS) {
475                     Slog.d(TAG, "[WindowProcessController(" + mPid
476                             + ")] Activity start allowed: within "
477                             + ACTIVITY_BG_START_GRACE_PERIOD_MS + "ms grace period");
478                 }
479                 return true;
480             }
481             if (DEBUG_ACTIVITY_STARTS) {
482                 Slog.d(TAG, "[WindowProcessController(" + mPid + ")] Activity start within "
483                         + ACTIVITY_BG_START_GRACE_PERIOD_MS
484                         + "ms grace period but also within stop app switch window");
485             }
486 
487         }
488         // allow if the proc is instrumenting with background activity starts privs
489         if (mInstrumentingWithBackgroundActivityStartPrivileges) {
490             if (DEBUG_ACTIVITY_STARTS) {
491                 Slog.d(TAG, "[WindowProcessController(" + mPid
492                         + ")] Activity start allowed: process instrumenting with background "
493                         + "activity starts privileges");
494             }
495             return true;
496         }
497         // allow if the caller has an activity in any foreground task
498         if (hasActivityInVisibleTask()) {
499             if (DEBUG_ACTIVITY_STARTS) {
500                 Slog.d(TAG, "[WindowProcessController(" + mPid
501                         + ")] Activity start allowed: process has activity in foreground task");
502             }
503             return true;
504         }
505         // allow if the caller is bound by a UID that's currently foreground
506         if (isBoundByForegroundUid()) {
507             if (DEBUG_ACTIVITY_STARTS) {
508                 Slog.d(TAG, "[WindowProcessController(" + mPid
509                         + ")] Activity start allowed: process bound by foreground uid");
510             }
511             return true;
512         }
513         return false;
514     }
515 
isBoundByForegroundUid()516     private boolean isBoundByForegroundUid() {
517         for (int i = mBoundClientUids.size() - 1; i >= 0; --i) {
518             if (mAtm.isUidForeground(mBoundClientUids.valueAt(i))) {
519                 return true;
520             }
521         }
522         return false;
523     }
524 
setBoundClientUids(ArraySet<Integer> boundClientUids)525     public void setBoundClientUids(ArraySet<Integer> boundClientUids) {
526         mBoundClientUids = boundClientUids;
527     }
528 
setInstrumenting(boolean instrumenting, boolean hasBackgroundActivityStartPrivileges)529     public void setInstrumenting(boolean instrumenting,
530             boolean hasBackgroundActivityStartPrivileges) {
531         mInstrumenting = instrumenting;
532         mInstrumentingWithBackgroundActivityStartPrivileges = hasBackgroundActivityStartPrivileges;
533     }
534 
isInstrumenting()535     boolean isInstrumenting() {
536         return mInstrumenting;
537     }
538 
setPerceptible(boolean perceptible)539     public void setPerceptible(boolean perceptible) {
540         mPerceptible = perceptible;
541     }
542 
isPerceptible()543     boolean isPerceptible() {
544         return mPerceptible;
545     }
546 
547     @Override
getChildCount()548     protected int getChildCount() {
549         return 0;
550     }
551 
552     @Override
getChildAt(int index)553     protected ConfigurationContainer getChildAt(int index) {
554         return null;
555     }
556 
557     @Override
getParent()558     protected ConfigurationContainer getParent() {
559         // Returning RootWindowContainer as the parent, so that this process controller always
560         // has full configuration and overrides (e.g. from display) are always added on top of
561         // global config.
562         return mAtm.mRootWindowContainer;
563     }
564 
565     @HotPath(caller = HotPath.PROCESS_CHANGE)
addPackage(String packageName)566     public void addPackage(String packageName) {
567         synchronized (mAtm.mGlobalLockWithoutBoost) {
568             mPkgList.add(packageName);
569         }
570     }
571 
572     @HotPath(caller = HotPath.PROCESS_CHANGE)
clearPackageList()573     public void clearPackageList() {
574         synchronized (mAtm.mGlobalLockWithoutBoost) {
575             mPkgList.clear();
576         }
577     }
578 
addActivityIfNeeded(ActivityRecord r)579     void addActivityIfNeeded(ActivityRecord r) {
580         // even if we already track this activity, note down that it has been launched
581         setLastActivityLaunchTime(r.lastLaunchTime);
582         if (mActivities.contains(r)) {
583             return;
584         }
585         mActivities.add(r);
586         updateActivityConfigurationListener();
587     }
588 
removeActivity(ActivityRecord r)589     void removeActivity(ActivityRecord r) {
590         mActivities.remove(r);
591         updateActivityConfigurationListener();
592     }
593 
makeFinishingForProcessRemoved()594     void makeFinishingForProcessRemoved() {
595         for (int i = mActivities.size() - 1; i >= 0; --i) {
596             mActivities.get(i).makeFinishingLocked();
597         }
598     }
599 
clearActivities()600     void clearActivities() {
601         mActivities.clear();
602         updateActivityConfigurationListener();
603     }
604 
605     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
hasActivities()606     public boolean hasActivities() {
607         synchronized (mAtm.mGlobalLockWithoutBoost) {
608             return !mActivities.isEmpty();
609         }
610     }
611 
612     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
hasVisibleActivities()613     public boolean hasVisibleActivities() {
614         synchronized (mAtm.mGlobalLockWithoutBoost) {
615             for (int i = mActivities.size() - 1; i >= 0; --i) {
616                 final ActivityRecord r = mActivities.get(i);
617                 if (r.mVisibleRequested) {
618                     return true;
619                 }
620             }
621         }
622         return false;
623     }
624 
625     @HotPath(caller = HotPath.LRU_UPDATE)
hasActivitiesOrRecentTasks()626     public boolean hasActivitiesOrRecentTasks() {
627         synchronized (mAtm.mGlobalLockWithoutBoost) {
628             return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
629         }
630     }
631 
hasActivityInVisibleTask()632     private boolean hasActivityInVisibleTask() {
633         for (int i = mActivities.size() - 1; i >= 0; --i) {
634             Task task = mActivities.get(i).getTask();
635             if (task == null) {
636                 continue;
637             }
638             ActivityRecord topActivity = task.getTopNonFinishingActivity();
639             if (topActivity != null && topActivity.mVisibleRequested) {
640                 return true;
641             }
642         }
643         return false;
644     }
645 
646     /**
647      * Update the top resuming activity in process for pre-Q apps, only the top-most visible
648      * activities are allowed to be resumed per process.
649      * @return {@code true} if the activity is allowed to be resumed by compatibility
650      * restrictions, which the activity was the topmost visible activity in process or the app is
651      * targeting after Q. Note that non-focusable activity, in picture-in-picture mode for instance,
652      * does not count as a topmost activity.
653      */
updateTopResumingActivityInProcessIfNeeded(@onNull ActivityRecord activity)654     boolean updateTopResumingActivityInProcessIfNeeded(@NonNull ActivityRecord activity) {
655         if (mInfo.targetSdkVersion >= Q || mPreQTopResumedActivity == activity) {
656             return true;
657         }
658 
659         final DisplayContent display = activity.getDisplay();
660         if (display == null) {
661             // No need to update if the activity hasn't attach to any display.
662             return false;
663         }
664 
665         boolean canUpdate = false;
666         final DisplayContent topDisplay =
667                 mPreQTopResumedActivity != null ? mPreQTopResumedActivity.getDisplay() : null;
668         // Update the topmost activity if current top activity is
669         // - not on any display OR
670         // - no longer visible OR
671         // - not focusable (in PiP mode for instance)
672         if (topDisplay == null
673                 || !mPreQTopResumedActivity.mVisibleRequested
674                 || !mPreQTopResumedActivity.isFocusable()) {
675             canUpdate = true;
676         }
677 
678         // Update the topmost activity if the current top activity wasn't on top of the other one.
679         if (!canUpdate && topDisplay.mDisplayContent.compareTo(display.mDisplayContent) < 0) {
680             canUpdate = true;
681         }
682 
683         // Compare the z-order of ActivityStacks if both activities landed on same display.
684         if (display == topDisplay
685                 && mPreQTopResumedActivity.getRootTask().compareTo(
686                         activity.getRootTask()) <= 0) {
687             canUpdate = true;
688         }
689 
690         if (canUpdate) {
691             // Make sure the previous top activity in the process no longer be resumed.
692             if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) {
693                 final ActivityStack stack = mPreQTopResumedActivity.getRootTask();
694                 if (stack != null) {
695                     stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
696                             activity);
697                 }
698             }
699             mPreQTopResumedActivity = activity;
700         }
701         return canUpdate;
702     }
703 
stopFreezingActivities()704     public void stopFreezingActivities() {
705         synchronized (mAtm.mGlobalLock) {
706             int i = mActivities.size();
707             while (i > 0) {
708                 i--;
709                 mActivities.get(i).stopFreezingScreenLocked(true);
710             }
711         }
712     }
713 
finishActivities()714     void finishActivities() {
715         ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities);
716         for (int i = 0; i < activities.size(); i++) {
717             final ActivityRecord r = activities.get(i);
718             if (!r.finishing && r.isInStackLocked()) {
719                 r.finishIfPossible("finish-heavy", true /* oomAdj */);
720             }
721         }
722     }
723 
isInterestingToUser()724     public boolean isInterestingToUser() {
725         synchronized (mAtm.mGlobalLock) {
726             final int size = mActivities.size();
727             for (int i = 0; i < size; i++) {
728                 ActivityRecord r = mActivities.get(i);
729                 if (r.isInterestingToUserLocked()) {
730                     return true;
731                 }
732             }
733             if (isEmbedded()) {
734                 return true;
735             }
736         }
737         return false;
738     }
739 
740     /**
741      * @return {@code true} if this process is rendering content on to a window shown by
742      * another process.
743      */
isEmbedded()744     private boolean isEmbedded() {
745         for (int i = mHostActivities.size() - 1; i >= 0; --i) {
746             final ActivityRecord r = mHostActivities.get(i);
747             if (r.isInterestingToUserLocked()) {
748                 return true;
749             }
750         }
751         return false;
752     }
753 
hasRunningActivity(String packageName)754     public boolean hasRunningActivity(String packageName) {
755         synchronized (mAtm.mGlobalLock) {
756             for (int i = mActivities.size() - 1; i >= 0; --i) {
757                 final ActivityRecord r = mActivities.get(i);
758                 if (packageName.equals(r.packageName)) {
759                     return true;
760                 }
761             }
762         }
763         return false;
764     }
765 
clearPackagePreferredForHomeActivities()766     public void clearPackagePreferredForHomeActivities() {
767         synchronized (mAtm.mGlobalLock) {
768             for (int i = mActivities.size() - 1; i >= 0; --i) {
769                 final ActivityRecord r = mActivities.get(i);
770                 if (r.isActivityTypeHome()) {
771                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
772                     try {
773                         ActivityThread.getPackageManager()
774                                 .clearPackagePreferredActivities(r.packageName);
775                     } catch (RemoteException c) {
776                         // pm is in same process, this will never happen.
777                     }
778                 }
779             }
780         }
781     }
782 
hasStartedActivity(ActivityRecord launchedActivity)783     boolean hasStartedActivity(ActivityRecord launchedActivity) {
784         for (int i = mActivities.size() - 1; i >= 0; i--) {
785             final ActivityRecord activity = mActivities.get(i);
786             if (launchedActivity == activity) {
787                 continue;
788             }
789             if (!activity.stopped) {
790                 return true;
791             }
792         }
793         return false;
794     }
795 
hasResumedActivity()796     boolean hasResumedActivity() {
797         for (int i = mActivities.size() - 1; i >= 0; --i) {
798             final ActivityRecord activity = mActivities.get(i);
799             if (activity.isState(RESUMED)) {
800                 return true;
801             }
802         }
803         return false;
804     }
805 
806 
updateIntentForHeavyWeightActivity(Intent intent)807     void updateIntentForHeavyWeightActivity(Intent intent) {
808         if (mActivities.isEmpty()) {
809             return;
810         }
811         ActivityRecord hist = mActivities.get(0);
812         intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
813         intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTask().mTaskId);
814     }
815 
shouldKillProcessForRemovedTask(Task task)816     boolean shouldKillProcessForRemovedTask(Task task) {
817         for (int k = 0; k < mActivities.size(); k++) {
818             final ActivityRecord activity = mActivities.get(k);
819             if (!activity.stopped) {
820                 // Don't kill process(es) that has an activity not stopped.
821                 return false;
822             }
823             final Task otherTask = activity.getTask();
824             if (task.mTaskId != otherTask.mTaskId && otherTask.inRecents) {
825                 // Don't kill process(es) that has an activity in a different task that is
826                 // also in recents.
827                 return false;
828             }
829         }
830         return true;
831     }
832 
releaseSomeActivities(String reason)833     void releaseSomeActivities(String reason) {
834         // Examine all activities currently running in the process.
835         // Candidate activities that can be destroyed.
836         ArrayList<ActivityRecord> candidates = null;
837         if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this);
838         for (int i = 0; i < mActivities.size(); i++) {
839             final ActivityRecord r = mActivities.get(i);
840             // First, if we find an activity that is in the process of being destroyed,
841             // then we just aren't going to do anything for now; we want things to settle
842             // down before we try to prune more activities.
843             if (r.finishing || r.isState(DESTROYING, DESTROYED)) {
844                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
845                 return;
846             }
847             // Don't consider any activities that are currently not in a state where they
848             // can be destroyed.
849             if (r.mVisibleRequested || !r.stopped || !r.hasSavedState() || !r.isDestroyable()
850                     || r.isState(STARTED, RESUMED, PAUSING, PAUSED, STOPPING)) {
851                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
852                 continue;
853             }
854 
855             if (r.getParent() != null) {
856                 if (candidates == null) {
857                     candidates = new ArrayList<>();
858                 }
859                 candidates.add(r);
860             }
861         }
862 
863         if (candidates != null) {
864             // Sort based on z-order in hierarchy.
865             candidates.sort(WindowContainer::compareTo);
866             // Release some older activities
867             int maxRelease = Math.max(candidates.size(), 1);
868             do {
869                 final ActivityRecord r = candidates.remove(0);
870                 if (DEBUG_RELEASE) Slog.v(TAG_RELEASE, "Destroying " + r
871                         + " in state " + r.getState() + " for reason " + reason);
872                 r.destroyImmediately(true /*removeFromApp*/, reason);
873                 --maxRelease;
874             } while (maxRelease > 0);
875         }
876     }
877 
878     /**
879      * Returns display UI context list which there is any app window shows or starting activities
880      * int this process.
881      */
getDisplayContextsWithErrorDialogs(List<Context> displayContexts)882     public void getDisplayContextsWithErrorDialogs(List<Context> displayContexts) {
883         if (displayContexts == null) {
884             return;
885         }
886         synchronized (mAtm.mGlobalLock) {
887             final RootWindowContainer root = mAtm.mWindowManager.mRoot;
888             root.getDisplayContextsWithNonToastVisibleWindows(mPid, displayContexts);
889 
890             for (int i = mActivities.size() - 1; i >= 0; --i) {
891                 final ActivityRecord r = mActivities.get(i);
892                 final int displayId = r.getDisplayId();
893                 final Context c = root.getDisplayUiContext(displayId);
894 
895                 if (r.mVisibleRequested && !displayContexts.contains(c)) {
896                     displayContexts.add(c);
897                 }
898             }
899         }
900     }
901 
902     /** Adds an activity that hosts UI drawn by the current process. */
addHostActivity(ActivityRecord r)903     void addHostActivity(ActivityRecord r) {
904         if (mHostActivities.contains(r)) {
905             return;
906         }
907         mHostActivities.add(r);
908     }
909 
910     /** Removes an activity that hosts UI drawn by the current process. */
removeHostActivity(ActivityRecord r)911     void removeHostActivity(ActivityRecord r) {
912         mHostActivities.remove(r);
913     }
914 
915     public interface ComputeOomAdjCallback {
onVisibleActivity()916         void onVisibleActivity();
onPausedActivity()917         void onPausedActivity();
onStoppingActivity(boolean finishing)918         void onStoppingActivity(boolean finishing);
onOtherActivity()919         void onOtherActivity();
920     }
921 
922     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback)923     public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
924         // Since there could be more than one activities in a process record, we don't need to
925         // compute the OomAdj with each of them, just need to find out the activity with the
926         // "best" state, the order would be visible, pausing, stopping...
927         ActivityStack.ActivityState best = DESTROYED;
928         boolean finishing = true;
929         boolean visible = false;
930         synchronized (mAtm.mGlobalLockWithoutBoost) {
931             final int activitiesSize = mActivities.size();
932             for (int j = 0; j < activitiesSize; j++) {
933                 final ActivityRecord r = mActivities.get(j);
934                 if (r.app != this) {
935                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
936                             + " instead of expected " + this);
937                     if (r.app == null || (r.app.mUid == mUid)) {
938                         // Only fix things up when they look sane
939                         r.setProcess(this);
940                     } else {
941                         continue;
942                     }
943                 }
944                 if (r.mVisibleRequested) {
945                     final Task task = r.getTask();
946                     if (task != null && minTaskLayer > 0) {
947                         final int layer = task.mLayerRank;
948                         if (layer >= 0 && minTaskLayer > layer) {
949                             minTaskLayer = layer;
950                         }
951                     }
952                     visible = true;
953                     // continue the loop, in case there are multiple visible activities in
954                     // this process, we'd find out the one with the minimal layer, thus it'll
955                     // get a higher adj score.
956                 } else {
957                     if (best != PAUSING && best != PAUSED) {
958                         if (r.isState(PAUSING, PAUSED)) {
959                             best = PAUSING;
960                         } else if (r.isState(STOPPING)) {
961                             best = STOPPING;
962                             // Not "finishing" if any of activity isn't finishing.
963                             finishing &= r.finishing;
964                         }
965                     }
966                 }
967             }
968         }
969         if (visible) {
970             callback.onVisibleActivity();
971         } else if (best == PAUSING) {
972             callback.onPausedActivity();
973         } else if (best == STOPPING) {
974             callback.onStoppingActivity(finishing);
975         } else {
976             callback.onOtherActivity();
977         }
978 
979         return minTaskLayer;
980     }
981 
computeRelaunchReason()982     public int computeRelaunchReason() {
983         synchronized (mAtm.mGlobalLock) {
984             final int activitiesSize = mActivities.size();
985             for (int i = activitiesSize - 1; i >= 0; i--) {
986                 final ActivityRecord r = mActivities.get(i);
987                 if (r.mRelaunchReason != RELAUNCH_REASON_NONE) {
988                     return r.mRelaunchReason;
989                 }
990             }
991         }
992         return RELAUNCH_REASON_NONE;
993     }
994 
getInputDispatchingTimeout()995     public long getInputDispatchingTimeout() {
996         synchronized (mAtm.mGlobalLock) {
997             return isInstrumenting() || isUsingWrapper()
998                     ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS;
999         }
1000     }
1001 
clearProfilerIfNeeded()1002     void clearProfilerIfNeeded() {
1003         if (mListener == null) return;
1004         // Posting on handler so WM lock isn't held when we call into AM.
1005         mAtm.mH.sendMessage(PooledLambda.obtainMessage(
1006                 WindowProcessListener::clearProfilerIfNeeded, mListener));
1007     }
1008 
updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange, boolean updateOomAdj, boolean addPendingTopUid)1009     void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
1010             boolean updateOomAdj, boolean addPendingTopUid) {
1011         if (mListener == null) return;
1012         if (addPendingTopUid) {
1013             mAtm.mAmInternal.addPendingTopUid(mUid, mPid);
1014         }
1015         // Posting on handler so WM lock isn't held when we call into AM.
1016         final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
1017                 mListener, updateServiceConnectionActivities, activityChange, updateOomAdj);
1018         mAtm.mH.sendMessage(m);
1019     }
1020 
updateServiceConnectionActivities()1021     void updateServiceConnectionActivities() {
1022         if (mListener == null) return;
1023         // Posting on handler so WM lock isn't held when we call into AM.
1024         mAtm.mH.sendMessage(PooledLambda.obtainMessage(
1025                 WindowProcessListener::updateServiceConnectionActivities, mListener));
1026     }
1027 
setPendingUiCleanAndForceProcessStateUpTo(int newState)1028     void setPendingUiCleanAndForceProcessStateUpTo(int newState) {
1029         if (mListener == null) return;
1030         // Posting on handler so WM lock isn't held when we call into AM.
1031         final Message m = PooledLambda.obtainMessage(
1032                 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo,
1033                 mListener, newState);
1034         mAtm.mH.sendMessage(m);
1035     }
1036 
isRemoved()1037     boolean isRemoved() {
1038         return mListener == null ? false : mListener.isRemoved();
1039     }
1040 
shouldSetProfileProc()1041     private boolean shouldSetProfileProc() {
1042         return mAtm.mProfileApp != null && mAtm.mProfileApp.equals(mName)
1043                 && (mAtm.mProfileProc == null || mAtm.mProfileProc == this);
1044     }
1045 
createProfilerInfoIfNeeded()1046     ProfilerInfo createProfilerInfoIfNeeded() {
1047         final ProfilerInfo currentProfilerInfo = mAtm.mProfilerInfo;
1048         if (currentProfilerInfo == null || currentProfilerInfo.profileFile == null
1049                 || !shouldSetProfileProc()) {
1050             return null;
1051         }
1052         if (currentProfilerInfo.profileFd != null) {
1053             try {
1054                 currentProfilerInfo.profileFd = currentProfilerInfo.profileFd.dup();
1055             } catch (IOException e) {
1056                 currentProfilerInfo.closeFd();
1057             }
1058         }
1059         return new ProfilerInfo(currentProfilerInfo);
1060     }
1061 
onStartActivity(int topProcessState, ActivityInfo info)1062     void onStartActivity(int topProcessState, ActivityInfo info) {
1063         if (mListener == null) return;
1064         String packageName = null;
1065         if ((info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
1066                 || !"android".equals(info.packageName)) {
1067             // Don't add this if it is a platform component that is marked to run in multiple
1068             // processes, because this is actually part of the framework so doesn't make sense
1069             // to track as a separate apk in the process.
1070             packageName = info.packageName;
1071         }
1072         // update ActivityManagerService.PendingStartActivityUids list.
1073         if (topProcessState == ActivityManager.PROCESS_STATE_TOP) {
1074             mAtm.mAmInternal.addPendingTopUid(mUid, mPid);
1075         }
1076         // Posting the message at the front of queue so WM lock isn't held when we call into AM,
1077         // and the process state of starting activity can be updated quicker which will give it a
1078         // higher scheduling group.
1079         final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
1080                 mListener, topProcessState, shouldSetProfileProc(), packageName,
1081                 info.applicationInfo.longVersionCode);
1082         mAtm.mH.sendMessageAtFrontOfQueue(m);
1083     }
1084 
appDied(String reason)1085     void appDied(String reason) {
1086         if (mListener == null) return;
1087         // Posting on handler so WM lock isn't held when we call into AM.
1088         final Message m = PooledLambda.obtainMessage(
1089                 WindowProcessListener::appDied, mListener, reason);
1090         mAtm.mH.sendMessage(m);
1091     }
1092 
registerDisplayConfigurationListener(DisplayContent displayContent)1093     void registerDisplayConfigurationListener(DisplayContent displayContent) {
1094         if (displayContent == null) {
1095             return;
1096         }
1097         // A process can only register to one display to listen to the override configuration
1098         // change. Unregister existing listener if it has one before register the new one.
1099         unregisterDisplayConfigurationListener();
1100         unregisterActivityConfigurationListener();
1101         mDisplayId = displayContent.mDisplayId;
1102         displayContent.registerConfigurationChangeListener(this);
1103     }
1104 
1105     @VisibleForTesting
unregisterDisplayConfigurationListener()1106     void unregisterDisplayConfigurationListener() {
1107         if (mDisplayId == INVALID_DISPLAY) {
1108             return;
1109         }
1110         final DisplayContent displayContent =
1111                 mAtm.mRootWindowContainer.getDisplayContent(mDisplayId);
1112         if (displayContent != null) {
1113             displayContent.unregisterConfigurationChangeListener(this);
1114         }
1115         mDisplayId = INVALID_DISPLAY;
1116         onMergedOverrideConfigurationChanged(Configuration.EMPTY);
1117     }
1118 
registerActivityConfigurationListener(ActivityRecord activityRecord)1119     private void registerActivityConfigurationListener(ActivityRecord activityRecord) {
1120         if (activityRecord == null || activityRecord.containsListener(this)) {
1121             return;
1122         }
1123         // A process can only register to one activityRecord to listen to the override configuration
1124         // change. Unregister existing listener if it has one before register the new one.
1125         unregisterDisplayConfigurationListener();
1126         unregisterActivityConfigurationListener();
1127         mConfigActivityRecord = activityRecord;
1128         activityRecord.registerConfigurationChangeListener(this);
1129     }
1130 
unregisterActivityConfigurationListener()1131     private void unregisterActivityConfigurationListener() {
1132         if (mConfigActivityRecord == null) {
1133             return;
1134         }
1135         mConfigActivityRecord.unregisterConfigurationChangeListener(this);
1136         mConfigActivityRecord = null;
1137         onMergedOverrideConfigurationChanged(Configuration.EMPTY);
1138     }
1139 
1140     /**
1141      * Check if activity configuration override for the activity process needs an update and perform
1142      * if needed. By default we try to override the process configuration to match the top activity
1143      * config to increase app compatibility with multi-window and multi-display. The process will
1144      * always track the configuration of the non-finishing activity last added to the process.
1145      */
updateActivityConfigurationListener()1146     private void updateActivityConfigurationListener() {
1147         if (!mIsActivityConfigOverrideAllowed) {
1148             return;
1149         }
1150 
1151         for (int i = mActivities.size() - 1; i >= 0; i--) {
1152             final ActivityRecord activityRecord = mActivities.get(i);
1153             if (!activityRecord.finishing) {
1154                 // Eligible activity is found, update listener.
1155                 registerActivityConfigurationListener(activityRecord);
1156                 return;
1157             }
1158         }
1159 
1160         // No eligible activities found, let's remove the configuration listener.
1161         unregisterActivityConfigurationListener();
1162     }
1163 
1164     @Override
onConfigurationChanged(Configuration newGlobalConfig)1165     public void onConfigurationChanged(Configuration newGlobalConfig) {
1166         super.onConfigurationChanged(newGlobalConfig);
1167         updateConfiguration();
1168     }
1169 
1170     @Override
onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig)1171     public void onMergedOverrideConfigurationChanged(Configuration mergedOverrideConfig) {
1172         // Make sure that we don't accidentally override the activity type.
1173         mNewOverrideConfig.setTo(mergedOverrideConfig);
1174         mNewOverrideConfig.windowConfiguration.setActivityType(ACTIVITY_TYPE_UNDEFINED);
1175         super.onRequestedOverrideConfigurationChanged(mNewOverrideConfig);
1176     }
1177 
updateConfiguration()1178     private void updateConfiguration() {
1179         final Configuration config = getConfiguration();
1180         if (mLastReportedConfiguration.diff(config) == 0) {
1181             // Nothing changed.
1182             if (Build.IS_DEBUGGABLE && mHasImeService) {
1183                 // TODO (b/135719017): Temporary log for debugging IME service.
1184                 Slog.w(TAG_CONFIGURATION, "Current config: " + config
1185                         + " unchanged for IME proc " + mName);
1186             }
1187             return;
1188         }
1189 
1190         if (mListener.isCached()) {
1191             // This process is in a cached state. We will delay delivering the config change to the
1192             // process until the process is no longer cached.
1193             if (mPendingConfiguration == null) {
1194                 mPendingConfiguration = new Configuration(config);
1195             } else {
1196                 mPendingConfiguration.setTo(config);
1197             }
1198             return;
1199         }
1200 
1201         dispatchConfigurationChange(config);
1202     }
1203 
dispatchConfigurationChange(Configuration config)1204     private void dispatchConfigurationChange(Configuration config) {
1205         if (mThread == null) {
1206             if (Build.IS_DEBUGGABLE && mHasImeService) {
1207                 // TODO (b/135719017): Temporary log for debugging IME service.
1208                 Slog.w(TAG_CONFIGURATION, "Unable to send config for IME proc " + mName
1209                         + ": no app thread");
1210             }
1211             return;
1212         }
1213         if (DEBUG_CONFIGURATION) {
1214             Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName + " new config " + config);
1215         }
1216         if (Build.IS_DEBUGGABLE && mHasImeService) {
1217             // TODO (b/135719017): Temporary log for debugging IME service.
1218             Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config);
1219         }
1220 
1221         try {
1222             config.seq = mAtm.increaseConfigurationSeqLocked();
1223             mAtm.getLifecycleManager().scheduleTransaction(mThread,
1224                     ConfigurationChangeItem.obtain(config));
1225             setLastReportedConfiguration(config);
1226         } catch (Exception e) {
1227             Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
1228         }
1229     }
1230 
setLastReportedConfiguration(Configuration config)1231     private void setLastReportedConfiguration(Configuration config) {
1232         mLastReportedConfiguration.setTo(config);
1233     }
1234 
getLastReportedConfiguration()1235     Configuration getLastReportedConfiguration() {
1236         return mLastReportedConfiguration;
1237     }
1238 
1239     /** Returns the total time (in milliseconds) spent executing in both user and system code. */
getCpuTime()1240     public long getCpuTime() {
1241         return (mListener != null) ? mListener.getCpuTime() : 0;
1242     }
1243 
addRecentTask(Task task)1244     void addRecentTask(Task task) {
1245         mRecentTasks.add(task);
1246     }
1247 
removeRecentTask(Task task)1248     void removeRecentTask(Task task) {
1249         mRecentTasks.remove(task);
1250     }
1251 
1252     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
hasRecentTasks()1253     public boolean hasRecentTasks() {
1254         synchronized (mAtm.mGlobalLockWithoutBoost) {
1255             return !mRecentTasks.isEmpty();
1256         }
1257     }
1258 
clearRecentTasks()1259     void clearRecentTasks() {
1260         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1261             mRecentTasks.get(i).clearRootProcess();
1262         }
1263         mRecentTasks.clear();
1264     }
1265 
appEarlyNotResponding(String annotation, Runnable killAppCallback)1266     public void appEarlyNotResponding(String annotation, Runnable killAppCallback) {
1267         Runnable targetRunnable = null;
1268         synchronized (mAtm.mGlobalLock) {
1269             if (mAtm.mController == null) {
1270                 return;
1271             }
1272 
1273             try {
1274                 // 0 == continue, -1 = kill process immediately
1275                 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation);
1276                 if (res < 0 && mPid != MY_PID) {
1277                     targetRunnable = killAppCallback;
1278                 }
1279             } catch (RemoteException e) {
1280                 mAtm.mController = null;
1281                 Watchdog.getInstance().setActivityController(null);
1282             }
1283         }
1284         if (targetRunnable != null) {
1285             targetRunnable.run();
1286         }
1287     }
1288 
appNotResponding(String info, Runnable killAppCallback, Runnable serviceTimeoutCallback)1289     public boolean appNotResponding(String info, Runnable killAppCallback,
1290             Runnable serviceTimeoutCallback) {
1291         Runnable targetRunnable = null;
1292         synchronized (mAtm.mGlobalLock) {
1293             if (mAtm.mController == null) {
1294                 return false;
1295             }
1296 
1297             try {
1298                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
1299                 int res = mAtm.mController.appNotResponding(mName, mPid, info);
1300                 if (res != 0) {
1301                     if (res < 0 && mPid != MY_PID) {
1302                         targetRunnable = killAppCallback;
1303                     } else {
1304                         targetRunnable = serviceTimeoutCallback;
1305                     }
1306                 }
1307             } catch (RemoteException e) {
1308                 mAtm.mController = null;
1309                 Watchdog.getInstance().setActivityController(null);
1310                 return false;
1311             }
1312         }
1313         if (targetRunnable != null) {
1314             // Execute runnable outside WM lock since the runnable will hold AM lock
1315             targetRunnable.run();
1316             return true;
1317         }
1318         return false;
1319     }
1320 
1321     /**
1322      * Called to notify WindowProcessController of a change in the process's cached state.
1323      *
1324      * @param isCached whether or not the process is cached.
1325      */
1326     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
onProcCachedStateChanged(boolean isCached)1327     public void onProcCachedStateChanged(boolean isCached) {
1328         if (!isCached) {
1329             synchronized (mAtm.mGlobalLockWithoutBoost) {
1330                 if (mPendingConfiguration != null) {
1331                     final Configuration config = mPendingConfiguration;
1332                     mPendingConfiguration = null;
1333                     dispatchConfigurationChange(config);
1334                 }
1335             }
1336         }
1337     }
1338 
1339     /**
1340      * Called to notify {@link WindowProcessController} of a started service.
1341      *
1342      * @param serviceInfo information describing the started service.
1343      */
onServiceStarted(ServiceInfo serviceInfo)1344     public void onServiceStarted(ServiceInfo serviceInfo) {
1345         String permission = serviceInfo.permission;
1346         if (permission == null) {
1347             return;
1348         }
1349 
1350         // TODO: Audit remaining services for disabling activity override (Wallpaper, Dream, etc).
1351         switch (permission) {
1352             case Manifest.permission.BIND_INPUT_METHOD:
1353                 mHasImeService = true;
1354                 // Fall-through
1355             case Manifest.permission.BIND_ACCESSIBILITY_SERVICE:
1356             case Manifest.permission.BIND_VOICE_INTERACTION:
1357                 // We want to avoid overriding the config of these services with that of the
1358                 // activity as it could lead to incorrect display metrics. For ex, IME services
1359                 // expect their config to match the config of the display with the IME window
1360                 // showing.
1361                 mIsActivityConfigOverrideAllowed = false;
1362                 break;
1363             default:
1364                 break;
1365         }
1366     }
1367 
1368     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
onTopProcChanged()1369     public void onTopProcChanged() {
1370         synchronized (mAtm.mGlobalLockWithoutBoost) {
1371             mAtm.mVrController.onTopProcChangedLocked(this);
1372         }
1373     }
1374 
1375     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
isHomeProcess()1376     public boolean isHomeProcess() {
1377         synchronized (mAtm.mGlobalLockWithoutBoost) {
1378             return this == mAtm.mHomeProcess;
1379         }
1380     }
1381 
1382     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
isPreviousProcess()1383     public boolean isPreviousProcess() {
1384         synchronized (mAtm.mGlobalLockWithoutBoost) {
1385             return this == mAtm.mPreviousProcess;
1386         }
1387     }
1388 
setRunningRecentsAnimation(boolean running)1389     void setRunningRecentsAnimation(boolean running) {
1390         if (mRunningRecentsAnimation == running) {
1391             return;
1392         }
1393         mRunningRecentsAnimation = running;
1394         updateRunningRemoteOrRecentsAnimation();
1395     }
1396 
setRunningRemoteAnimation(boolean running)1397     void setRunningRemoteAnimation(boolean running) {
1398         if (mRunningRemoteAnimation == running) {
1399             return;
1400         }
1401         mRunningRemoteAnimation = running;
1402         updateRunningRemoteOrRecentsAnimation();
1403     }
1404 
updateRunningRemoteOrRecentsAnimation()1405     private void updateRunningRemoteOrRecentsAnimation() {
1406 
1407         // Posting on handler so WM lock isn't held when we call into AM.
1408         mAtm.mH.sendMessage(PooledLambda.obtainMessage(
1409                 WindowProcessListener::setRunningRemoteAnimation, mListener,
1410                 mRunningRecentsAnimation || mRunningRemoteAnimation));
1411     }
1412 
1413     @Override
toString()1414     public String toString() {
1415         return mOwner != null ? mOwner.toString() : null;
1416     }
1417 
dump(PrintWriter pw, String prefix)1418     public void dump(PrintWriter pw, String prefix) {
1419         synchronized (mAtm.mGlobalLock) {
1420             if (mActivities.size() > 0) {
1421                 pw.print(prefix); pw.println("Activities:");
1422                 for (int i = 0; i < mActivities.size(); i++) {
1423                     pw.print(prefix); pw.print("  - "); pw.println(mActivities.get(i));
1424                 }
1425             }
1426 
1427             if (mRecentTasks.size() > 0) {
1428                 pw.println(prefix + "Recent Tasks:");
1429                 for (int i = 0; i < mRecentTasks.size(); i++) {
1430                     pw.println(prefix + "  - " + mRecentTasks.get(i));
1431                 }
1432             }
1433 
1434             if (mVrThreadTid != 0) {
1435                 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid);
1436             }
1437         }
1438         pw.println(prefix + " Configuration=" + getConfiguration());
1439         pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
1440         pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
1441     }
1442 
dumpDebug(ProtoOutputStream proto, long fieldId)1443     void dumpDebug(ProtoOutputStream proto, long fieldId) {
1444         if (mListener != null) {
1445             mListener.dumpDebug(proto, fieldId);
1446         }
1447     }
1448 }
1449