Fix a couple of rotation bugs
- device stuck in landscape mode: rotation watcher should not be unregistered when rotation button is hidden. In the case of launcher forcing portrait mode, rotation watcher listens to the rotation change and update the current rotation on the System UI side - floating rotation button animation timeout: because we attach and detach the view upon rotation visibility change, posting the callback on the view is not a good idea. We change it to post on the main thread instead. Fixes: 134643704 Test: Open any app in the fully gestural mode, rotate to landscape mode using the rotation button, and swipe up. Go back to the app and observe it's opened in the portrait mode. Test: Previously if user changes the device orientation and presses on the rotation button in the middle of the animation, and quickly changes the orientation back, the second rotation button animation duration is cut short. Now the duration of both animations are the full 5 seconds. Change-Id: I9b58ef3d284e7366e83ffaa777fd822ed1e0bc23
This commit is contained in:
@@ -115,7 +115,6 @@ public class FloatingRotationButton implements RotationButton {
|
||||
return false;
|
||||
}
|
||||
mWindowManager.removeViewImmediate(mKeyButtonView);
|
||||
mRotationButtonController.cleanUp();
|
||||
mIsShowing = false;
|
||||
return true;
|
||||
}
|
||||
@@ -141,10 +140,7 @@ public class FloatingRotationButton implements RotationButton {
|
||||
|
||||
@Override
|
||||
public void setOnClickListener(View.OnClickListener onClickListener) {
|
||||
mKeyButtonView.setOnClickListener(view -> {
|
||||
hide();
|
||||
onClickListener.onClick(view);
|
||||
});
|
||||
mKeyButtonView.setOnClickListener(onClickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -872,9 +872,6 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
|
||||
boolean[] feedbackEnabled = new boolean[1];
|
||||
int a11yFlags = getA11yButtonState(feedbackEnabled);
|
||||
|
||||
mNavigationBarView.getRotationButtonController().setAccessibilityFeedbackEnabled(
|
||||
feedbackEnabled[0]);
|
||||
|
||||
boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
|
||||
boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
|
||||
mNavigationBarView.setAccessibilityButtonState(clickable, longClickable);
|
||||
|
||||
@@ -1040,6 +1040,9 @@ public class NavigationBarView extends FrameLayout implements
|
||||
reorient();
|
||||
onNavigationModeChanged(mNavBarMode);
|
||||
setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
|
||||
if (mRotationButtonController != null) {
|
||||
mRotationButtonController.registerListeners();
|
||||
}
|
||||
|
||||
mEdgeBackGestureHandler.onNavBarAttached();
|
||||
getViewTreeObserver().addOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
|
||||
@@ -1053,6 +1056,10 @@ public class NavigationBarView extends FrameLayout implements
|
||||
for (int i = 0; i < mButtonDispatchers.size(); ++i) {
|
||||
mButtonDispatchers.valueAt(i).onDestroy();
|
||||
}
|
||||
if (mRotationButtonController != null) {
|
||||
mRotationButtonController.unregisterListeners();
|
||||
}
|
||||
|
||||
mEdgeBackGestureHandler.onNavBarDetached();
|
||||
getViewTreeObserver().removeOnComputeInternalInsetsListener(
|
||||
mOnComputeInternalInsetsListener);
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.app.StatusBarManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.view.IRotationWatcher.Stub;
|
||||
@@ -34,6 +34,7 @@ import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.WindowManagerGlobal;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
@@ -42,6 +43,7 @@ import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
|
||||
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
|
||||
import com.android.systemui.statusbar.policy.RotationLockController;
|
||||
|
||||
@@ -64,8 +66,10 @@ public class RotationButtonController {
|
||||
private boolean mPendingRotationSuggestion;
|
||||
private boolean mHoveringRotationSuggestion;
|
||||
private RotationLockController mRotationLockController;
|
||||
private AccessibilityManagerWrapper mAccessibilityManagerWrapper;
|
||||
private TaskStackListenerImpl mTaskStackListener;
|
||||
private Consumer<Integer> mRotWatcherListener;
|
||||
private boolean mListenersRegistered = false;
|
||||
private boolean mIsNavigationBarShowing;
|
||||
|
||||
private final Runnable mRemoveRotationProposal =
|
||||
@@ -73,22 +77,17 @@ public class RotationButtonController {
|
||||
private final Runnable mCancelPendingRotationProposal =
|
||||
() -> mPendingRotationSuggestion = false;
|
||||
private Animator mRotateHideAnimator;
|
||||
private boolean mAccessibilityFeedbackEnabled;
|
||||
|
||||
private final Context mContext;
|
||||
private final RotationButton mRotationButton;
|
||||
private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
private final Stub mRotationWatcher = new Stub() {
|
||||
@Override
|
||||
public void onRotationChanged(final int rotation) throws RemoteException {
|
||||
if (mRotationButton.getCurrentView() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need this to be scheduled as early as possible to beat the redrawing of
|
||||
// window in response to the orientation change.
|
||||
Handler h = mRotationButton.getCurrentView().getHandler();
|
||||
Message msg = Message.obtain(h, () -> {
|
||||
mMainThreadHandler.postAtFrontOfQueue(() -> {
|
||||
// If the screen rotation changes while locked, potentially update lock to flow with
|
||||
// new screen rotation and hide any showing suggestions.
|
||||
if (mRotationLockController.isRotationLocked()) {
|
||||
@@ -102,8 +101,6 @@ public class RotationButtonController {
|
||||
mRotWatcherListener.accept(rotation);
|
||||
}
|
||||
});
|
||||
msg.setAsynchronous(true);
|
||||
h.sendMessageAtFrontOfQueue(msg);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,40 +121,49 @@ public class RotationButtonController {
|
||||
mStyleRes = style;
|
||||
mIsNavigationBarShowing = true;
|
||||
mRotationLockController = Dependency.get(RotationLockController.class);
|
||||
mAccessibilityManagerWrapper = Dependency.get(AccessibilityManagerWrapper.class);
|
||||
|
||||
// Register the task stack listener
|
||||
mTaskStackListener = new TaskStackListenerImpl();
|
||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
|
||||
mRotationButton.setOnClickListener(this::onRotateSuggestionClick);
|
||||
mRotationButton.setOnHoverListener(this::onRotateSuggestionHover);
|
||||
}
|
||||
|
||||
void registerListeners() {
|
||||
if (mListenersRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
mListenersRegistered = true;
|
||||
try {
|
||||
WindowManagerGlobal.getWindowManagerService()
|
||||
.watchRotation(mRotationWatcher, mContext.getDisplay().getDisplayId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
|
||||
}
|
||||
|
||||
void cleanUp() {
|
||||
// Unregister the task stack listener
|
||||
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
|
||||
void unregisterListeners() {
|
||||
if (!mListenersRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
mListenersRegistered = false;
|
||||
try {
|
||||
WindowManagerGlobal.getWindowManagerService().removeRotationWatcher(mRotationWatcher);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
|
||||
}
|
||||
|
||||
void addRotationCallback(Consumer<Integer> watcher) {
|
||||
mRotWatcherListener = watcher;
|
||||
}
|
||||
|
||||
void setAccessibilityFeedbackEnabled(boolean flag) {
|
||||
mAccessibilityFeedbackEnabled = flag;
|
||||
}
|
||||
|
||||
void setRotationLockedAtAngle(int rotationSuggestion) {
|
||||
mRotationLockController.setRotationLockedAtAngle(true /* locked */, rotationSuggestion);
|
||||
}
|
||||
@@ -185,7 +191,7 @@ public class RotationButtonController {
|
||||
|
||||
// Clear any pending suggestion flag as it has either been nullified or is being shown
|
||||
mPendingRotationSuggestion = false;
|
||||
view.removeCallbacks(mCancelPendingRotationProposal);
|
||||
mMainThreadHandler.removeCallbacks(mCancelPendingRotationProposal);
|
||||
|
||||
// Handle the visibility change and animation
|
||||
if (visible) { // Appear and change (cannot force)
|
||||
@@ -255,13 +261,9 @@ public class RotationButtonController {
|
||||
return;
|
||||
}
|
||||
|
||||
final View currentView = mRotationButton.getCurrentView();
|
||||
|
||||
// If window rotation matches suggested rotation, remove any current suggestions
|
||||
if (rotation == windowRotation) {
|
||||
if (currentView != null) {
|
||||
currentView.removeCallbacks(mRemoveRotationProposal);
|
||||
}
|
||||
mMainThreadHandler.removeCallbacks(mRemoveRotationProposal);
|
||||
setRotateSuggestionButtonState(false /* visible */);
|
||||
return;
|
||||
}
|
||||
@@ -285,11 +287,9 @@ public class RotationButtonController {
|
||||
// If the navbar isn't shown, flag the rotate icon to be shown should the navbar become
|
||||
// visible given some time limit.
|
||||
mPendingRotationSuggestion = true;
|
||||
if (currentView != null) {
|
||||
currentView.removeCallbacks(mCancelPendingRotationProposal);
|
||||
currentView.postDelayed(mCancelPendingRotationProposal,
|
||||
NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS);
|
||||
}
|
||||
mMainThreadHandler.removeCallbacks(mCancelPendingRotationProposal);
|
||||
mMainThreadHandler.postDelayed(mCancelPendingRotationProposal,
|
||||
NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,9 +334,7 @@ public class RotationButtonController {
|
||||
private void onRotationSuggestionsDisabled() {
|
||||
// Immediately hide the rotate button and clear any planned removal
|
||||
setRotateSuggestionButtonState(false /* visible */, true /* force */);
|
||||
if (mRotationButton.getCurrentView() != null) {
|
||||
mRotationButton.getCurrentView().removeCallbacks(mRemoveRotationProposal);
|
||||
}
|
||||
mMainThreadHandler.removeCallbacks(mRemoveRotationProposal);
|
||||
}
|
||||
|
||||
private void showAndLogRotationSuggestion() {
|
||||
@@ -369,10 +367,6 @@ public class RotationButtonController {
|
||||
}
|
||||
|
||||
private void rescheduleRotationTimeout(final boolean reasonHover) {
|
||||
if (mRotationButton.getCurrentView() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// May be called due to a new rotation proposal or a change in hover state
|
||||
if (reasonHover) {
|
||||
// Don't reschedule if a hide animator is running
|
||||
@@ -382,16 +376,16 @@ public class RotationButtonController {
|
||||
}
|
||||
|
||||
// Stop any pending removal
|
||||
mRotationButton.getCurrentView().removeCallbacks(mRemoveRotationProposal);
|
||||
mMainThreadHandler.removeCallbacks(mRemoveRotationProposal);
|
||||
// Schedule timeout
|
||||
mRotationButton.getCurrentView().postDelayed(mRemoveRotationProposal,
|
||||
mMainThreadHandler.postDelayed(mRemoveRotationProposal,
|
||||
computeRotationProposalTimeout());
|
||||
}
|
||||
|
||||
private int computeRotationProposalTimeout() {
|
||||
if (mAccessibilityFeedbackEnabled) return 10000;
|
||||
if (mHoveringRotationSuggestion) return 8000;
|
||||
return 5000;
|
||||
return mAccessibilityManagerWrapper.getRecommendedTimeoutMillis(
|
||||
mHoveringRotationSuggestion ? 16000 : 5000,
|
||||
AccessibilityManager.FLAG_CONTENT_CONTROLS);
|
||||
}
|
||||
|
||||
private boolean isRotateSuggestionIntroduced() {
|
||||
|
||||
@@ -63,13 +63,6 @@ public class RotationContextButton extends ContextualButton implements
|
||||
null /* ovalBackgroundColor */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (mRotationButtonController != null) {
|
||||
mRotationButtonController.cleanUp();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNavigationModeChanged(int mode) {
|
||||
mNavBarMode = mode;
|
||||
|
||||
Reference in New Issue
Block a user