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