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