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