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