Skip to content

Commit 5068560

Browse files
author
Dianne Hackborn
committed
Improve how we manage the previous app.
Setting it when a new activity is being resumed is too soon, because things like an activity launching an exiting (without being seen by the user) can knock out the real previous app that we want. So now we set it when an activity is stopped. At this point it is going to move from the preceptible to background oom adj, so it is a good point to determine whether it should be a previous app to instead put it to that oom adj. This also avoids things like activities that start and immediately finish from impacting the previous app. Further, we keep track of the time each activity was last shown, and use this to further filter what is set as the previous app. Change-Id: I72d1cac4de0cc2d4598170296028f11b06918d4f
1 parent a124018 commit 5068560

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,12 @@ abstract class ForegroundToken implements IBinder.DeathRecipient {
414414
* is in a different process from the one they are currently in.
415415
*/
416416
ProcessRecord mPreviousProcess;
417-
417+
418+
/**
419+
* The time at which the previous process was last visible.
420+
*/
421+
long mPreviousProcessVisibleTime;
422+
418423
/**
419424
* Packages that the user has asked to have run in screen size
420425
* compatibility mode instead of filling the screen.
@@ -8361,6 +8366,12 @@ boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
83618366
pw.println();
83628367
pw.println(" mHomeProcess: " + mHomeProcess);
83638368
pw.println(" mPreviousProcess: " + mPreviousProcess);
8369+
if (dumpAll) {
8370+
StringBuilder sb = new StringBuilder(128);
8371+
sb.append(" mPreviousProcessVisibleTime: ");
8372+
TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
8373+
pw.println(sb);
8374+
}
83648375
if (mHeavyWeightProcess != null) {
83658376
pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
83668377
}

services/java/com/android/server/am/ActivityRecord.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ final class ActivityRecord {
8080
ThumbnailHolder thumbHolder; // where our thumbnails should go.
8181
long launchTime; // when we starting launching this activity
8282
long startTime; // last time this activity was started
83+
long lastVisibleTime; // last time this activity became visible
8384
long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
8485
Configuration configuration; // configuration activity was last running in
8586
CompatibilityInfo compat;// last used compatibility mode
@@ -188,6 +189,10 @@ void dump(PrintWriter pw, String prefix) {
188189
TimeUtils.formatDuration(launchTime, pw); pw.print(" startTime=");
189190
TimeUtils.formatDuration(startTime, pw); pw.println("");
190191
}
192+
if (lastVisibleTime != 0) {
193+
pw.print(prefix); pw.print("lastVisibleTime=");
194+
TimeUtils.formatDuration(lastVisibleTime, pw); pw.println("");
195+
}
191196
if (waitingVisible || nowVisible) {
192197
pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
193198
pw.print(" nowVisible="); pw.println(nowVisible);
@@ -632,6 +637,7 @@ public void windowsVisible() {
632637
ActivityManagerService.TAG, "windowsVisible(): " + this);
633638
if (!nowVisible) {
634639
nowVisible = true;
640+
lastVisibleTime = SystemClock.uptimeMillis();
635641
if (!idle) {
636642
// Instead of doing the full stop routine here, let's just
637643
// hide any activities we now can, and let them stop when

services/java/com/android/server/am/ActivityStack.java

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,22 @@ final void activityStoppedLocked(ActivityRecord r, Bundle icicle, Bitmap thumbna
949949
if (r.configDestroy) {
950950
destroyActivityLocked(r, true, false, "stop-config");
951951
resumeTopActivityLocked(null);
952+
} else {
953+
// Now that this process has stopped, we may want to consider
954+
// it to be the previous app to try to keep around in case
955+
// the user wants to return to it.
956+
ProcessRecord fgApp = null;
957+
if (mResumedActivity != null) {
958+
fgApp = mResumedActivity.app;
959+
} else if (mPausingActivity != null) {
960+
fgApp = mPausingActivity.app;
961+
}
962+
if (r.app != null && fgApp != null && r.app != fgApp
963+
&& r.lastVisibleTime > mService.mPreviousProcessVisibleTime
964+
&& r.app != mService.mHomeProcess) {
965+
mService.mPreviousProcess = r.app;
966+
mService.mPreviousProcessVisibleTime = r.lastVisibleTime;
967+
}
952968
}
953969
}
954970
}
@@ -1363,14 +1379,6 @@ final boolean resumeTopActivityLocked(ActivityRecord prev) {
13631379
+ ", nowVisible=" + next.nowVisible);
13641380
}
13651381
}
1366-
1367-
if (!prev.finishing && prev.app != null && prev.app != next.app
1368-
&& prev.app != mService.mHomeProcess) {
1369-
// We are switching to a new activity that is in a different
1370-
// process than the previous one. Note the previous process,
1371-
// so we can try to keep it around.
1372-
mService.mPreviousProcess = prev.app;
1373-
}
13741382
}
13751383

13761384
// Launching this app's activity, make sure the app is no longer

0 commit comments

Comments
 (0)