Merge "Some fixes for docking from navigation bar use case"
This commit is contained in:
@@ -1958,10 +1958,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
|| tempOtherTaskInsetBounds != null);
|
||||
}
|
||||
|
||||
void resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow) {
|
||||
boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow) {
|
||||
if (!task.mResizeable) {
|
||||
Slog.w(TAG, "resizeTask: task " + task + " not resizeable.");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
adjustForMinimalTaskDimensions(task, bounds);
|
||||
@@ -1971,7 +1971,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
|
||||
if (task.mBounds != null && task.mBounds.equals(bounds) && !forced) {
|
||||
// Nothing to do here...
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mWindowManager.isValidTaskId(task.taskId)) {
|
||||
@@ -1983,7 +1983,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
// re-restore the task so it can have the proper stack association.
|
||||
restoreRecentTaskLocked(task, FREEFORM_WORKSPACE_STACK_ID);
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do not move the task to another stack here.
|
||||
@@ -2012,6 +2012,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
mWindowManager.resizeTask(task.taskId, bounds, task.mOverrideConfig, kept, forced);
|
||||
|
||||
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
|
||||
return kept;
|
||||
}
|
||||
|
||||
private void adjustForMinimalTaskDimensions(TaskRecord task, Rect bounds) {
|
||||
@@ -2169,13 +2170,17 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
|
||||
final ActivityRecord topActivity = task.getTopActivity();
|
||||
if (StackId.preserveWindowOnTaskMove(stackId) && topActivity != null) {
|
||||
final boolean mightReplaceWindow =
|
||||
StackId.preserveWindowOnTaskMove(stackId) && topActivity != null;
|
||||
if (mightReplaceWindow) {
|
||||
// We are about to relaunch the activity because its configuration changed due to
|
||||
// being maximized, i.e. size change. The activity will first remove the old window
|
||||
// and then add a new one. This call will tell window manager about this, so it can
|
||||
// preserve the old window until the new one is drawn. This prevents having a gap
|
||||
// between the removal and addition, in which no window is visible. We also want the
|
||||
// entrance of the new window to be properly animated.
|
||||
// Note here we always set the replacing window first, as the flags might be needed
|
||||
// during the relaunch. If we end up not doing any relaunch, we clear the flags later.
|
||||
mWindowManager.setReplacingWindow(topActivity.appToken, animate);
|
||||
}
|
||||
final ActivityStack stack = moveTaskToStackUncheckedLocked(
|
||||
@@ -2185,15 +2190,23 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
stack.mNoAnimActivities.add(topActivity);
|
||||
}
|
||||
|
||||
boolean kept = true;
|
||||
// Make sure the task has the appropriate bounds/size for the stack it is in.
|
||||
if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) {
|
||||
resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
|
||||
kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
|
||||
} else if (stackId == FREEFORM_WORKSPACE_STACK_ID
|
||||
&& task.mBounds == null && task.mLastNonFullscreenBounds != null) {
|
||||
resizeTaskLocked(task, task.mLastNonFullscreenBounds,
|
||||
kept = resizeTaskLocked(task, task.mLastNonFullscreenBounds,
|
||||
RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
|
||||
} else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) {
|
||||
resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
|
||||
kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !PRESERVE_WINDOWS);
|
||||
}
|
||||
|
||||
if (mightReplaceWindow) {
|
||||
// If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
|
||||
// window), we need to clear the replace window settings. Otherwise, we schedule a
|
||||
// timeout to remove the old window if the replacing window is not coming in time.
|
||||
mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept);
|
||||
}
|
||||
|
||||
// The task might have already been running and its visibility needs to be synchronized with
|
||||
|
||||
@@ -25,6 +25,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
import static com.android.server.wm.WindowManagerService.WINDOW_REPLACEMENT_TIMEOUT_DURATION;
|
||||
|
||||
import com.android.server.input.InputApplicationHandle;
|
||||
import com.android.server.wm.WindowManagerService.H;
|
||||
@@ -403,12 +404,28 @@ class AppWindowToken extends WindowToken {
|
||||
}
|
||||
}
|
||||
|
||||
void resetReplacingWindows() {
|
||||
if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Resetting app token " + appWindowToken
|
||||
+ " of replacing window marks.");
|
||||
|
||||
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
|
||||
final WindowState w = allAppWindows.get(i);
|
||||
w.resetReplacing();
|
||||
}
|
||||
}
|
||||
|
||||
void addWindow(WindowState w) {
|
||||
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
|
||||
WindowState candidate = allAppWindows.get(i);
|
||||
if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null &&
|
||||
candidate.getWindowTag().equals(w.getWindowTag().toString())) {
|
||||
candidate.mReplacingWindow = w;
|
||||
|
||||
// if we got a replacement window, reset the timeout to give drawing more time
|
||||
service.mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT);
|
||||
service.mH.sendMessageDelayed(
|
||||
service.mH.obtainMessage(H.WINDOW_REPLACEMENT_TIMEOUT, this),
|
||||
WINDOW_REPLACEMENT_TIMEOUT_DURATION);
|
||||
}
|
||||
}
|
||||
allAppWindows.add(w);
|
||||
@@ -424,7 +441,7 @@ class AppWindowToken extends WindowToken {
|
||||
return false;
|
||||
}
|
||||
|
||||
void clearTimedoutReplaceesLocked() {
|
||||
void clearTimedoutReplacesLocked() {
|
||||
for (int i = allAppWindows.size() - 1; i >= 0;
|
||||
// removeWindowLocked at bottom of loop may remove multiple entries from
|
||||
// allAppWindows if the window to be removed has child windows. It also may
|
||||
@@ -437,7 +454,11 @@ class AppWindowToken extends WindowToken {
|
||||
continue;
|
||||
}
|
||||
candidate.mWillReplaceWindow = false;
|
||||
service.removeWindowLocked(candidate);
|
||||
// Since the window already timed out, remove it immediately now.
|
||||
// Use removeWindowInnerLocked() instead of removeWindowLocked(), as the latter
|
||||
// delays removal on certain conditions, which will leave the stale window in the
|
||||
// stack and marked mWillReplaceWindow=false, so the window will never be removed.
|
||||
service.removeWindowInnerLocked(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8106,7 +8106,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
case WINDOW_REPLACEMENT_TIMEOUT: {
|
||||
final AppWindowToken token = (AppWindowToken) msg.obj;
|
||||
synchronized (mWindowMap) {
|
||||
token.clearTimedoutReplaceesLocked();
|
||||
token.clearTimedoutReplacesLocked();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -10192,11 +10192,34 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
appWindowToken.setReplacingWindows(animate);
|
||||
}
|
||||
}
|
||||
|
||||
if (appWindowToken != null) {
|
||||
mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT);
|
||||
mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_REPLACEMENT_TIMEOUT, appWindowToken),
|
||||
WINDOW_REPLACEMENT_TIMEOUT_DURATION);
|
||||
/**
|
||||
* If we're replacing the window, schedule a timer to clear the replaced window
|
||||
* after a timeout, in case the replacing window is not coming.
|
||||
*
|
||||
* If we're not replacing the window, clear the replace window settings of the app.
|
||||
*
|
||||
* @param token Application token for the activity whose window might be replaced.
|
||||
* @param replacing Whether the window is being replaced or not.
|
||||
*/
|
||||
public void scheduleClearReplacingWindowIfNeeded(IBinder token, boolean replacing) {
|
||||
AppWindowToken appWindowToken = null;
|
||||
synchronized (mWindowMap) {
|
||||
appWindowToken = findAppWindowToken(token);
|
||||
if (appWindowToken == null) {
|
||||
Slog.w(TAG_WM, "Attempted to reset replacing window on non-existing app token "
|
||||
+ token);
|
||||
return;
|
||||
}
|
||||
if (replacing) {
|
||||
mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT);
|
||||
mH.sendMessageDelayed(
|
||||
mH.obtainMessage(H.WINDOW_REPLACEMENT_TIMEOUT, appWindowToken),
|
||||
WINDOW_REPLACEMENT_TIMEOUT_DURATION);
|
||||
} else {
|
||||
appWindowToken.resetReplacingWindows();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2363,4 +2363,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
|
||||
mReplacingWindow = null;
|
||||
mAnimateReplacingWindow = animate;
|
||||
}
|
||||
|
||||
void resetReplacing() {
|
||||
mWillReplaceWindow = false;
|
||||
mReplacingWindow = null;
|
||||
mAnimateReplacingWindow = false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user