Fix weirdness when home task forces rotation

- Make sure to retain the state when divider goes through a configuration
change in order to avoid that nothing happens when entering multi-window.
Save the state in DividerState and use a handler that's independant of the
attached state.
- Don't allow home task to dictate orientation unless the docked stack is
minimized. This caused a lot of weird bugs because when docking a task,
home stack gets moved to front, and if home task is front of stack, it
temporarily might dictate the rotation but later not anymore so this
causes two rapid configuration changes which may cause a lot of weirdness.

Change-Id: I6a2308af893cd8413ee8801e5b964f6ddc0abd51
Fixes: 28943853
This commit is contained in:
Jorim Jaggi
2016-05-27 00:31:21 -07:00
parent c5fc6c602c
commit a6c05d5151
4 changed files with 47 additions and 16 deletions

View File

@@ -39,6 +39,7 @@ import java.io.PrintWriter;
public class Divider extends SystemUI { public class Divider extends SystemUI {
private DividerWindowManager mWindowManager; private DividerWindowManager mWindowManager;
private DividerView mView; private DividerView mView;
private final DividerState mDividerState = new DividerState();
private DockDividerVisibilityListener mDockDividerVisibilityListener; private DockDividerVisibilityListener mDockDividerVisibilityListener;
private boolean mVisible = false; private boolean mVisible = false;
private boolean mMinimized = false; private boolean mMinimized = false;
@@ -76,7 +77,7 @@ public class Divider extends SystemUI {
final int width = landscape ? size : MATCH_PARENT; final int width = landscape ? size : MATCH_PARENT;
final int height = landscape ? MATCH_PARENT : size; final int height = landscape ? MATCH_PARENT : size;
mWindowManager.add(mView, width, height); mWindowManager.add(mView, width, height);
mView.setWindowManager(mWindowManager); mView.injectDependencies(mWindowManager, mDividerState);
} }
private void removeDivider() { private void removeDivider() {

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.systemui.stackdivider;
/**
* Class to hold state of divider that needs to persist across configuration changes.
*/
public class DividerState {
public boolean animateAfterRecentsDrawn;
public boolean growAfterRecentsDrawn;
}

View File

@@ -30,12 +30,12 @@ import android.graphics.Rect;
import android.graphics.Region.Op; import android.graphics.Region.Op;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.Display; import android.view.Display;
import android.view.DisplayInfo; import android.view.DisplayInfo;
import android.view.GestureDetector; import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener; import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.PointerIcon; import android.view.PointerIcon;
import android.view.VelocityTracker; import android.view.VelocityTracker;
@@ -141,8 +141,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
private DividerSnapAlgorithm mSnapAlgorithm; private DividerSnapAlgorithm mSnapAlgorithm;
private final Rect mStableInsets = new Rect(); private final Rect mStableInsets = new Rect();
private boolean mAnimateAfterRecentsDrawn;
private boolean mGrowAfterRecentsDrawn;
private boolean mGrowRecents; private boolean mGrowRecents;
private ValueAnimator mCurrentAnimator; private ValueAnimator mCurrentAnimator;
private boolean mEntranceAnimationRunning; private boolean mEntranceAnimationRunning;
@@ -151,6 +149,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
private GestureDetector mGestureDetector; private GestureDetector mGestureDetector;
private boolean mDockedStackMinimized; private boolean mDockedStackMinimized;
private boolean mAdjustedForIme; private boolean mAdjustedForIme;
private DividerState mState;
private final Handler mHandler = new Handler();
private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() { private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
@Override @Override
@@ -335,8 +335,9 @@ public class DividerView extends FrameLayout implements OnTouchListener,
} }
} }
public void setWindowManager(DividerWindowManager windowManager) { public void injectDependencies(DividerWindowManager windowManager, DividerState dividerState) {
mWindowManager = windowManager; mWindowManager = windowManager;
mState = dividerState;
} }
public WindowManagerProxy getWindowManagerProxy() { public WindowManagerProxy getWindowManagerProxy() {
@@ -558,7 +559,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
if (endDelay == 0 || mCancelled) { if (endDelay == 0 || mCancelled) {
endAction.run(); endAction.run();
} else { } else {
postDelayed(endAction, endDelay); mHandler.postDelayed(endAction, endDelay);
} }
} }
}); });
@@ -1048,15 +1049,15 @@ public class DividerView extends FrameLayout implements OnTouchListener,
public final void onBusEvent(RecentsActivityStartingEvent recentsActivityStartingEvent) { public final void onBusEvent(RecentsActivityStartingEvent recentsActivityStartingEvent) {
if (mGrowRecents && getWindowManagerProxy().getDockSide() == WindowManager.DOCKED_TOP if (mGrowRecents && getWindowManagerProxy().getDockSide() == WindowManager.DOCKED_TOP
&& getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position) { && getCurrentPosition() == getSnapAlgorithm().getLastSplitTarget().position) {
mGrowAfterRecentsDrawn = true; mState.growAfterRecentsDrawn = true;
startDragging(false /* animate */, false /* touching */); startDragging(false /* animate */, false /* touching */);
} }
} }
public final void onBusEvent(DockedTopTaskEvent event) { public final void onBusEvent(DockedTopTaskEvent event) {
if (event.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) { if (event.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) {
mGrowAfterRecentsDrawn = false; mState.growAfterRecentsDrawn = false;
mAnimateAfterRecentsDrawn = true; mState.animateAfterRecentsDrawn = true;
startDragging(false /* animate */, false /* touching */); startDragging(false /* animate */, false /* touching */);
} }
updateDockSide(); updateDockSide();
@@ -1068,11 +1069,11 @@ public class DividerView extends FrameLayout implements OnTouchListener,
} }
public final void onBusEvent(RecentsDrawnEvent drawnEvent) { public final void onBusEvent(RecentsDrawnEvent drawnEvent) {
if (mAnimateAfterRecentsDrawn) { if (mState.animateAfterRecentsDrawn) {
mAnimateAfterRecentsDrawn = false; mState.animateAfterRecentsDrawn = false;
updateDockSide(); updateDockSide();
post(() -> { mHandler.post(() -> {
// Delay switching resizing mode because this might cause jank in recents animation // Delay switching resizing mode because this might cause jank in recents animation
// that's longer than this animation. // that's longer than this animation.
stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(),
@@ -1080,8 +1081,8 @@ public class DividerView extends FrameLayout implements OnTouchListener,
200 /* endDelay */); 200 /* endDelay */);
}); });
} }
if (mGrowAfterRecentsDrawn) { if (mState.growAfterRecentsDrawn) {
mGrowAfterRecentsDrawn = false; mState.growAfterRecentsDrawn = false;
updateDockSide(); updateDockSide();
EventBus.getDefault().send(new RecentsGrowingEvent()); EventBus.getDefault().send(new RecentsGrowingEvent());
stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 336, stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 336,

View File

@@ -3569,6 +3569,8 @@ public class WindowManagerService extends IWindowManager.Stub
final ArrayList<Task> tasks = displayContent.getTasks(); final ArrayList<Task> tasks = displayContent.getTasks();
final boolean inMultiWindow = isStackVisibleLocked(DOCKED_STACK_ID) final boolean inMultiWindow = isStackVisibleLocked(DOCKED_STACK_ID)
|| isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID); || isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID);
final boolean dockMinimized =
getDefaultDisplayContentLocked().mDividerControllerLocked.isMinimizedDock();
for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
AppTokenList tokens = tasks.get(taskNdx).mAppTokens; AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
final int firstToken = tokens.size() - 1; final int firstToken = tokens.size() - 1;
@@ -3603,8 +3605,10 @@ public class WindowManagerService extends IWindowManager.Stub
continue; continue;
} }
// No app except the home app may specify the screen orientation in multi-window. // No app except the home app may specify the screen orientation in multi-window,
if (inMultiWindow && !atoken.mTask.isHomeTask()) { // and only if the docked stack is minimized to avoid weirdness when home task
// temporarily gets moved to the front.
if (inMultiWindow && (!atoken.mTask.isHomeTask() || !dockMinimized)) {
continue; continue;
} }