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.os.Build.VERSION_CODES.Q;
21 import static android.view.Display.INVALID_DISPLAY;
22 
23 import static com.android.server.am.ActivityManagerService.MY_PID;
24 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
25 import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
26 import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
27 import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
28 import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
29 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
30 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
31 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
32 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
33 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
34 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
35 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
36 import static com.android.server.wm.ActivityTaskManagerService.ACTIVITY_BG_START_GRACE_PERIOD_MS;
37 import static com.android.server.wm.ActivityTaskManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
38 import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
39 import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
40 
41 import android.annotation.NonNull;
42 import android.app.Activity;
43 import android.app.ActivityThread;
44 import android.app.IApplicationThread;
45 import android.app.ProfilerInfo;
46 import android.app.servertransaction.ConfigurationChangeItem;
47 import android.content.Intent;
48 import android.content.pm.ActivityInfo;
49 import android.content.pm.ApplicationInfo;
50 import android.content.res.Configuration;
51 import android.os.Message;
52 import android.os.RemoteException;
53 import android.os.SystemClock;
54 import android.util.ArraySet;
55 import android.util.Log;
56 import android.util.Slog;
57 import android.util.proto.ProtoOutputStream;
58 import android.view.IRemoteAnimationRunner;
59 
60 import com.android.internal.annotations.VisibleForTesting;
61 import com.android.internal.app.HeavyWeightSwitcherActivity;
62 import com.android.internal.util.function.pooled.PooledLambda;
63 import com.android.server.Watchdog;
64 import com.android.server.wm.ActivityTaskManagerService.HotPath;
65 
66 import java.io.IOException;
67 import java.io.PrintWriter;
68 import java.util.ArrayList;
69 
70 /**
71  * The Activity Manager (AM) package manages the lifecycle of processes in the system through
72  * ProcessRecord. However, it is important for the Window Manager (WM) package to be aware
73  * of the processes and their state since it affects how WM manages windows and activities. This
74  * class that allows the ProcessRecord object in the AM package to communicate important
75  * changes to its state to the WM package in a structured way. WM package also uses
76  * {@link WindowProcessListener} to request changes to the process state on the AM side.
77  * Note that public calls into this class are assumed to be originating from outside the
78  * window manager so the window manager lock is held and appropriate permissions are checked before
79  * calls are allowed to proceed.
80  */
81 public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
82         implements ConfigurationContainerListener {
83     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM;
84     private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
85     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
86 
87     // all about the first app in the process
88     final ApplicationInfo mInfo;
89     final String mName;
90     final int mUid;
91     // The process of this application; 0 if none
92     private volatile int mPid;
93     // user of process.
94     final int mUserId;
95     // The owner of this window process controller object. Mainly for identification when we
96     // communicate back to the activity manager side.
97     public final Object mOwner;
98     // List of packages running in the process
99     final ArraySet<String> mPkgList = new ArraySet<>();
100     private final WindowProcessListener mListener;
101     private final ActivityTaskManagerService mAtm;
102     // The actual proc...  may be null only if 'persistent' is true (in which case we are in the
103     // process of launching the app)
104     private IApplicationThread mThread;
105     // Currently desired scheduling class
106     private volatile int mCurSchedGroup;
107     // Currently computed process state
108     private volatile int mCurProcState = PROCESS_STATE_NONEXISTENT;
109     // Last reported process state;
110     private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT;
111     // are we in the process of crashing?
112     private volatile boolean mCrashing;
113     // does the app have a not responding dialog?
114     private volatile boolean mNotResponding;
115     // always keep this application running?
116     private volatile boolean mPersistent;
117     // The ABI this process was launched with
118     private volatile String mRequiredAbi;
119     // Running any services that are foreground?
120     private volatile boolean mHasForegroundServices;
121     // Running any activities that are foreground?
122     private volatile boolean mHasForegroundActivities;
123     // Are there any client services with activities?
124     private volatile boolean mHasClientActivities;
125     // Is this process currently showing a non-activity UI that the user is interacting with?
126     // E.g. The status bar when it is expanded, but not when it is minimized. When true the process
127     // will be set to use the ProcessList#SCHED_GROUP_TOP_APP scheduling group to boost performance.
128     private volatile boolean mHasTopUi;
129     // Is the process currently showing a non-activity UI that overlays on-top of activity UIs on
130     // screen. E.g. display a window of type
131     // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY When true the process will
132     // oom adj score will be set to ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
133     // of the process getting killed.
134     private volatile boolean mHasOverlayUi;
135     // Want to clean up resources from showing UI?
136     private volatile boolean mPendingUiClean;
137     // The time we sent the last interaction event
138     private volatile long mInteractionEventTime;
139     // When we became foreground for interaction purposes
140     private volatile long mFgInteractionTime;
141     // When (uptime) the process last became unimportant
142     private volatile long mWhenUnimportant;
143     // was app launched for debugging?
144     private volatile boolean mDebugging;
145     // Active instrumentation running in process?
146     private volatile boolean mInstrumenting;
147     // Active instrumentation with background activity starts privilege running in process?
148     private volatile boolean mInstrumentingWithBackgroundActivityStartPrivileges;
149     // This process it perceptible by the user.
150     private volatile boolean mPerceptible;
151     // Set to true when process was launched with a wrapper attached
152     private volatile boolean mUsingWrapper;
153     // Set to true if this process is currently temporarily whitelisted to start activities even if
154     // it's not in the foreground
155     private volatile boolean mAllowBackgroundActivityStarts;
156     // Set of UIDs of clients currently bound to this process
157     private volatile ArraySet<Integer> mBoundClientUids = new ArraySet<Integer>();
158 
159     // Thread currently set for VR scheduling
160     int mVrThreadTid;
161 
162     // all activities running in the process
163     private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
164     // any tasks this process had run root activities in
165     private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>();
166     // The most recent top-most activity that was resumed in the process for pre-Q app.
167     private ActivityRecord mPreQTopResumedActivity = null;
168     // The last time an activity was launched in the process
169     private long mLastActivityLaunchTime;
170     // The last time an activity was finished in the process while the process participated
171     // in a visible task
172     private long mLastActivityFinishTime;
173 
174     // Last configuration that was reported to the process.
175     private final Configuration mLastReportedConfiguration;
176     // Registered display id as a listener to override config change
177     private int mDisplayId;
178 
179     /** Whether our process is currently running a {@link RecentsAnimation} */
180     private boolean mRunningRecentsAnimation;
181 
182     /** Whether our process is currently running a {@link IRemoteAnimationRunner} */
183     private boolean mRunningRemoteAnimation;
184 
WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info, String name, int uid, int userId, Object owner, WindowProcessListener listener)185     public WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info,
186             String name, int uid, int userId, Object owner, WindowProcessListener listener) {
187         mInfo = info;
188         mName = name;
189         mUid = uid;
190         mUserId = userId;
191         mOwner = owner;
192         mListener = listener;
193         mAtm = atm;
194         mLastReportedConfiguration = new Configuration();
195         mDisplayId = INVALID_DISPLAY;
196         if (atm != null) {
197             onConfigurationChanged(atm.getGlobalConfiguration());
198         }
199     }
200 
setPid(int pid)201     public void setPid(int pid) {
202         mPid = pid;
203     }
204 
getPid()205     public int getPid() {
206         return mPid;
207     }
208 
209     @HotPath(caller = HotPath.PROCESS_CHANGE)
setThread(IApplicationThread thread)210     public void setThread(IApplicationThread thread) {
211         synchronized (mAtm.mGlobalLockWithoutBoost) {
212             mThread = thread;
213         }
214     }
215 
getThread()216     IApplicationThread getThread() {
217         return mThread;
218     }
219 
hasThread()220     boolean hasThread() {
221         return mThread != null;
222     }
223 
setCurrentSchedulingGroup(int curSchedGroup)224     public void setCurrentSchedulingGroup(int curSchedGroup) {
225         mCurSchedGroup = curSchedGroup;
226     }
227 
getCurrentSchedulingGroup()228     int getCurrentSchedulingGroup() {
229         return mCurSchedGroup;
230     }
231 
setCurrentProcState(int curProcState)232     public void setCurrentProcState(int curProcState) {
233         mCurProcState = curProcState;
234     }
235 
getCurrentProcState()236     int getCurrentProcState() {
237         return mCurProcState;
238     }
239 
setReportedProcState(int repProcState)240     public void setReportedProcState(int repProcState) {
241         mRepProcState = repProcState;
242     }
243 
getReportedProcState()244     int getReportedProcState() {
245         return mRepProcState;
246     }
247 
setCrashing(boolean crashing)248     public void setCrashing(boolean crashing) {
249         mCrashing = crashing;
250     }
251 
isCrashing()252     boolean isCrashing() {
253         return mCrashing;
254     }
255 
setNotResponding(boolean notResponding)256     public void setNotResponding(boolean notResponding) {
257         mNotResponding = notResponding;
258     }
259 
isNotResponding()260     boolean isNotResponding() {
261         return mNotResponding;
262     }
263 
setPersistent(boolean persistent)264     public void setPersistent(boolean persistent) {
265         mPersistent = persistent;
266     }
267 
isPersistent()268     boolean isPersistent() {
269         return mPersistent;
270     }
271 
setHasForegroundServices(boolean hasForegroundServices)272     public void setHasForegroundServices(boolean hasForegroundServices) {
273         mHasForegroundServices = hasForegroundServices;
274     }
275 
hasForegroundServices()276     boolean hasForegroundServices() {
277         return mHasForegroundServices;
278     }
279 
setHasForegroundActivities(boolean hasForegroundActivities)280     public void setHasForegroundActivities(boolean hasForegroundActivities) {
281         mHasForegroundActivities = hasForegroundActivities;
282     }
283 
hasForegroundActivities()284     boolean hasForegroundActivities() {
285         return mHasForegroundActivities;
286     }
287 
setHasClientActivities(boolean hasClientActivities)288     public void setHasClientActivities(boolean hasClientActivities) {
289         mHasClientActivities = hasClientActivities;
290     }
291 
hasClientActivities()292     boolean hasClientActivities() {
293         return mHasClientActivities;
294     }
295 
setHasTopUi(boolean hasTopUi)296     public void setHasTopUi(boolean hasTopUi) {
297         mHasTopUi = hasTopUi;
298     }
299 
hasTopUi()300     boolean hasTopUi() {
301         return mHasTopUi;
302     }
303 
setHasOverlayUi(boolean hasOverlayUi)304     public void setHasOverlayUi(boolean hasOverlayUi) {
305         mHasOverlayUi = hasOverlayUi;
306     }
307 
hasOverlayUi()308     boolean hasOverlayUi() {
309         return mHasOverlayUi;
310     }
311 
setPendingUiClean(boolean hasPendingUiClean)312     public void setPendingUiClean(boolean hasPendingUiClean) {
313         mPendingUiClean = hasPendingUiClean;
314     }
315 
hasPendingUiClean()316     boolean hasPendingUiClean() {
317         return mPendingUiClean;
318     }
319 
320     /** @return {@code true} if the process registered to a display as a config listener. */
registeredForDisplayConfigChanges()321     boolean registeredForDisplayConfigChanges() {
322         return mDisplayId != INVALID_DISPLAY;
323     }
324 
postPendingUiCleanMsg(boolean pendingUiClean)325     void postPendingUiCleanMsg(boolean pendingUiClean) {
326         if (mListener == null) return;
327         // Posting on handler so WM lock isn't held when we call into AM.
328         final Message m = PooledLambda.obtainMessage(
329                 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
330         mAtm.mH.sendMessage(m);
331     }
332 
setInteractionEventTime(long interactionEventTime)333     public void setInteractionEventTime(long interactionEventTime) {
334         mInteractionEventTime = interactionEventTime;
335     }
336 
getInteractionEventTime()337     long getInteractionEventTime() {
338         return mInteractionEventTime;
339     }
340 
setFgInteractionTime(long fgInteractionTime)341     public void setFgInteractionTime(long fgInteractionTime) {
342         mFgInteractionTime = fgInteractionTime;
343     }
344 
getFgInteractionTime()345     long getFgInteractionTime() {
346         return mFgInteractionTime;
347     }
348 
setWhenUnimportant(long whenUnimportant)349     public void setWhenUnimportant(long whenUnimportant) {
350         mWhenUnimportant = whenUnimportant;
351     }
352 
getWhenUnimportant()353     long getWhenUnimportant() {
354         return mWhenUnimportant;
355     }
356 
setRequiredAbi(String requiredAbi)357     public void setRequiredAbi(String requiredAbi) {
358         mRequiredAbi = requiredAbi;
359     }
360 
getRequiredAbi()361     String getRequiredAbi() {
362         return mRequiredAbi;
363     }
364 
365     /** Returns ID of display overriding the configuration for this process, or
366      *  INVALID_DISPLAY if no display is overriding. */
367     @VisibleForTesting
getDisplayId()368     int getDisplayId() {
369         return mDisplayId;
370     }
371 
setDebugging(boolean debugging)372     public void setDebugging(boolean debugging) {
373         mDebugging = debugging;
374     }
375 
isDebugging()376     boolean isDebugging() {
377         return mDebugging;
378     }
379 
setUsingWrapper(boolean usingWrapper)380     public void setUsingWrapper(boolean usingWrapper) {
381         mUsingWrapper = usingWrapper;
382     }
383 
isUsingWrapper()384     boolean isUsingWrapper() {
385         return mUsingWrapper;
386     }
387 
setLastActivityLaunchTime(long launchTime)388     void setLastActivityLaunchTime(long launchTime) {
389         if (launchTime <= mLastActivityLaunchTime) {
390             return;
391         }
392         mLastActivityLaunchTime = launchTime;
393     }
394 
setLastActivityFinishTimeIfNeeded(long finishTime)395     void setLastActivityFinishTimeIfNeeded(long finishTime) {
396         if (finishTime <= mLastActivityFinishTime || !hasActivityInVisibleTask()) {
397             return;
398         }
399         mLastActivityFinishTime = finishTime;
400     }
401 
setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts)402     public void setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts) {
403         mAllowBackgroundActivityStarts = allowBackgroundActivityStarts;
404     }
405 
areBackgroundActivityStartsAllowed()406     boolean areBackgroundActivityStartsAllowed() {
407         // allow if the whitelisting flag was explicitly set
408         if (mAllowBackgroundActivityStarts) {
409             return true;
410         }
411         // allow if any activity in the caller has either started or finished very recently, and
412         // it must be started or finished after last stop app switches time.
413         final long now = SystemClock.uptimeMillis();
414         if (now - mLastActivityLaunchTime < ACTIVITY_BG_START_GRACE_PERIOD_MS
415                 || now - mLastActivityFinishTime < ACTIVITY_BG_START_GRACE_PERIOD_MS) {
416             // if activity is started and finished before stop app switch time, we should not
417             // let app to be able to start background activity even it's in grace period.
418             if (mLastActivityLaunchTime > mAtm.getLastStopAppSwitchesTime()
419                     || mLastActivityFinishTime > mAtm.getLastStopAppSwitchesTime()) {
420                 return true;
421             }
422         }
423         // allow if the proc is instrumenting with background activity starts privs
424         if (mInstrumentingWithBackgroundActivityStartPrivileges) {
425             return true;
426         }
427         // allow if the caller has an activity in any foreground task
428         if (hasActivityInVisibleTask()) {
429             return true;
430         }
431         // allow if the caller is bound by a UID that's currently foreground
432         if (isBoundByForegroundUid()) {
433             return true;
434         }
435         return false;
436     }
437 
isBoundByForegroundUid()438     private boolean isBoundByForegroundUid() {
439         for (int i = mBoundClientUids.size() - 1; i >= 0; --i) {
440             if (mAtm.isUidForeground(mBoundClientUids.valueAt(i))) {
441                 return true;
442             }
443         }
444         return false;
445     }
446 
setBoundClientUids(ArraySet<Integer> boundClientUids)447     public void setBoundClientUids(ArraySet<Integer> boundClientUids) {
448         mBoundClientUids = boundClientUids;
449     }
450 
setInstrumenting(boolean instrumenting, boolean hasBackgroundActivityStartPrivileges)451     public void setInstrumenting(boolean instrumenting,
452             boolean hasBackgroundActivityStartPrivileges) {
453         mInstrumenting = instrumenting;
454         mInstrumentingWithBackgroundActivityStartPrivileges = hasBackgroundActivityStartPrivileges;
455     }
456 
isInstrumenting()457     boolean isInstrumenting() {
458         return mInstrumenting;
459     }
460 
setPerceptible(boolean perceptible)461     public void setPerceptible(boolean perceptible) {
462         mPerceptible = perceptible;
463     }
464 
isPerceptible()465     boolean isPerceptible() {
466         return mPerceptible;
467     }
468 
469     @Override
getChildCount()470     protected int getChildCount() {
471         return 0;
472     }
473 
474     @Override
getChildAt(int index)475     protected ConfigurationContainer getChildAt(int index) {
476         return null;
477     }
478 
479     @Override
getParent()480     protected ConfigurationContainer getParent() {
481         return null;
482     }
483 
484     @HotPath(caller = HotPath.PROCESS_CHANGE)
addPackage(String packageName)485     public void addPackage(String packageName) {
486         synchronized (mAtm.mGlobalLockWithoutBoost) {
487             mPkgList.add(packageName);
488         }
489     }
490 
491     @HotPath(caller = HotPath.PROCESS_CHANGE)
clearPackageList()492     public void clearPackageList() {
493         synchronized (mAtm.mGlobalLockWithoutBoost) {
494             mPkgList.clear();
495         }
496     }
497 
addActivityIfNeeded(ActivityRecord r)498     void addActivityIfNeeded(ActivityRecord r) {
499         // even if we already track this activity, note down that it has been launched
500         setLastActivityLaunchTime(r.lastLaunchTime);
501         if (mActivities.contains(r)) {
502             return;
503         }
504         mActivities.add(r);
505     }
506 
removeActivity(ActivityRecord r)507     void removeActivity(ActivityRecord r) {
508         mActivities.remove(r);
509     }
510 
makeFinishingForProcessRemoved()511     void makeFinishingForProcessRemoved() {
512         for (int i = mActivities.size() - 1; i >= 0; --i) {
513             mActivities.get(i).makeFinishingLocked();
514         }
515     }
516 
clearActivities()517     void clearActivities() {
518         mActivities.clear();
519     }
520 
521     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
hasActivities()522     public boolean hasActivities() {
523         synchronized (mAtm.mGlobalLockWithoutBoost) {
524             return !mActivities.isEmpty();
525         }
526     }
527 
528     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
hasVisibleActivities()529     public boolean hasVisibleActivities() {
530         synchronized (mAtm.mGlobalLockWithoutBoost) {
531             for (int i = mActivities.size() - 1; i >= 0; --i) {
532                 final ActivityRecord r = mActivities.get(i);
533                 if (r.visible) {
534                     return true;
535                 }
536             }
537         }
538         return false;
539     }
540 
541     @HotPath(caller = HotPath.LRU_UPDATE)
hasActivitiesOrRecentTasks()542     public boolean hasActivitiesOrRecentTasks() {
543         synchronized (mAtm.mGlobalLockWithoutBoost) {
544             return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
545         }
546     }
547 
hasActivityInVisibleTask()548     private boolean hasActivityInVisibleTask() {
549         for (int i = mActivities.size() - 1; i >= 0; --i) {
550             TaskRecord task = mActivities.get(i).getTaskRecord();
551             if (task == null) {
552                 continue;
553             }
554             ActivityRecord topActivity = task.getTopActivity();
555             if (topActivity != null && topActivity.visible) {
556                 return true;
557             }
558         }
559         return false;
560     }
561 
562     /**
563      * Update the top resuming activity in process for pre-Q apps, only the top-most visible
564      * activities are allowed to be resumed per process.
565      * @return {@code true} if the activity is allowed to be resumed by compatibility
566      * restrictions, which the activity was the topmost visible activity in process or the app is
567      * targeting after Q. Note that non-focusable activity, in picture-in-picture mode for instance,
568      * does not count as a topmost activity.
569      */
updateTopResumingActivityInProcessIfNeeded(@onNull ActivityRecord activity)570     boolean updateTopResumingActivityInProcessIfNeeded(@NonNull ActivityRecord activity) {
571         if (mInfo.targetSdkVersion >= Q || mPreQTopResumedActivity == activity) {
572             return true;
573         }
574 
575         final ActivityDisplay display = activity.getDisplay();
576         if (display == null) {
577             // No need to update if the activity hasn't attach to any display.
578             return false;
579         }
580 
581         boolean canUpdate = false;
582         final ActivityDisplay topDisplay =
583                 mPreQTopResumedActivity != null ? mPreQTopResumedActivity.getDisplay() : null;
584         // Update the topmost activity if current top activity is
585         // - not on any display OR
586         // - no longer visible OR
587         // - not focusable (in PiP mode for instance)
588         if (topDisplay == null
589                 || !mPreQTopResumedActivity.visible
590                 || !mPreQTopResumedActivity.isFocusable()) {
591             canUpdate = true;
592         }
593 
594         // Update the topmost activity if the current top activity wasn't on top of the other one.
595         if (!canUpdate && topDisplay.mDisplayContent.compareTo(display.mDisplayContent) < 0) {
596             canUpdate = true;
597         }
598 
599         // Compare the z-order of ActivityStacks if both activities landed on same display.
600         if (display == topDisplay
601                 && mPreQTopResumedActivity.getActivityStack().mTaskStack.compareTo(
602                 activity.getActivityStack().mTaskStack) <= 0) {
603             canUpdate = true;
604         }
605 
606         if (canUpdate) {
607             // Make sure the previous top activity in the process no longer be resumed.
608             if (mPreQTopResumedActivity != null && mPreQTopResumedActivity.isState(RESUMED)) {
609                 final ActivityStack stack = mPreQTopResumedActivity.getActivityStack();
610                 if (stack != null) {
611                     stack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
612                             null /* resuming */, false /* pauseImmediately */);
613                 }
614             }
615             mPreQTopResumedActivity = activity;
616         }
617         return canUpdate;
618     }
619 
stopFreezingActivities()620     public void stopFreezingActivities() {
621         synchronized (mAtm.mGlobalLock) {
622             int i = mActivities.size();
623             while (i > 0) {
624                 i--;
625                 mActivities.get(i).stopFreezingScreenLocked(true);
626             }
627         }
628     }
629 
finishActivities()630     void finishActivities() {
631         ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities);
632         for (int i = 0; i < activities.size(); i++) {
633             final ActivityRecord r = activities.get(i);
634             if (!r.finishing && r.isInStackLocked()) {
635                 r.getActivityStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
636                         null, "finish-heavy", true);
637             }
638         }
639     }
640 
isInterestingToUser()641     public boolean isInterestingToUser() {
642         synchronized (mAtm.mGlobalLock) {
643             final int size = mActivities.size();
644             for (int i = 0; i < size; i++) {
645                 ActivityRecord r = mActivities.get(i);
646                 if (r.isInterestingToUserLocked()) {
647                     return true;
648                 }
649             }
650         }
651         return false;
652     }
653 
hasRunningActivity(String packageName)654     public boolean hasRunningActivity(String packageName) {
655         synchronized (mAtm.mGlobalLock) {
656             for (int i = mActivities.size() - 1; i >= 0; --i) {
657                 final ActivityRecord r = mActivities.get(i);
658                 if (packageName.equals(r.packageName)) {
659                     return true;
660                 }
661             }
662         }
663         return false;
664     }
665 
clearPackagePreferredForHomeActivities()666     public void clearPackagePreferredForHomeActivities() {
667         synchronized (mAtm.mGlobalLock) {
668             for (int i = mActivities.size() - 1; i >= 0; --i) {
669                 final ActivityRecord r = mActivities.get(i);
670                 if (r.isActivityTypeHome()) {
671                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
672                     try {
673                         ActivityThread.getPackageManager()
674                                 .clearPackagePreferredActivities(r.packageName);
675                     } catch (RemoteException c) {
676                         // pm is in same process, this will never happen.
677                     }
678                 }
679             }
680         }
681     }
682 
hasStartedActivity(ActivityRecord launchedActivity)683     boolean hasStartedActivity(ActivityRecord launchedActivity) {
684         for (int i = mActivities.size() - 1; i >= 0; i--) {
685             final ActivityRecord activity = mActivities.get(i);
686             if (launchedActivity == activity) {
687                 continue;
688             }
689             if (!activity.stopped) {
690                 return true;
691             }
692         }
693         return false;
694     }
695 
696 
updateIntentForHeavyWeightActivity(Intent intent)697     void updateIntentForHeavyWeightActivity(Intent intent) {
698         if (mActivities.isEmpty()) {
699             return;
700         }
701         ActivityRecord hist = mActivities.get(0);
702         intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
703         intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTaskRecord().taskId);
704     }
705 
shouldKillProcessForRemovedTask(TaskRecord tr)706     boolean shouldKillProcessForRemovedTask(TaskRecord tr) {
707         for (int k = 0; k < mActivities.size(); k++) {
708             final ActivityRecord activity = mActivities.get(k);
709             if (!activity.stopped) {
710                 // Don't kill process(es) that has an activity not stopped.
711                 return false;
712             }
713             final TaskRecord otherTask = activity.getTaskRecord();
714             if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
715                 // Don't kill process(es) that has an activity in a different task that is
716                 // also in recents.
717                 return false;
718             }
719         }
720         return true;
721     }
722 
getReleaseSomeActivitiesTasks()723     ArraySet<TaskRecord> getReleaseSomeActivitiesTasks() {
724         // Examine all activities currently running in the process.
725         TaskRecord firstTask = null;
726         // Tasks is non-null only if two or more tasks are found.
727         ArraySet<TaskRecord> tasks = null;
728         if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this);
729         for (int i = 0; i < mActivities.size(); i++) {
730             final ActivityRecord r = mActivities.get(i);
731             // First, if we find an activity that is in the process of being destroyed,
732             // then we just aren't going to do anything for now; we want things to settle
733             // down before we try to prune more activities.
734             if (r.finishing || r.isState(DESTROYING, DESTROYED)) {
735                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
736                 return null;
737             }
738             // Don't consider any activies that are currently not in a state where they
739             // can be destroyed.
740             if (r.visible || !r.stopped || !r.haveState
741                     || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) {
742                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
743                 continue;
744             }
745 
746             final TaskRecord task = r.getTaskRecord();
747             if (task != null) {
748                 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task
749                         + " from " + r);
750                 if (firstTask == null) {
751                     firstTask = task;
752                 } else if (firstTask != task) {
753                     if (tasks == null) {
754                         tasks = new ArraySet<>();
755                         tasks.add(firstTask);
756                     }
757                     tasks.add(task);
758                 }
759             }
760         }
761 
762         return tasks;
763     }
764 
765     public interface ComputeOomAdjCallback {
onVisibleActivity()766         void onVisibleActivity();
onPausedActivity()767         void onPausedActivity();
onStoppingActivity(boolean finishing)768         void onStoppingActivity(boolean finishing);
onOtherActivity()769         void onOtherActivity();
770     }
771 
772     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback)773     public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
774         synchronized (mAtm.mGlobalLockWithoutBoost) {
775             final int activitiesSize = mActivities.size();
776             for (int j = 0; j < activitiesSize; j++) {
777                 final ActivityRecord r = mActivities.get(j);
778                 if (r.app != this) {
779                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
780                             + " instead of expected " + this);
781                     if (r.app == null || (r.app.mUid == mUid)) {
782                         // Only fix things up when they look sane
783                         r.setProcess(this);
784                     } else {
785                         continue;
786                     }
787                 }
788                 if (r.visible) {
789                     callback.onVisibleActivity();
790                     final TaskRecord task = r.getTaskRecord();
791                     if (task != null && minTaskLayer > 0) {
792                         final int layer = task.mLayerRank;
793                         if (layer >= 0 && minTaskLayer > layer) {
794                             minTaskLayer = layer;
795                         }
796                     }
797                     break;
798                 } else if (r.isState(PAUSING, PAUSED)) {
799                     callback.onPausedActivity();
800                 } else if (r.isState(STOPPING)) {
801                     callback.onStoppingActivity(r.finishing);
802                 } else {
803                     callback.onOtherActivity();
804                 }
805             }
806         }
807 
808         return minTaskLayer;
809     }
810 
computeRelaunchReason()811     public int computeRelaunchReason() {
812         synchronized (mAtm.mGlobalLock) {
813             final int activitiesSize = mActivities.size();
814             for (int i = activitiesSize - 1; i >= 0; i--) {
815                 final ActivityRecord r = mActivities.get(i);
816                 if (r.mRelaunchReason != RELAUNCH_REASON_NONE) {
817                     return r.mRelaunchReason;
818                 }
819             }
820         }
821         return RELAUNCH_REASON_NONE;
822     }
823 
getInputDispatchingTimeout()824     public long getInputDispatchingTimeout() {
825         synchronized (mAtm.mGlobalLock) {
826             return isInstrumenting() || isUsingWrapper()
827                     ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS;
828         }
829     }
830 
clearProfilerIfNeeded()831     void clearProfilerIfNeeded() {
832         if (mListener == null) return;
833         // Posting on handler so WM lock isn't held when we call into AM.
834         mAtm.mH.sendMessage(PooledLambda.obtainMessage(
835                 WindowProcessListener::clearProfilerIfNeeded, mListener));
836     }
837 
updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange, boolean updateOomAdj)838     void updateProcessInfo(boolean updateServiceConnectionActivities, boolean activityChange,
839             boolean updateOomAdj) {
840         if (mListener == null) return;
841         // Posting on handler so WM lock isn't held when we call into AM.
842         final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
843                 mListener, updateServiceConnectionActivities, activityChange, updateOomAdj);
844         mAtm.mH.sendMessage(m);
845     }
846 
updateServiceConnectionActivities()847     void updateServiceConnectionActivities() {
848         if (mListener == null) return;
849         // Posting on handler so WM lock isn't held when we call into AM.
850         mAtm.mH.sendMessage(PooledLambda.obtainMessage(
851                 WindowProcessListener::updateServiceConnectionActivities, mListener));
852     }
853 
setPendingUiCleanAndForceProcessStateUpTo(int newState)854     void setPendingUiCleanAndForceProcessStateUpTo(int newState) {
855         if (mListener == null) return;
856         // Posting on handler so WM lock isn't held when we call into AM.
857         final Message m = PooledLambda.obtainMessage(
858                 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo,
859                 mListener, newState);
860         mAtm.mH.sendMessage(m);
861     }
862 
isRemoved()863     boolean isRemoved() {
864         return mListener == null ? false : mListener.isRemoved();
865     }
866 
shouldSetProfileProc()867     private boolean shouldSetProfileProc() {
868         return mAtm.mProfileApp != null && mAtm.mProfileApp.equals(mName)
869                 && (mAtm.mProfileProc == null || mAtm.mProfileProc == this);
870     }
871 
createProfilerInfoIfNeeded()872     ProfilerInfo createProfilerInfoIfNeeded() {
873         final ProfilerInfo currentProfilerInfo = mAtm.mProfilerInfo;
874         if (currentProfilerInfo == null || currentProfilerInfo.profileFile == null
875                 || !shouldSetProfileProc()) {
876             return null;
877         }
878         if (currentProfilerInfo.profileFd != null) {
879             try {
880                 currentProfilerInfo.profileFd = currentProfilerInfo.profileFd.dup();
881             } catch (IOException e) {
882                 currentProfilerInfo.closeFd();
883             }
884         }
885         return new ProfilerInfo(currentProfilerInfo);
886     }
887 
onStartActivity(int topProcessState, ActivityInfo info)888     void onStartActivity(int topProcessState, ActivityInfo info) {
889         if (mListener == null) return;
890         String packageName = null;
891         if ((info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
892                 || !"android".equals(info.packageName)) {
893             // Don't add this if it is a platform component that is marked to run in multiple
894             // processes, because this is actually part of the framework so doesn't make sense
895             // to track as a separate apk in the process.
896             packageName = info.packageName;
897         }
898         // Posting the message at the front of queue so WM lock isn't held when we call into AM,
899         // and the process state of starting activity can be updated quicker which will give it a
900         // higher scheduling group.
901         final Message m = PooledLambda.obtainMessage(WindowProcessListener::onStartActivity,
902                 mListener, topProcessState, shouldSetProfileProc(), packageName,
903                 info.applicationInfo.longVersionCode);
904         mAtm.mH.sendMessageAtFrontOfQueue(m);
905     }
906 
appDied()907     public void appDied() {
908         if (mListener == null) return;
909         // Posting on handler so WM lock isn't held when we call into AM.
910         final Message m = PooledLambda.obtainMessage(
911                 WindowProcessListener::appDied, mListener);
912         mAtm.mH.sendMessage(m);
913     }
914 
registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay)915     void registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay) {
916         if (activityDisplay == null) {
917             return;
918         }
919         // A process can only register to one display to listener to the override configuration
920         // change. Unregister existing listener if it has one before register the new one.
921         unregisterDisplayConfigurationListenerLocked();
922         mDisplayId = activityDisplay.mDisplayId;
923         activityDisplay.registerConfigurationChangeListener(this);
924     }
925 
926     @VisibleForTesting
unregisterDisplayConfigurationListenerLocked()927     void unregisterDisplayConfigurationListenerLocked() {
928         if (mDisplayId == INVALID_DISPLAY) {
929             return;
930         }
931         final ActivityDisplay activityDisplay =
932                 mAtm.mRootActivityContainer.getActivityDisplay(mDisplayId);
933         if (activityDisplay != null) {
934             activityDisplay.unregisterConfigurationChangeListener(this);
935         }
936         mDisplayId = INVALID_DISPLAY;
937     }
938 
939     @Override
onConfigurationChanged(Configuration newGlobalConfig)940     public void onConfigurationChanged(Configuration newGlobalConfig) {
941         super.onConfigurationChanged(newGlobalConfig);
942         updateConfiguration();
943     }
944 
945     @Override
onRequestedOverrideConfigurationChanged(Configuration newOverrideConfig)946     public void onRequestedOverrideConfigurationChanged(Configuration newOverrideConfig) {
947         super.onRequestedOverrideConfigurationChanged(newOverrideConfig);
948         updateConfiguration();
949     }
950 
updateConfiguration()951     private void updateConfiguration() {
952         final Configuration config = getConfiguration();
953         if (mLastReportedConfiguration.diff(config) == 0) {
954             // Nothing changed.
955             return;
956         }
957 
958         try {
959             if (mThread == null) {
960                 return;
961             }
962             if (DEBUG_CONFIGURATION) {
963                 Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName
964                         + " new config " + config);
965             }
966             config.seq = mAtm.increaseConfigurationSeqLocked();
967             mAtm.getLifecycleManager().scheduleTransaction(mThread,
968                     ConfigurationChangeItem.obtain(config));
969             setLastReportedConfiguration(config);
970         } catch (Exception e) {
971             Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
972         }
973     }
974 
setLastReportedConfiguration(Configuration config)975     private void setLastReportedConfiguration(Configuration config) {
976         mLastReportedConfiguration.setTo(config);
977     }
978 
getLastReportedConfiguration()979     Configuration getLastReportedConfiguration() {
980         return mLastReportedConfiguration;
981     }
982 
983     /** Returns the total time (in milliseconds) spent executing in both user and system code. */
getCpuTime()984     public long getCpuTime() {
985         return (mListener != null) ? mListener.getCpuTime() : 0;
986     }
987 
addRecentTask(TaskRecord task)988     void addRecentTask(TaskRecord task) {
989         mRecentTasks.add(task);
990     }
991 
removeRecentTask(TaskRecord task)992     void removeRecentTask(TaskRecord task) {
993         mRecentTasks.remove(task);
994     }
995 
996     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
hasRecentTasks()997     public boolean hasRecentTasks() {
998         synchronized (mAtm.mGlobalLockWithoutBoost) {
999             return !mRecentTasks.isEmpty();
1000         }
1001     }
1002 
clearRecentTasks()1003     void clearRecentTasks() {
1004         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1005             mRecentTasks.get(i).clearRootProcess();
1006         }
1007         mRecentTasks.clear();
1008     }
1009 
appEarlyNotResponding(String annotation, Runnable killAppCallback)1010     public void appEarlyNotResponding(String annotation, Runnable killAppCallback) {
1011         synchronized (mAtm.mGlobalLock) {
1012             if (mAtm.mController == null) {
1013                 return;
1014             }
1015 
1016             try {
1017                 // 0 == continue, -1 = kill process immediately
1018                 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation);
1019                 if (res < 0 && mPid != MY_PID) {
1020                     killAppCallback.run();
1021                 }
1022             } catch (RemoteException e) {
1023                 mAtm.mController = null;
1024                 Watchdog.getInstance().setActivityController(null);
1025             }
1026         }
1027     }
1028 
appNotResponding(String info, Runnable killAppCallback, Runnable serviceTimeoutCallback)1029     public boolean appNotResponding(String info, Runnable killAppCallback,
1030             Runnable serviceTimeoutCallback) {
1031         Runnable targetRunnable = null;
1032         synchronized (mAtm.mGlobalLock) {
1033             if (mAtm.mController == null) {
1034                 return false;
1035             }
1036 
1037             try {
1038                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
1039                 int res = mAtm.mController.appNotResponding(mName, mPid, info);
1040                 if (res != 0) {
1041                     if (res < 0 && mPid != MY_PID) {
1042                         targetRunnable = killAppCallback;
1043                     } else {
1044                         targetRunnable = serviceTimeoutCallback;
1045                     }
1046                 }
1047             } catch (RemoteException e) {
1048                 mAtm.mController = null;
1049                 Watchdog.getInstance().setActivityController(null);
1050                 return false;
1051             }
1052         }
1053         if (targetRunnable != null) {
1054             targetRunnable.run();
1055             return true;
1056         }
1057         return false;
1058     }
1059 
1060     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
onTopProcChanged()1061     public void onTopProcChanged() {
1062         synchronized (mAtm.mGlobalLockWithoutBoost) {
1063             mAtm.mVrController.onTopProcChangedLocked(this);
1064         }
1065     }
1066 
1067     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
isHomeProcess()1068     public boolean isHomeProcess() {
1069         synchronized (mAtm.mGlobalLockWithoutBoost) {
1070             return this == mAtm.mHomeProcess;
1071         }
1072     }
1073 
1074     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
isPreviousProcess()1075     public boolean isPreviousProcess() {
1076         synchronized (mAtm.mGlobalLockWithoutBoost) {
1077             return this == mAtm.mPreviousProcess;
1078         }
1079     }
1080 
setRunningRecentsAnimation(boolean running)1081     void setRunningRecentsAnimation(boolean running) {
1082         if (mRunningRecentsAnimation == running) {
1083             return;
1084         }
1085         mRunningRecentsAnimation = running;
1086         updateRunningRemoteOrRecentsAnimation();
1087     }
1088 
setRunningRemoteAnimation(boolean running)1089     void setRunningRemoteAnimation(boolean running) {
1090         if (mRunningRemoteAnimation == running) {
1091             return;
1092         }
1093         mRunningRemoteAnimation = running;
1094         updateRunningRemoteOrRecentsAnimation();
1095     }
1096 
updateRunningRemoteOrRecentsAnimation()1097     private void updateRunningRemoteOrRecentsAnimation() {
1098 
1099         // Posting on handler so WM lock isn't held when we call into AM.
1100         mAtm.mH.sendMessage(PooledLambda.obtainMessage(
1101                 WindowProcessListener::setRunningRemoteAnimation, mListener,
1102                 mRunningRecentsAnimation || mRunningRemoteAnimation));
1103     }
1104 
1105     @Override
toString()1106     public String toString() {
1107         return mOwner != null ? mOwner.toString() : null;
1108     }
1109 
dump(PrintWriter pw, String prefix)1110     public void dump(PrintWriter pw, String prefix) {
1111         synchronized (mAtm.mGlobalLock) {
1112             if (mActivities.size() > 0) {
1113                 pw.print(prefix); pw.println("Activities:");
1114                 for (int i = 0; i < mActivities.size(); i++) {
1115                     pw.print(prefix); pw.print("  - "); pw.println(mActivities.get(i));
1116                 }
1117             }
1118 
1119             if (mRecentTasks.size() > 0) {
1120                 pw.println(prefix + "Recent Tasks:");
1121                 for (int i = 0; i < mRecentTasks.size(); i++) {
1122                     pw.println(prefix + "  - " + mRecentTasks.get(i));
1123                 }
1124             }
1125 
1126             if (mVrThreadTid != 0) {
1127                 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid);
1128             }
1129         }
1130         pw.println(prefix + " Configuration=" + getConfiguration());
1131         pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
1132         pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
1133     }
1134 
writeToProto(ProtoOutputStream proto, long fieldId)1135     void writeToProto(ProtoOutputStream proto, long fieldId) {
1136         if (mListener != null) {
1137             mListener.writeToProto(proto, fieldId);
1138         }
1139     }
1140 }
1141