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