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