Merge "Notify SysUi on device rotation for back gesture" into ub-launcher3-rvc-dev

This commit is contained in:
TreeHugger Robot 2020-06-10 23:14:06 +00:00 committed by Android (Google) Code Review
commit ca5e9cb7ef
2 changed files with 115 additions and 10 deletions

View File

@ -16,6 +16,7 @@
package com.android.quickstep;
import static android.content.Intent.ACTION_USER_UNLOCKED;
import static android.view.Surface.ROTATION_0;
import static com.android.launcher3.util.DefaultDisplay.CHANGE_ALL;
import static com.android.launcher3.util.DefaultDisplay.CHANGE_FRAME_DELAY;
@ -48,15 +49,18 @@ import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
import androidx.annotation.BinderThread;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DefaultDisplay;
import com.android.launcher3.util.SecureSettingsObserver;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
@ -112,9 +116,53 @@ public class RecentsAnimationDeviceState implements
}
enableMultipleRegions(false);
}
@Override
public void onActivityRotation(int displayId) {
super.onActivityRotation(displayId);
// This always gets called before onDisplayInfoChanged() so we know how to process
// the rotation in that method. This is done to avoid having a race condition between
// the sensor readings and onDisplayInfoChanged() call
if (displayId != mDisplayId) {
return;
}
mPrioritizeDeviceRotation = true;
if (mInOverview) {
// reset, launcher must be rotating
mExitOverviewRunnable.run();
}
}
};
private Runnable mExitOverviewRunnable = new Runnable() {
@Override
public void run() {
mInOverview = false;
enableMultipleRegions(false);
}
};
private OrientationTouchTransformer mOrientationTouchTransformer;
/**
* Used to listen for when the device rotates into the orientation of the current
* foreground app. For example, if a user quickswitches from a portrait to a fixed landscape
* app and then rotates rotates the device to match that orientation, this triggers calls to
* sysui to adjust the navbar.
*/
private OrientationEventListener mOrientationListener;
private int mPreviousRotation = ROTATION_0;
/**
* This is the configuration of the foreground app or the app that will be in the foreground
* once a quickstep gesture finishes.
*/
private int mCurrentAppRotation = -1;
/**
* This flag is set to true when the device physically changes orientations. When true,
* we will always report the current rotation of the foreground app whenever the display
* changes, as it would indicate the user's intention to rotate the foreground app.
*/
private boolean mPrioritizeDeviceRotation = false;
private Region mExclusionRegion;
private SystemGestureExclusionListenerCompat mExclusionListener;
@ -193,6 +241,26 @@ public class RecentsAnimationDeviceState implements
userSetupObserver.register();
runOnDestroy(userSetupObserver::unregister);
}
mOrientationListener = new OrientationEventListener(context) {
@Override
public void onOrientationChanged(int degrees) {
int newRotation = RecentsOrientedState.getRotationForUserDegreesRotated(degrees,
mPreviousRotation);
if (newRotation == mPreviousRotation) {
return;
}
mPreviousRotation = newRotation;
mPrioritizeDeviceRotation = true;
if (newRotation == mCurrentAppRotation) {
// When user rotates device to the orientation of the foreground app after
// quickstepping
toggleSecondaryNavBarsForRotation(false);
}
}
};
}
private void setupOrientationSwipeHandler() {
@ -268,6 +336,18 @@ public class RecentsAnimationDeviceState implements
mNavBarPosition = new NavBarPosition(mMode, info);
updateGestureTouchRegions();
mOrientationTouchTransformer.createOrAddTouchRegion(info);
mCurrentAppRotation = mDisplayRotation;
/* Update nav bars on the following:
* a) if we're not expecting quickswitch, this is coming from an activity rotation
* b) we launch an app in the orientation that user is already in
* c) We're not in overview, since overview will always be portrait (w/o home rotation)
*/
if ((mPrioritizeDeviceRotation
|| mCurrentAppRotation == mPreviousRotation) // switch to an app of orientation user is in
&& !mInOverview) {
toggleSecondaryNavBarsForRotation(false);
}
}
/**
@ -553,9 +633,13 @@ public class RecentsAnimationDeviceState implements
mOrientationTouchTransformer.transform(event);
}
void enableMultipleRegions(boolean enable) {
mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
notifySysuiForRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
private void enableMultipleRegions(boolean enable) {
toggleSecondaryNavBarsForRotation(enable);
if (enable && !TestProtocol.sDisableSensorRotation) {
mOrientationListener.enable();
} else {
mOrientationListener.disable();
}
}
private void notifySysuiForRotation(int rotation) {
@ -581,10 +665,7 @@ public class RecentsAnimationDeviceState implements
// If we're in landscape w/o ever quickswitching, show the navbar in landscape
enableMultipleRegions(true);
}
activityInterface.onExitOverview(this, () -> {
mInOverview = false;
enableMultipleRegions(false);
});
activityInterface.onExitOverview(this, mExitOverviewRunnable);
} else if (endTarget == GestureState.GestureEndTarget.HOME) {
enableMultipleRegions(false);
} else if (endTarget == GestureState.GestureEndTarget.NEW_TASK) {
@ -594,6 +675,11 @@ public class RecentsAnimationDeviceState implements
} else {
notifySysuiForRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
}
// A new gesture is starting, reset the current device rotation
// This is done under the assumption that the user won't rotate the phone and then
// quickswitch in the old orientation.
mPrioritizeDeviceRotation = false;
} else if (endTarget == GestureState.GestureEndTarget.LAST_TASK) {
if (!mTaskListFrozen) {
// touched nav bar but didn't go anywhere and not quickswitching, do nothing
@ -603,7 +689,24 @@ public class RecentsAnimationDeviceState implements
}
}
int getCurrentActiveRotation() {
private void notifySysuiOfCurrentRotation(int rotation) {
UI_HELPER_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(mContext)
.onQuickSwitchToNewTask(rotation));
}
/**
* Disables/Enables multiple nav bars on {@link OrientationTouchTransformer} and then
* notifies system UI of the primary rotation the user is interacting with
*
* @param enable if {@code true}, this will report to sysUI the navbar of the region the gesture
* started in (during ACTION_DOWN), otherwise will report {@param displayRotation}
*/
private void toggleSecondaryNavBarsForRotation(boolean enable) {
mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
}
public int getCurrentActiveRotation() {
if (!mMode.hasGestures) {
// touch rotation should always match that of display for 3 button
return mDisplayRotation;

View File

@ -445,7 +445,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
}
break;
case ROTATION_270:
if (degrees < (90 - threshold)) {
if (degrees < (90 - threshold) ||
(degrees > (270 + threshold) && degrees < 360)) {
return ROTATION_0;
}
if (degrees > (90 + threshold) && degrees < 180) {
@ -468,7 +469,8 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
if (degrees < (270 - threshold) && degrees > 90) {
return ROTATION_180;
}
if (degrees > (270 + threshold) && degrees < 360) {
if (degrees > (270 + threshold) && degrees < 360
|| (degrees >= 0 && degrees < threshold)) {
return ROTATION_0;
}
// flip from landscape to seascape