blob: bb1725477ac0403877e34d3b933f479db6e4a2e1 [file] [log] [blame]
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -07001/*
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
Wale Ogunwale59507092018-10-29 09:00:30 -070017package com.android.server.wm;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070018
19import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
Yunfan Chen79b96062018-10-17 12:45:23 -070020import static android.view.Display.INVALID_DISPLAY;
Yunfan Chen75157d72018-07-27 14:47:21 +090021
Wale Ogunwalee2172292018-10-25 10:11:10 -070022import static com.android.server.am.ActivityManagerService.MY_PID;
Wale Ogunwale59507092018-10-29 09:00:30 -070023import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
24import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
25import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
26import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
27import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
28import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
29import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
30import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
31import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
32import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
33import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
34import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
35import static com.android.server.wm.ActivityTaskManagerService
Yunfan Chen79b96062018-10-17 12:45:23 -070036 .INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
Wale Ogunwale59507092018-10-29 09:00:30 -070037import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
38import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070039
40import android.app.Activity;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070041import android.app.ActivityThread;
42import android.app.IApplicationThread;
Wale Ogunwale9c103022018-10-18 07:44:54 -070043import android.app.ProfilerInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +090044import android.app.servertransaction.ConfigurationChangeItem;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070045import android.content.Intent;
46import android.content.pm.ApplicationInfo;
Yunfan Chen75157d72018-07-27 14:47:21 +090047import android.content.res.Configuration;
Yohei Yukawae2fa39e2018-09-22 13:13:10 -070048import android.os.Message;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070049import android.os.RemoteException;
50import android.util.ArraySet;
51import android.util.Log;
52import android.util.Slog;
Wale Ogunwale51cc98a2018-10-15 10:41:05 -070053import android.util.proto.ProtoOutputStream;
Yunfan Chen79b96062018-10-17 12:45:23 -070054
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070055import com.android.internal.app.HeavyWeightSwitcherActivity;
56import com.android.internal.util.function.pooled.PooledLambda;
Wale Ogunwalee2172292018-10-25 10:11:10 -070057import com.android.server.Watchdog;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070058
59import java.io.PrintWriter;
60import java.util.ArrayList;
61
62/**
63 * The Activity Manager (AM) package manages the lifecycle of processes in the system through
Wale Ogunwale59507092018-10-29 09:00:30 -070064 * ProcessRecord. However, it is important for the Window Manager (WM) package to be aware
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070065 * of the processes and their state since it affects how WM manages windows and activities. This
Wale Ogunwale59507092018-10-29 09:00:30 -070066 * class that allows the ProcessRecord object in the AM package to communicate important
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070067 * changes to its state to the WM package in a structured way. WM package also uses
68 * {@link WindowProcessListener} to request changes to the process state on the AM side.
69 * Note that public calls into this class are assumed to be originating from outside the
70 * window manager so the window manager lock is held and appropriate permissions are checked before
71 * calls are allowed to proceed.
72 */
Yunfan Chen79b96062018-10-17 12:45:23 -070073public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
74 implements ConfigurationContainerListener {
Wale Ogunwale98875612018-10-12 07:53:02 -070075 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070076 private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
Yunfan Chen75157d72018-07-27 14:47:21 +090077 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -070078
79 // all about the first app in the process
80 final ApplicationInfo mInfo;
81 final String mName;
82 final int mUid;
83 // The process of this application; 0 if none
84 private volatile int mPid;
85 // user of process.
86 final int mUserId;
87 // The owner of this window process controller object. Mainly for identification when we
88 // communicate back to the activity manager side.
89 public final Object mOwner;
90 // List of packages running in the process
91 final ArraySet<String> mPkgList = new ArraySet<>();
92 private final WindowProcessListener mListener;
93 private final ActivityTaskManagerService mAtm;
94 // The actual proc... may be null only if 'persistent' is true (in which case we are in the
95 // process of launching the app)
96 private volatile IApplicationThread mThread;
97 // Currently desired scheduling class
98 private volatile int mCurSchedGroup;
Wale Ogunwale342fbe92018-10-09 08:44:10 -070099 // Currently computed process state
100 private volatile int mCurProcState = PROCESS_STATE_NONEXISTENT;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700101 // Last reported process state;
102 private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT;
103 // are we in the process of crashing?
104 private volatile boolean mCrashing;
105 // does the app have a not responding dialog?
106 private volatile boolean mNotResponding;
107 // always keep this application running?
108 private volatile boolean mPersistent;
109 // The ABI this process was launched with
110 private volatile String mRequiredAbi;
111 // Running any services that are foreground?
112 private volatile boolean mHasForegroundServices;
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700113 // Running any activities that are foreground?
114 private volatile boolean mHasForegroundActivities;
115 // Are there any client services with activities?
116 private volatile boolean mHasClientActivities;
117 // Is this process currently showing a non-activity UI that the user is interacting with?
118 // E.g. The status bar when it is expanded, but not when it is minimized. When true the process
119 // will be set to use the ProcessList#SCHED_GROUP_TOP_APP scheduling group to boost performance.
120 private volatile boolean mHasTopUi;
121 // Is the process currently showing a non-activity UI that overlays on-top of activity UIs on
122 // screen. E.g. display a window of type
123 // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY When true the process will
124 // oom adj score will be set to ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
125 // of the process getting killed.
126 private volatile boolean mHasOverlayUi;
127 // Want to clean up resources from showing UI?
128 private volatile boolean mPendingUiClean;
129 // The time we sent the last interaction event
130 private volatile long mInteractionEventTime;
131 // When we became foreground for interaction purposes
132 private volatile long mFgInteractionTime;
133 // When (uptime) the process last became unimportant
134 private volatile long mWhenUnimportant;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700135 // was app launched for debugging?
136 private volatile boolean mDebugging;
137 // Active instrumentation running in process?
138 private volatile boolean mInstrumenting;
Wale Ogunwale31913b52018-10-13 08:29:31 -0700139 // This process it perceptible by the user.
140 private volatile boolean mPerceptible;
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700141 // Set to true when process was launched with a wrapper attached
142 private volatile boolean mUsingWrapper;
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700143
144 // Thread currently set for VR scheduling
145 int mVrThreadTid;
146
147 // all activities running in the process
148 private final ArrayList<ActivityRecord> mActivities = new ArrayList<>();
149 // any tasks this process had run root activities in
150 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>();
151
Yunfan Chen75157d72018-07-27 14:47:21 +0900152 // Last configuration that was reported to the process.
153 private final Configuration mLastReportedConfiguration;
Yunfan Chen79b96062018-10-17 12:45:23 -0700154 // Registered display id as a listener to override config change
155 private int mDisplayId;
Yunfan Chen75157d72018-07-27 14:47:21 +0900156
Wale Ogunwale59507092018-10-29 09:00:30 -0700157 public WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info,
158 String name, int uid, int userId, Object owner, WindowProcessListener listener) {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700159 mInfo = info;
160 mName = name;
161 mUid = uid;
162 mUserId = userId;
163 mOwner = owner;
164 mListener = listener;
165 mAtm = atm;
Yunfan Chen75157d72018-07-27 14:47:21 +0900166 mLastReportedConfiguration = new Configuration();
Yunfan Chen79b96062018-10-17 12:45:23 -0700167 mDisplayId = INVALID_DISPLAY;
Wale Ogunwale387b34c2018-10-25 19:59:40 -0700168 if (atm != null) {
169 onConfigurationChanged(atm.getGlobalConfiguration());
Yunfan Chen75157d72018-07-27 14:47:21 +0900170 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700171 }
172
173 public void setPid(int pid) {
174 mPid = pid;
175 }
176
Wale Ogunwale59507092018-10-29 09:00:30 -0700177 public int getPid() {
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700178 return mPid;
179 }
180
181 public void setThread(IApplicationThread thread) {
182 mThread = thread;
183 }
184
185 IApplicationThread getThread() {
186 return mThread;
187 }
188
189 boolean hasThread() {
190 return mThread != null;
191 }
192
193 public void setCurrentSchedulingGroup(int curSchedGroup) {
194 mCurSchedGroup = curSchedGroup;
195 }
196
197 int getCurrentSchedulingGroup() {
198 return mCurSchedGroup;
199 }
200
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700201 public void setCurrentProcState(int curProcState) {
202 mCurProcState = curProcState;
203 }
204
205 int getCurrentProcState() {
206 return mCurProcState;
207 }
208
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700209 public void setReportedProcState(int repProcState) {
210 mRepProcState = repProcState;
211 }
212
213 int getReportedProcState() {
214 return mRepProcState;
215 }
216
217 public void setCrashing(boolean crashing) {
218 mCrashing = crashing;
219 }
220
221 boolean isCrashing() {
222 return mCrashing;
223 }
224
225 public void setNotResponding(boolean notResponding) {
226 mNotResponding = notResponding;
227 }
228
229 boolean isNotResponding() {
230 return mNotResponding;
231 }
232
233 public void setPersistent(boolean persistent) {
234 mPersistent = persistent;
235 }
236
237 boolean isPersistent() {
238 return mPersistent;
239 }
240
241 public void setHasForegroundServices(boolean hasForegroundServices) {
242 mHasForegroundServices = hasForegroundServices;
243 }
244
245 boolean hasForegroundServices() {
246 return mHasForegroundServices;
247 }
248
Wale Ogunwale342fbe92018-10-09 08:44:10 -0700249 public void setHasForegroundActivities(boolean hasForegroundActivities) {
250 mHasForegroundActivities = hasForegroundActivities;
251 }
252
253 boolean hasForegroundActivities() {
254 return mHasForegroundActivities;
255 }
256
257 public void setHasClientActivities(boolean hasClientActivities) {
258 mHasClientActivities = hasClientActivities;
259 }
260
261 boolean hasClientActivities() {
262 return mHasClientActivities;
263 }
264
265 public void setHasTopUi(boolean hasTopUi) {
266 mHasTopUi = hasTopUi;
267 }
268
269 boolean hasTopUi() {
270 return mHasTopUi;
271 }
272
273 public void setHasOverlayUi(boolean hasOverlayUi) {
274 mHasOverlayUi = hasOverlayUi;
275 }
276
277 boolean hasOverlayUi() {
278 return mHasOverlayUi;
279 }
280
281 public void setPendingUiClean(boolean hasPendingUiClean) {
282 mPendingUiClean = hasPendingUiClean;
283 }
284
285 boolean hasPendingUiClean() {
286 return mPendingUiClean;
287 }
288
289 void postPendingUiCleanMsg(boolean pendingUiClean) {
290 if (mListener == null) return;
291 // Posting on handler so WM lock isn't held when we call into AM.
292 final Message m = PooledLambda.obtainMessage(
293 WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
294 mAtm.mH.sendMessage(m);
295 }
296
297 public void setInteractionEventTime(long interactionEventTime) {
298 mInteractionEventTime = interactionEventTime;
299 }
300
301 long getInteractionEventTime() {
302 return mInteractionEventTime;
303 }
304
305 public void setFgInteractionTime(long fgInteractionTime) {
306 mFgInteractionTime = fgInteractionTime;
307 }
308
309 long getFgInteractionTime() {
310 return mFgInteractionTime;
311 }
312
313 public void setWhenUnimportant(long whenUnimportant) {
314 mWhenUnimportant = whenUnimportant;
315 }
316
317 long getWhenUnimportant() {
318 return mWhenUnimportant;
319 }
320
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700321 public void setRequiredAbi(String requiredAbi) {
322 mRequiredAbi = requiredAbi;
323 }
324
325 String getRequiredAbi() {
326 return mRequiredAbi;
327 }
328
Wale Ogunwale906f9c62018-07-23 11:23:44 -0700329 public void setDebugging(boolean debugging) {
330 mDebugging = debugging;
331 }
332
333 boolean isDebugging() {
334 return mDebugging;
335 }
336
337 public void setUsingWrapper(boolean usingWrapper) {
338 mUsingWrapper = usingWrapper;
339 }
340
341 boolean isUsingWrapper() {
342 return mUsingWrapper;
343 }
344
345 public void setInstrumenting(boolean instrumenting) {
346 mInstrumenting = instrumenting;
347 }
348
349 boolean isInstrumenting() {
350 return mInstrumenting;
351 }
352
Wale Ogunwale31913b52018-10-13 08:29:31 -0700353 public void setPerceptible(boolean perceptible) {
354 mPerceptible = perceptible;
355 }
356
357 boolean isPerceptible() {
358 return mPerceptible;
359 }
360
Yunfan Chen75157d72018-07-27 14:47:21 +0900361 @Override
362 protected int getChildCount() {
363 return 0;
364 }
365
366 @Override
367 protected ConfigurationContainer getChildAt(int index) {
368 return null;
369 }
370
371 @Override
372 protected ConfigurationContainer getParent() {
373 return null;
374 }
375
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700376 public void addPackage(String packageName) {
377 synchronized (mAtm.mGlobalLock) {
378 mPkgList.add(packageName);
379 }
380 }
381
382 public void clearPackageList() {
383 synchronized (mAtm.mGlobalLock) {
384 mPkgList.clear();
385 }
386 }
387
388 void addActivityIfNeeded(ActivityRecord r) {
389 if (mActivities.contains(r)) {
390 return;
391 }
392 mActivities.add(r);
393 }
394
395 void removeActivity(ActivityRecord r) {
396 mActivities.remove(r);
397 }
398
399 public void clearActivities() {
400 synchronized (mAtm.mGlobalLock) {
401 mActivities.clear();
402 }
403 }
404
405 public boolean hasActivities() {
406 synchronized (mAtm.mGlobalLock) {
407 return !mActivities.isEmpty();
408 }
409 }
410
411 public boolean hasVisibleActivities() {
412 synchronized (mAtm.mGlobalLock) {
413 for (int i = mActivities.size() - 1; i >= 0; --i) {
414 final ActivityRecord r = mActivities.get(i);
415 if (r.visible) {
416 return true;
417 }
418 }
419 }
420 return false;
421 }
422
423 public boolean hasActivitiesOrRecentTasks() {
424 synchronized (mAtm.mGlobalLock) {
425 return !mActivities.isEmpty() || !mRecentTasks.isEmpty();
426 }
427 }
428
429 public void stopFreezingActivities() {
430 synchronized (mAtm.mGlobalLock) {
431 int i = mActivities.size();
432 while (i > 0) {
433 i--;
434 mActivities.get(i).stopFreezingScreenLocked(true);
435 }
436 }
437 }
438
439 public void finishActivities() {
440 synchronized (mAtm.mGlobalLock) {
441 ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities);
442 for (int i = 0; i < activities.size(); i++) {
443 final ActivityRecord r = activities.get(i);
444 if (!r.finishing && r.isInStackLocked()) {
445 r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
446 null, "finish-heavy", true);
447 }
448 }
449 }
450 }
451
452 public boolean isInterestingToUser() {
453 synchronized (mAtm.mGlobalLock) {
454 final int size = mActivities.size();
455 for (int i = 0; i < size; i++) {
456 ActivityRecord r = mActivities.get(i);
457 if (r.isInterestingToUserLocked()) {
458 return true;
459 }
460 }
461 }
462 return false;
463 }
464
465 public boolean hasRunningActivity(String packageName) {
466 synchronized (mAtm.mGlobalLock) {
467 for (int i = mActivities.size() - 1; i >= 0; --i) {
468 final ActivityRecord r = mActivities.get(i);
469 if (packageName.equals(r.packageName)) {
470 return true;
471 }
472 }
473 }
474 return false;
475 }
476
477 public void clearPackagePreferredForHomeActivities() {
478 synchronized (mAtm.mGlobalLock) {
479 for (int i = mActivities.size() - 1; i >= 0; --i) {
480 final ActivityRecord r = mActivities.get(i);
481 if (r.isActivityTypeHome()) {
482 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
483 try {
484 ActivityThread.getPackageManager()
485 .clearPackagePreferredActivities(r.packageName);
486 } catch (RemoteException c) {
487 // pm is in same process, this will never happen.
488 }
489 }
490 }
491 }
492 }
493
494 boolean hasStartedActivity(ActivityRecord launchedActivity) {
495 for (int i = mActivities.size() - 1; i >= 0; i--) {
496 final ActivityRecord activity = mActivities.get(i);
497 if (launchedActivity == activity) {
498 continue;
499 }
500 if (!activity.stopped) {
501 return true;
502 }
503 }
504 return false;
505 }
506
507
508 public void updateIntentForHeavyWeightActivity(Intent intent) {
509 synchronized (mAtm.mGlobalLock) {
510 if (mActivities.isEmpty()) {
511 return;
512 }
513 ActivityRecord hist = mActivities.get(0);
514 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
515 intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTask().taskId);
516 }
517 }
518
519 boolean shouldKillProcessForRemovedTask(TaskRecord tr) {
520 for (int k = 0; k < mActivities.size(); k++) {
Yunfan Chenafc15832018-07-26 16:34:28 +0900521 final ActivityRecord activity = mActivities.get(k);
522 if (!activity.stopped) {
523 // Don't kill process(es) that has an activity not stopped.
524 return false;
525 }
526 final TaskRecord otherTask = activity.getTask();
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700527 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
528 // Don't kill process(es) that has an activity in a different task that is
529 // also in recents.
530 return false;
531 }
532 }
533 return true;
534 }
535
536 ArraySet<TaskRecord> getReleaseSomeActivitiesTasks() {
537 // Examine all activities currently running in the process.
538 TaskRecord firstTask = null;
539 // Tasks is non-null only if two or more tasks are found.
540 ArraySet<TaskRecord> tasks = null;
541 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this);
542 for (int i = 0; i < mActivities.size(); i++) {
543 final ActivityRecord r = mActivities.get(i);
544 // First, if we find an activity that is in the process of being destroyed,
545 // then we just aren't going to do anything for now; we want things to settle
546 // down before we try to prune more activities.
547 if (r.finishing || r.isState(DESTROYING, DESTROYED)) {
548 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r);
549 return null;
550 }
551 // Don't consider any activies that are currently not in a state where they
552 // can be destroyed.
553 if (r.visible || !r.stopped || !r.haveState
554 || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) {
555 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r);
556 continue;
557 }
558
559 final TaskRecord task = r.getTask();
560 if (task != null) {
561 if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task
562 + " from " + r);
563 if (firstTask == null) {
564 firstTask = task;
565 } else if (firstTask != task) {
566 if (tasks == null) {
567 tasks = new ArraySet<>();
568 tasks.add(firstTask);
569 }
570 tasks.add(task);
571 }
572 }
573 }
574
575 return tasks;
576 }
577
578 public interface ComputeOomAdjCallback {
579 void onVisibleActivity();
580 void onPausedActivity();
581 void onStoppingActivity(boolean finishing);
582 void onOtherActivity();
583 }
584
585 public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) {
586 synchronized (mAtm.mGlobalLock) {
587 final int activitiesSize = mActivities.size();
588 for (int j = 0; j < activitiesSize; j++) {
589 final ActivityRecord r = mActivities.get(j);
590 if (r.app != this) {
591 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
592 + " instead of expected " + this);
593 if (r.app == null || (r.app.mUid == mUid)) {
594 // Only fix things up when they look sane
595 r.setProcess(this);
596 } else {
597 continue;
598 }
599 }
600 if (r.visible) {
601 callback.onVisibleActivity();
602 final TaskRecord task = r.getTask();
603 if (task != null && minTaskLayer > 0) {
604 final int layer = task.mLayerRank;
605 if (layer >= 0 && minTaskLayer > layer) {
606 minTaskLayer = layer;
607 }
608 }
609 break;
610 } else if (r.isState(PAUSING, PAUSED)) {
611 callback.onPausedActivity();
612 } else if (r.isState(STOPPING)) {
613 callback.onStoppingActivity(r.finishing);
614 } else {
615 callback.onOtherActivity();
616 }
617 }
618 }
619
620 return minTaskLayer;
621 }
622
Wale Ogunwale59507092018-10-29 09:00:30 -0700623 public int computeRelaunchReason() {
Garfield Tan2746ab52018-07-25 12:33:01 -0700624 synchronized (mAtm.mGlobalLock) {
625 final int activitiesSize = mActivities.size();
626 for (int i = activitiesSize - 1; i >= 0; i--) {
627 final ActivityRecord r = mActivities.get(i);
Wale Ogunwale64258362018-10-16 15:13:37 -0700628 if (r.mRelaunchReason != RELAUNCH_REASON_NONE) {
Garfield Tan2746ab52018-07-25 12:33:01 -0700629 return r.mRelaunchReason;
630 }
631 }
632 }
Wale Ogunwale64258362018-10-16 15:13:37 -0700633 return RELAUNCH_REASON_NONE;
Garfield Tan2746ab52018-07-25 12:33:01 -0700634 }
635
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700636 public long getInputDispatchingTimeout() {
637 synchronized (mAtm.mGlobalLock) {
638 return isInstrumenting() || isUsingWrapper()
639 ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS;
640 }
641 }
642
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700643 void clearProfilerIfNeeded() {
644 if (mListener == null) return;
645 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700646 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
647 WindowProcessListener::clearProfilerIfNeeded, mListener));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700648 }
649
650 void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru,
651 boolean activityChange, boolean updateOomAdj) {
652 if (mListener == null) return;
653 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700654 final Message m = PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700655 mListener, updateServiceConnectionActivities, updateLru, activityChange,
656 updateOomAdj);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700657 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700658 }
659
660 void updateServiceConnectionActivities() {
661 if (mListener == null) return;
662 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700663 mAtm.mH.sendMessage(PooledLambda.obtainMessage(
664 WindowProcessListener::updateServiceConnectionActivities, mListener));
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700665 }
666
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700667 void setPendingUiCleanAndForceProcessStateUpTo(int newState) {
668 if (mListener == null) return;
669 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700670 final Message m = PooledLambda.obtainMessage(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700671 WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo,
672 mListener, newState);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700673 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700674 }
675
676 void setRemoved(boolean removed) {
677 if (mListener == null) return;
678 // Posting on handler so WM lock isn't held when we call into AM.
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700679 final Message m = PooledLambda.obtainMessage(
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700680 WindowProcessListener::setRemoved, mListener, removed);
Yohei Yukawae2fa39e2018-09-22 13:13:10 -0700681 mAtm.mH.sendMessage(m);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700682 }
683
Wale Ogunwale9c103022018-10-18 07:44:54 -0700684 void clearWaitingToKill() {
685 if (mListener == null) return;
686 // Posting on handler so WM lock isn't held when we call into AM.
687 final Message m = PooledLambda.obtainMessage(
688 WindowProcessListener::clearWaitingToKill, mListener);
689 mAtm.mH.sendMessage(m);
690 }
691
692 void addPackage(String pkg, long versionCode) {
693 // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
694 // using WM lock. Need to figure-out if it is okay to do this asynchronously.
695 if (mListener == null) return;
696 mListener.addPackage(pkg, versionCode);
697 }
698
699 ProfilerInfo onStartActivity(int topProcessState) {
700 // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
701 // using WM lock. Need to figure-out if it is okay to do this asynchronously.
702 if (mListener == null) return null;
703 return mListener.onStartActivity(topProcessState);
704 }
705
706 public void appDied() {
707 // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
708 // using WM lock. Need to figure-out if it is okay to do this asynchronously.
709 if (mListener == null) return;
710 mListener.appDied();
711 }
712
Yunfan Chen79b96062018-10-17 12:45:23 -0700713 void registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay) {
714 if (activityDisplay == null) {
715 return;
716 }
717 // A process can only register to one display to listener to the override configuration
718 // change. Unregister existing listener if it has one before register the new one.
719 unregisterDisplayConfigurationListenerLocked();
720 mDisplayId = activityDisplay.mDisplayId;
721 activityDisplay.registerConfigurationChangeListener(this);
722 }
723
724 private void unregisterDisplayConfigurationListenerLocked() {
725 if (mDisplayId == INVALID_DISPLAY) {
726 return;
727 }
728 final ActivityDisplay activityDisplay =
729 mAtm.mStackSupervisor.getActivityDisplay(mDisplayId);
730 if (activityDisplay != null) {
731 mAtm.mStackSupervisor.getActivityDisplay(
732 mDisplayId).unregisterConfigurationChangeListener(this);
733 }
734 mDisplayId = INVALID_DISPLAY;
735 }
736
Yunfan Chen75157d72018-07-27 14:47:21 +0900737 @Override
738 public void onConfigurationChanged(Configuration newGlobalConfig) {
739 super.onConfigurationChanged(newGlobalConfig);
740 updateConfiguration();
741 }
742
743 @Override
744 public void onOverrideConfigurationChanged(Configuration newOverrideConfig) {
745 super.onOverrideConfigurationChanged(newOverrideConfig);
746 updateConfiguration();
747 }
748
749 private void updateConfiguration() {
750 final Configuration config = getConfiguration();
751 if (mLastReportedConfiguration.diff(config) == 0) {
752 // Nothing changed.
753 return;
754 }
755
756 try {
757 if (mThread == null) {
758 return;
759 }
760 if (DEBUG_CONFIGURATION) {
761 Slog.v(TAG_CONFIGURATION, "Sending to proc " + mName
762 + " new config " + config);
763 }
764 config.seq = mAtm.increaseConfigurationSeqLocked();
765 mAtm.getLifecycleManager().scheduleTransaction(mThread,
766 ConfigurationChangeItem.obtain(config));
767 setLastReportedConfiguration(config);
768 } catch (Exception e) {
769 Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
770 }
771 }
772
773 private void setLastReportedConfiguration(Configuration config) {
774 mLastReportedConfiguration.setTo(config);
775 }
776
777 Configuration getLastReportedConfiguration() {
778 return mLastReportedConfiguration;
779 }
780
Wale Ogunwale86b74462018-07-02 08:42:43 -0700781 /** Returns the total time (in milliseconds) spent executing in both user and system code. */
782 public long getCpuTime() {
783 return (mListener != null) ? mListener.getCpuTime() : 0;
784 }
785
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700786 void addRecentTask(TaskRecord task) {
787 mRecentTasks.add(task);
788 }
789
790 void removeRecentTask(TaskRecord task) {
791 mRecentTasks.remove(task);
792 }
793
794 public boolean hasRecentTasks() {
795 synchronized (mAtm.mGlobalLock) {
796 return !mRecentTasks.isEmpty();
797 }
798 }
799
800 public void clearRecentTasks() {
801 synchronized (mAtm.mGlobalLock) {
802 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
803 mRecentTasks.get(i).clearRootProcess();
804 }
805 mRecentTasks.clear();
806 }
807 }
808
Wale Ogunwalee2172292018-10-25 10:11:10 -0700809 public void appEarlyNotResponding(String annotation, Runnable killAppCallback) {
810 synchronized (mAtm.mGlobalLock) {
811 if (mAtm.mController == null) {
812 return;
813 }
814
815 try {
816 // 0 == continue, -1 = kill process immediately
817 int res = mAtm.mController.appEarlyNotResponding(mName, mPid, annotation);
818 if (res < 0 && mPid != MY_PID) {
819 killAppCallback.run();
820 }
821 } catch (RemoteException e) {
822 mAtm.mController = null;
823 Watchdog.getInstance().setActivityController(null);
824 }
825 }
826 }
827
828 public boolean appNotResponding(String info, Runnable killAppCallback,
829 Runnable serviceTimeoutCallback) {
830 synchronized (mAtm.mGlobalLock) {
831 if (mAtm.mController == null) {
832 return false;
833 }
834
835 try {
836 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
837 int res = mAtm.mController.appNotResponding(mName, mPid, info);
838 if (res != 0) {
839 if (res < 0 && mPid != MY_PID) {
840 killAppCallback.run();
841 } else {
842 serviceTimeoutCallback.run();
843 }
844 return true;
845 }
846 } catch (RemoteException e) {
847 mAtm.mController = null;
848 Watchdog.getInstance().setActivityController(null);
849 }
850 return false;
851 }
852 }
853
854 public void onTopProcChanged() {
855 synchronized (mAtm.mGlobalLock) {
856 mAtm.mVrController.onTopProcChangedLocked(this);
857 }
858 }
859
Wale Ogunwaled4d67d02018-10-25 18:09:39 -0700860 public boolean isHomeProcess() {
861 synchronized (mAtm.mGlobalLock) {
862 return this == mAtm.mHomeProcess;
863 }
864 }
865
866 public boolean isPreviousProcess() {
867 synchronized (mAtm.mGlobalLock) {
868 return this == mAtm.mPreviousProcess;
869 }
870 }
871
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700872 public void dump(PrintWriter pw, String prefix) {
873 synchronized (mAtm.mGlobalLock) {
874 if (mActivities.size() > 0) {
875 pw.print(prefix); pw.println("Activities:");
876 for (int i = 0; i < mActivities.size(); i++) {
877 pw.print(prefix); pw.print(" - "); pw.println(mActivities.get(i));
878 }
879 }
880
881 if (mRecentTasks.size() > 0) {
882 pw.println(prefix + "Recent Tasks:");
883 for (int i = 0; i < mRecentTasks.size(); i++) {
884 pw.println(prefix + " - " + mRecentTasks.get(i));
885 }
886 }
887
888 if (mVrThreadTid != 0) {
889 pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid);
890 }
891 }
Yunfan Chen75157d72018-07-27 14:47:21 +0900892 pw.println(prefix + " Configuration=" + getConfiguration());
893 pw.println(prefix + " OverrideConfiguration=" + getOverrideConfiguration());
894 pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700895 }
896
Wale Ogunwale51cc98a2018-10-15 10:41:05 -0700897 void writeToProto(ProtoOutputStream proto, long fieldId) {
898 if (mListener != null) {
899 mListener.writeToProto(proto, fieldId);
900 }
901 }
Wale Ogunwale9e4f3e02018-05-17 09:35:39 -0700902}