Merge "Fixed some activity visiblility issues in picture-in-picutre mode"

This commit is contained in:
Wale Ogunwale
2016-01-13 00:59:34 +00:00
committed by Android (Google) Code Review
4 changed files with 46 additions and 40 deletions

View File

@@ -592,6 +592,14 @@ public class ActivityManager {
public static boolean isAlwaysOnTop(int stackId) {
return stackId == PINNED_STACK_ID;
}
/**
* Returns true if the top task in the task is allowed to return home when finished and
* there are other tasks in the stack.
*/
public static boolean allowTopTaskToReturnHome(int stackId) {
return stackId != PINNED_STACK_ID;
}
}
/**

View File

@@ -171,7 +171,9 @@ final class ActivityRecord {
boolean stopped; // is activity pause finished?
boolean delayedResume; // not yet resumed because of stopped app switches?
boolean finishing; // activity in pending finish list?
boolean configDestroy; // need to destroy due to config change?
boolean deferRelaunchUntilPaused; // relaunch of activity is being deferred until pause is
// completed
boolean preserveWindowOnDeferredRelaunch; // activity windows are preserved on deferred relaunch
int configChangeFlags; // which config values have changed
boolean keysPaused; // has key dispatching been paused for it?
int launchMode; // the launch mode activity attribute.
@@ -184,9 +186,9 @@ final class ActivityRecord {
boolean immersive; // immersive mode (don't interrupt if possible)
boolean forceNewConfig; // force re-create with new config next time
int launchCount; // count of launches since last state
long lastLaunchTime; // time of last lauch of this activity
long lastLaunchTime; // time of last launch of this activity
boolean isVrActivity; // is the activity running in VR mode?
ArrayList<ActivityContainer> mChildContainers = new ArrayList<ActivityContainer>();
ArrayList<ActivityContainer> mChildContainers = new ArrayList<>();
String stringName; // for caching of toString().
@@ -341,8 +343,8 @@ final class ActivityRecord {
else TimeUtils.formatDuration(lastVisibleTime, now, pw);
pw.println();
}
if (configDestroy || configChangeFlags != 0) {
pw.print(prefix); pw.print("configDestroy="); pw.print(configDestroy);
if (deferRelaunchUntilPaused || configChangeFlags != 0) {
pw.print(prefix); pw.print("deferRelaunchUntilPaused="); pw.print(deferRelaunchUntilPaused);
pw.print(" configChangeFlags=");
pw.println(Integer.toHexString(configChangeFlags));
}
@@ -551,7 +553,7 @@ final class ActivityRecord {
stopped = false;
delayedResume = false;
finishing = false;
configDestroy = false;
deferRelaunchUntilPaused = false;
keysPaused = false;
inHistory = false;
visible = false;

View File

@@ -1088,7 +1088,7 @@ final class ActivityStack {
if (r.finishing) {
r.clearOptionsLocked();
} else {
if (r.configDestroy) {
if (r.deferRelaunchUntilPaused) {
destroyActivityLocked(r, true, "stop-config");
mStackSupervisor.resumeFocusedStackTopActivityLocked();
} else {
@@ -1114,14 +1114,11 @@ final class ActivityStack {
if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
"Complete pause, no longer waiting: " + prev);
}
if (prev.configDestroy) {
// The previous is being paused because the configuration
// is changing, which means it is actually stopping...
// To juggle the fact that we are also starting a new
// instance right now, we need to first completely stop
// the current instance before starting the new one.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Destroying after pause: " + prev);
destroyActivityLocked(prev, true, "pause-config");
if (prev.deferRelaunchUntilPaused) {
// Complete the deferred relaunch that was waiting for pause to complete.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
relaunchActivityLocked(prev, prev.configChangeFlags, false,
prev.preserveWindowOnDeferredRelaunch);
} else if (wasStopping) {
// We are also stopping, the stop request must have gone soon after the pause.
// We can't clobber it, because the stop confirmation will not be handled.
@@ -2318,11 +2315,12 @@ final class ActivityStack {
ActivityStack lastStack = mStackSupervisor.getLastStack();
final boolean fromHome = lastStack.isHomeStack();
if (!isHomeStack() && (fromHome || topTask() != task)) {
task.setTaskToReturnTo(fromHome
? lastStack.topTask() == null
? HOME_ACTIVITY_TYPE
: lastStack.topTask().taskType
: APPLICATION_ACTIVITY_TYPE);
int returnToType = APPLICATION_ACTIVITY_TYPE;
if (fromHome && StackId.allowTopTaskToReturnHome(mStackId)) {
returnToType = lastStack.topTask() == null
? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType;
}
task.setTaskToReturnTo(returnToType);
}
} else {
task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
@@ -2972,7 +2970,7 @@ final class ActivityStack {
r.stopped = true;
if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
r.state = ActivityState.STOPPED;
if (r.configDestroy) {
if (r.deferRelaunchUntilPaused) {
destroyActivityLocked(r, true, "stop-except");
}
}
@@ -3403,7 +3401,7 @@ final class ActivityStack {
}
mService.resetFocusedActivityIfNeededLocked(r);
r.configDestroy = false;
r.deferRelaunchUntilPaused = false;
r.frozenBeforeDestroy = false;
if (setState) {
@@ -4175,38 +4173,33 @@ final class ActivityStack {
r.configChangeFlags |= changes;
r.startFreezingScreenLocked(r.app, globalChanges);
r.forceNewConfig = false;
preserveWindow &= isResizeOnlyChange(changes);
if (r.app == null || r.app.thread == null) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is destroying non-running " + r);
destroyActivityLocked(r, true, "config");
} else if (r.state == ActivityState.PAUSING) {
// A little annoying: we are waiting for this activity to
// finish pausing. Let's not do anything now, but just
// flag that it needs to be restarted when done pausing.
// A little annoying: we are waiting for this activity to finish pausing. Let's not
// do anything now, but just flag that it needs to be restarted when done pausing.
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is skipping already pausing " + r);
r.configDestroy = true;
r.deferRelaunchUntilPaused = true;
r.preserveWindowOnDeferredRelaunch = preserveWindow;
return true;
} else if (r.state == ActivityState.RESUMED) {
// Try to optimize this case: the configuration is changing
// and we need to restart the top, resumed activity.
// Instead of doing the normal handshaking, just say
// Try to optimize this case: the configuration is changing and we need to restart
// the top, resumed activity. Instead of doing the normal handshaking, just say
// "restart!".
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is relaunching resumed " + r);
relaunchActivityLocked(r, r.configChangeFlags, true,
preserveWindow && isResizeOnlyChange(changes));
r.configChangeFlags = 0;
relaunchActivityLocked(r, r.configChangeFlags, true, preserveWindow);
} else {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is relaunching non-resumed " + r);
relaunchActivityLocked(r, r.configChangeFlags, false,
preserveWindow && isResizeOnlyChange(changes));
r.configChangeFlags = 0;
relaunchActivityLocked(r, r.configChangeFlags, false, preserveWindow);
}
// All done... tell the caller we weren't able to keep this
// activity around.
// All done... tell the caller we weren't able to keep this activity around.
return false;
}
@@ -4298,6 +4291,7 @@ final class ActivityStack {
private void relaunchActivityLocked(
ActivityRecord r, int changes, boolean andResume, boolean preserveWindow) {
if (mService.mSuppressResizeConfigChanges && preserveWindow) {
r.configChangeFlags = 0;
return;
}
@@ -4341,6 +4335,8 @@ final class ActivityStack {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
r.state = ActivityState.PAUSED;
}
r.configChangeFlags = 0;
}
boolean willActivityBeVisibleLocked(IBinder token) {

View File

@@ -2722,7 +2722,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord s = mStoppingActivities.get(activityNdx);
final boolean waitingVisible = mWaitingVisibleActivities.contains(s);
if (DEBUG_ALL) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
+ " waitingVisible=" + waitingVisible + " finishing=" + s.finishing);
if (waitingVisible && nowVisible) {
mWaitingVisibleActivities.remove(s);
@@ -2732,12 +2732,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
// so get rid of it. Otherwise, we need to go through the
// normal flow and hide it once we determine that it is
// hidden by the activities in front of it.
if (DEBUG_ALL) Slog.v(TAG, "Before stopping, can hide: " + s);
if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s);
mWindowManager.setAppVisibility(s.appToken, false);
}
}
if ((!waitingVisible || mService.isSleepingOrShuttingDown()) && remove) {
if (DEBUG_ALL) Slog.v(TAG, "Ready to stop: " + s);
if (DEBUG_STATES) Slog.v(TAG, "Ready to stop: " + s);
if (stops == null) {
stops = new ArrayList<>();
}