Merge "Move rotation logic to RotationTouchHelper" into ub-launcher3-rvc-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
eb2eb38cc2
@@ -397,7 +397,8 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
|||||||
mOnDeferredActivityLaunch);
|
mOnDeferredActivityLaunch);
|
||||||
|
|
||||||
mGestureState.runOnceAtState(STATE_END_TARGET_SET,
|
mGestureState.runOnceAtState(STATE_END_TARGET_SET,
|
||||||
() -> mDeviceState.onEndTargetCalculated(mGestureState.getEndTarget(),
|
() -> mDeviceState.getRotationTouchHelper().
|
||||||
|
onEndTargetCalculated(mGestureState.getEndTarget(),
|
||||||
mActivityInterface));
|
mActivityInterface));
|
||||||
|
|
||||||
notifyGestureStartedAsync();
|
notifyGestureStartedAsync();
|
||||||
|
|||||||
+1
-1
@@ -140,7 +140,7 @@ public final class FallbackActivityInterface extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExitOverview(RecentsAnimationDeviceState deviceState, Runnable exitRunnable) {
|
public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) {
|
||||||
// no-op, fake landscape not supported for 3P
|
// no-op, fake landscape not supported for 3P
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -105,7 +105,7 @@ public final class LauncherActivityInterface extends
|
|||||||
// recents, we assume the first task is invisible, making translation off by one task.
|
// recents, we assume the first task is invisible, making translation off by one task.
|
||||||
launcher.getStateManager().reapplyState();
|
launcher.getStateManager().reapplyState();
|
||||||
launcher.getRootView().setForceHideBackArrow(false);
|
launcher.getRootView().setForceHideBackArrow(false);
|
||||||
notifyRecentsOfOrientation(deviceState);
|
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -120,7 +120,7 @@ public final class LauncherActivityInterface extends
|
|||||||
@Override
|
@Override
|
||||||
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
|
||||||
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
|
boolean activityVisible, Consumer<AnimatorPlaybackController> callback) {
|
||||||
notifyRecentsOfOrientation(deviceState);
|
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
|
||||||
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback) {
|
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback) {
|
||||||
@Override
|
@Override
|
||||||
public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator,
|
public void setShelfState(ShelfAnimState shelfState, Interpolator interpolator,
|
||||||
@@ -228,7 +228,7 @@ public final class LauncherActivityInterface extends
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onExitOverview(RecentsAnimationDeviceState deviceState, Runnable exitRunnable) {
|
public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) {
|
||||||
final StateManager<LauncherState> stateManager = getCreatedActivity().getStateManager();
|
final StateManager<LauncherState> stateManager = getCreatedActivity().getStateManager();
|
||||||
stateManager.addStateListener(
|
stateManager.addStateListener(
|
||||||
new StateManager.StateListener<LauncherState>() {
|
new StateManager.StateListener<LauncherState>() {
|
||||||
@@ -244,11 +244,11 @@ public final class LauncherActivityInterface extends
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyRecentsOfOrientation(RecentsAnimationDeviceState deviceState) {
|
private void notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper) {
|
||||||
// reset layout on swipe to home
|
// reset layout on swipe to home
|
||||||
RecentsView recentsView = getCreatedActivity().getOverviewPanel();
|
RecentsView recentsView = getCreatedActivity().getOverviewPanel();
|
||||||
recentsView.setLayoutRotation(deviceState.getCurrentActiveRotation(),
|
recentsView.setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(),
|
||||||
deviceState.getDisplayRotation());
|
rotationTouchHelper.getDisplayRotation());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ public abstract class SwipeUpAnimationLogic {
|
|||||||
mTransformParams = transformParams;
|
mTransformParams = transformParams;
|
||||||
|
|
||||||
mTaskViewSimulator.setLayoutRotation(
|
mTaskViewSimulator.setLayoutRotation(
|
||||||
mDeviceState.getCurrentActiveRotation(), mDeviceState.getDisplayRotation());
|
mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
|
||||||
|
mDeviceState.getRotationTouchHelper().getDisplayRotation());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||||
|
|||||||
+6
-4
@@ -258,6 +258,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
|
|
||||||
private static boolean sConnected = false;
|
private static boolean sConnected = false;
|
||||||
private static boolean sIsInitialized = false;
|
private static boolean sIsInitialized = false;
|
||||||
|
private RotationTouchHelper mRotationTouchHelper;
|
||||||
|
|
||||||
public static boolean isConnected() {
|
public static boolean isConnected() {
|
||||||
return sConnected;
|
return sConnected;
|
||||||
@@ -298,6 +299,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
mDeviceState = new RecentsAnimationDeviceState(this);
|
mDeviceState = new RecentsAnimationDeviceState(this);
|
||||||
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
|
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
|
||||||
mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
|
mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
|
||||||
|
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
|
||||||
ProtoTracer.INSTANCE.get(this).add(this);
|
ProtoTracer.INSTANCE.get(this).add(this);
|
||||||
|
|
||||||
sConnected = true;
|
sConnected = true;
|
||||||
@@ -326,7 +328,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
|
mInputEventReceiver = mInputMonitorCompat.getInputReceiver(Looper.getMainLooper(),
|
||||||
mMainChoreographer, this::onInputEvent);
|
mMainChoreographer, this::onInputEvent);
|
||||||
|
|
||||||
mDeviceState.updateGestureTouchRegions();
|
mRotationTouchHelper.updateGestureTouchRegions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -470,9 +472,9 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
if (TestProtocol.sDebugTracing) {
|
if (TestProtocol.sDebugTracing) {
|
||||||
Log.d(TestProtocol.NO_SWIPE_TO_HOME, "TouchInteractionService.onInputEvent:DOWN");
|
Log.d(TestProtocol.NO_SWIPE_TO_HOME, "TouchInteractionService.onInputEvent:DOWN");
|
||||||
}
|
}
|
||||||
mDeviceState.setOrientationTransformIfNeeded(event);
|
mRotationTouchHelper.setOrientationTransformIfNeeded(event);
|
||||||
|
|
||||||
if (mDeviceState.isInSwipeUpTouchRegion(event)) {
|
if (mRotationTouchHelper.isInSwipeUpTouchRegion(event)) {
|
||||||
if (TestProtocol.sDebugTracing) {
|
if (TestProtocol.sDebugTracing) {
|
||||||
Log.d(TestProtocol.NO_SWIPE_TO_HOME,
|
Log.d(TestProtocol.NO_SWIPE_TO_HOME,
|
||||||
"TouchInteractionService.onInputEvent:isInSwipeUpTouchRegion");
|
"TouchInteractionService.onInputEvent:isInSwipeUpTouchRegion");
|
||||||
@@ -509,7 +511,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
|||||||
// Other events
|
// Other events
|
||||||
if (mUncheckedConsumer != InputConsumer.NO_OP) {
|
if (mUncheckedConsumer != InputConsumer.NO_OP) {
|
||||||
// Only transform the event if we are handling it in a proper consumer
|
// Only transform the event if we are handling it in a proper consumer
|
||||||
mDeviceState.setOrientationTransformIfNeeded(event);
|
mRotationTouchHelper.setOrientationTransformIfNeeded(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -99,7 +99,8 @@ public class AccessibilityInputConsumer extends DelegateInputConsumer {
|
|||||||
case ACTION_POINTER_DOWN: {
|
case ACTION_POINTER_DOWN: {
|
||||||
if (mState == STATE_INACTIVE) {
|
if (mState == STATE_INACTIVE) {
|
||||||
int pointerIndex = ev.getActionIndex();
|
int pointerIndex = ev.getActionIndex();
|
||||||
if (mDeviceState.isInSwipeUpTouchRegion(ev, pointerIndex)
|
if (mDeviceState.getRotationTouchHelper()
|
||||||
|
.isInSwipeUpTouchRegion(ev, pointerIndex)
|
||||||
&& mDelegate.allowInterceptByParent()) {
|
&& mDelegate.allowInterceptByParent()) {
|
||||||
setActive(ev);
|
setActive(ev);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -147,7 +147,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
|
|||||||
if (!mThresholdCrossed) {
|
if (!mThresholdCrossed) {
|
||||||
// Cancel interaction in case of multi-touch interaction
|
// Cancel interaction in case of multi-touch interaction
|
||||||
int ptrIdx = ev.getActionIndex();
|
int ptrIdx = ev.getActionIndex();
|
||||||
if (!mDeviceState.isInSwipeUpTouchRegion(ev, ptrIdx)) {
|
if (!mDeviceState.getRotationTouchHelper().isInSwipeUpTouchRegion(ev, ptrIdx)) {
|
||||||
int action = ev.getAction();
|
int action = ev.getAction();
|
||||||
ev.setAction(ACTION_CANCEL);
|
ev.setAction(ACTION_CANCEL);
|
||||||
finishTouchTracking(ev);
|
finishTouchTracking(ev);
|
||||||
|
|||||||
+5
-2
@@ -59,6 +59,7 @@ import com.android.quickstep.GestureState;
|
|||||||
import com.android.quickstep.InputConsumer;
|
import com.android.quickstep.InputConsumer;
|
||||||
import com.android.quickstep.RecentsAnimationCallbacks;
|
import com.android.quickstep.RecentsAnimationCallbacks;
|
||||||
import com.android.quickstep.RecentsAnimationDeviceState;
|
import com.android.quickstep.RecentsAnimationDeviceState;
|
||||||
|
import com.android.quickstep.RotationTouchHelper;
|
||||||
import com.android.quickstep.TaskAnimationManager;
|
import com.android.quickstep.TaskAnimationManager;
|
||||||
import com.android.quickstep.util.ActiveGestureLog;
|
import com.android.quickstep.util.ActiveGestureLog;
|
||||||
import com.android.quickstep.util.CachedEventDispatcher;
|
import com.android.quickstep.util.CachedEventDispatcher;
|
||||||
@@ -86,6 +87,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
|||||||
private final NavBarPosition mNavBarPosition;
|
private final NavBarPosition mNavBarPosition;
|
||||||
private final TaskAnimationManager mTaskAnimationManager;
|
private final TaskAnimationManager mTaskAnimationManager;
|
||||||
private final GestureState mGestureState;
|
private final GestureState mGestureState;
|
||||||
|
private final RotationTouchHelper mRotationTouchHelper;
|
||||||
private RecentsAnimationCallbacks mActiveCallbacks;
|
private RecentsAnimationCallbacks mActiveCallbacks;
|
||||||
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
|
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
|
||||||
private final InputMonitorCompat mInputMonitorCompat;
|
private final InputMonitorCompat mInputMonitorCompat;
|
||||||
@@ -163,6 +165,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
|||||||
|
|
||||||
mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;
|
mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;
|
||||||
mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe;
|
mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe;
|
||||||
|
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -230,7 +233,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
|||||||
if (!mPassedPilferInputSlop) {
|
if (!mPassedPilferInputSlop) {
|
||||||
// Cancel interaction in case of multi-touch interaction
|
// Cancel interaction in case of multi-touch interaction
|
||||||
int ptrIdx = ev.getActionIndex();
|
int ptrIdx = ev.getActionIndex();
|
||||||
if (!mDeviceState.isInSwipeUpTouchRegion(ev, ptrIdx)) {
|
if (!mRotationTouchHelper.isInSwipeUpTouchRegion(ev, ptrIdx)) {
|
||||||
forceCancelGesture(ev);
|
forceCancelGesture(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,7 +427,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyOrientationSetup() {
|
public void notifyOrientationSetup() {
|
||||||
mDeviceState.onStartGesture();
|
mRotationTouchHelper.onStartGesture();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
|||||||
return deviceState.isInDeferredGestureRegion(ev);
|
return deviceState.isInDeferredGestureRegion(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onExitOverview(RecentsAnimationDeviceState deviceState,
|
public abstract void onExitOverview(RotationTouchHelper deviceState,
|
||||||
Runnable exitRunnable);
|
Runnable exitRunnable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,11 +16,9 @@
|
|||||||
package com.android.quickstep;
|
package com.android.quickstep;
|
||||||
|
|
||||||
import static android.content.Intent.ACTION_USER_UNLOCKED;
|
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_ALL;
|
||||||
import static com.android.launcher3.util.DefaultDisplay.CHANGE_FRAME_DELAY;
|
import static com.android.launcher3.util.DefaultDisplay.CHANGE_FRAME_DELAY;
|
||||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
|
||||||
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||||
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
|
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
|
||||||
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
|
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
|
||||||
@@ -49,23 +47,19 @@ import android.os.UserManager;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.OrientationEventListener;
|
|
||||||
|
|
||||||
import androidx.annotation.BinderThread;
|
import androidx.annotation.BinderThread;
|
||||||
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.testing.TestProtocol;
|
|
||||||
import com.android.launcher3.util.DefaultDisplay;
|
import com.android.launcher3.util.DefaultDisplay;
|
||||||
import com.android.launcher3.util.SecureSettingsObserver;
|
import com.android.launcher3.util.SecureSettingsObserver;
|
||||||
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
|
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
|
||||||
import com.android.quickstep.util.NavBarPosition;
|
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.ActivityManagerWrapper;
|
||||||
import com.android.systemui.shared.system.QuickStepContract;
|
import com.android.systemui.shared.system.QuickStepContract;
|
||||||
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
|
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
|
||||||
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
|
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
|
||||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -83,7 +77,7 @@ public class RecentsAnimationDeviceState implements
|
|||||||
private final SysUINavigationMode mSysUiNavMode;
|
private final SysUINavigationMode mSysUiNavMode;
|
||||||
private final DefaultDisplay mDefaultDisplay;
|
private final DefaultDisplay mDefaultDisplay;
|
||||||
private final int mDisplayId;
|
private final int mDisplayId;
|
||||||
private int mDisplayRotation;
|
private final RotationTouchHelper mRotationTouchHelper;
|
||||||
|
|
||||||
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
|
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
|
||||||
|
|
||||||
@@ -107,76 +101,10 @@ public class RecentsAnimationDeviceState implements
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private TaskStackChangeListener mFrozenTaskListener = new TaskStackChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onRecentTaskListFrozenChanged(boolean frozen) {
|
|
||||||
mTaskListFrozen = frozen;
|
|
||||||
if (frozen || mInOverview) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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 mSensorRotation = 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 Region mExclusionRegion;
|
||||||
private SystemGestureExclusionListenerCompat mExclusionListener;
|
private SystemGestureExclusionListenerCompat mExclusionListener;
|
||||||
|
|
||||||
private final List<ComponentName> mGestureBlockedActivities;
|
private final List<ComponentName> mGestureBlockedActivities;
|
||||||
private Runnable mOnDestroyFrozenTaskRunnable;
|
|
||||||
/**
|
|
||||||
* Set to true when user swipes to recents. In recents, we ignore the state of the recents
|
|
||||||
* task list being frozen or not to allow the user to keep interacting with nav bar rotation
|
|
||||||
* they went into recents with as opposed to defaulting to the default display rotation.
|
|
||||||
* TODO: (b/156984037) For when user rotates after entering overview
|
|
||||||
*/
|
|
||||||
private boolean mInOverview;
|
|
||||||
private boolean mTaskListFrozen;
|
|
||||||
|
|
||||||
private boolean mIsUserSetupComplete;
|
private boolean mIsUserSetupComplete;
|
||||||
|
|
||||||
@@ -186,6 +114,8 @@ public class RecentsAnimationDeviceState implements
|
|||||||
mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
|
mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
|
||||||
mDisplayId = mDefaultDisplay.getInfo().id;
|
mDisplayId = mDefaultDisplay.getInfo().id;
|
||||||
runOnDestroy(() -> mDefaultDisplay.removeChangeListener(this));
|
runOnDestroy(() -> mDefaultDisplay.removeChangeListener(this));
|
||||||
|
mRotationTouchHelper = RotationTouchHelper.INSTANCE.get(context);
|
||||||
|
runOnDestroy(mRotationTouchHelper::destroy);
|
||||||
|
|
||||||
// Register for user unlocked if necessary
|
// Register for user unlocked if necessary
|
||||||
mIsUserUnlocked = context.getSystemService(UserManager.class)
|
mIsUserUnlocked = context.getSystemService(UserManager.class)
|
||||||
@@ -207,10 +137,6 @@ public class RecentsAnimationDeviceState implements
|
|||||||
};
|
};
|
||||||
runOnDestroy(mExclusionListener::unregister);
|
runOnDestroy(mExclusionListener::unregister);
|
||||||
|
|
||||||
Resources resources = mContext.getResources();
|
|
||||||
mOrientationTouchTransformer = new OrientationTouchTransformer(resources, mMode,
|
|
||||||
() -> QuickStepContract.getWindowCornerRadius(resources));
|
|
||||||
|
|
||||||
// Register for navigation mode changes
|
// Register for navigation mode changes
|
||||||
onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
|
onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
|
||||||
runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
|
runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
|
||||||
@@ -241,38 +167,6 @@ public class RecentsAnimationDeviceState implements
|
|||||||
userSetupObserver.register();
|
userSetupObserver.register();
|
||||||
runOnDestroy(userSetupObserver::unregister);
|
runOnDestroy(userSetupObserver::unregister);
|
||||||
}
|
}
|
||||||
|
|
||||||
mOrientationListener = new OrientationEventListener(context) {
|
|
||||||
@Override
|
|
||||||
public void onOrientationChanged(int degrees) {
|
|
||||||
int newRotation = RecentsOrientedState.getRotationForUserDegreesRotated(degrees,
|
|
||||||
mSensorRotation);
|
|
||||||
if (newRotation == mSensorRotation) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mSensorRotation = newRotation;
|
|
||||||
mPrioritizeDeviceRotation = true;
|
|
||||||
|
|
||||||
if (newRotation == mCurrentAppRotation) {
|
|
||||||
// When user rotates device to the orientation of the foreground app after
|
|
||||||
// quickstepping
|
|
||||||
toggleSecondaryNavBarsForRotation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupOrientationSwipeHandler() {
|
|
||||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(mFrozenTaskListener);
|
|
||||||
mOnDestroyFrozenTaskRunnable = () -> ActivityManagerWrapper.getInstance()
|
|
||||||
.unregisterTaskStackListener(mFrozenTaskListener);
|
|
||||||
runOnDestroy(mOnDestroyFrozenTaskRunnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void destroyOrientationSwipeHandlerCallback() {
|
|
||||||
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mFrozenTaskListener);
|
|
||||||
mOnDestroyActions.remove(mOnDestroyFrozenTaskRunnable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runOnDestroy(Runnable action) {
|
private void runOnDestroy(Runnable action) {
|
||||||
@@ -311,13 +205,6 @@ public class RecentsAnimationDeviceState implements
|
|||||||
|
|
||||||
mNavBarPosition = new NavBarPosition(newMode, mDefaultDisplay.getInfo());
|
mNavBarPosition = new NavBarPosition(newMode, mDefaultDisplay.getInfo());
|
||||||
|
|
||||||
mOrientationTouchTransformer.setNavigationMode(newMode, mDefaultDisplay.getInfo());
|
|
||||||
if (!mMode.hasGestures && newMode.hasGestures) {
|
|
||||||
setupOrientationSwipeHandler();
|
|
||||||
} else if (mMode.hasGestures && !newMode.hasGestures){
|
|
||||||
destroyOrientationSwipeHandlerCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
mMode = newMode;
|
mMode = newMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,28 +215,10 @@ public class RecentsAnimationDeviceState implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDisplayRotation = info.rotation;
|
|
||||||
|
|
||||||
if (!mMode.hasGestures) {
|
if (!mMode.hasGestures) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mNavBarPosition = new NavBarPosition(mMode, info);
|
mNavBarPosition = new NavBarPosition(mMode, info);
|
||||||
updateGestureTouchRegions();
|
|
||||||
mOrientationTouchTransformer.createOrAddTouchRegion(info);
|
|
||||||
mCurrentAppRotation = mDisplayRotation;
|
|
||||||
|
|
||||||
/* Update nav bars on the following:
|
|
||||||
* a) if this is coming from an activity rotation OR
|
|
||||||
* aa) we launch an app in the orientation that user is already in
|
|
||||||
* b) We're not in overview, since overview will always be portrait (w/o home rotation)
|
|
||||||
* c) We're actively in quickswitch mode
|
|
||||||
*/
|
|
||||||
if ((mPrioritizeDeviceRotation
|
|
||||||
|| mCurrentAppRotation == mSensorRotation) // switch to an app of orientation user is in
|
|
||||||
&& !mInOverview
|
|
||||||
&& mTaskListFrozen) {
|
|
||||||
toggleSecondaryNavBarsForRotation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -464,7 +333,7 @@ public class RecentsAnimationDeviceState implements
|
|||||||
*/
|
*/
|
||||||
public boolean canStartSystemGesture() {
|
public boolean canStartSystemGesture() {
|
||||||
boolean canStartWithNavHidden = (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
|
boolean canStartWithNavHidden = (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
|
||||||
|| mTaskListFrozen;
|
|| mRotationTouchHelper.isTaskListFrozen();
|
||||||
return canStartWithNavHidden
|
return canStartWithNavHidden
|
||||||
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
|
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
|
||||||
&& (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
|
&& (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
|
||||||
@@ -536,33 +405,6 @@ public class RecentsAnimationDeviceState implements
|
|||||||
return (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
|
return (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the regions for detecting the swipe up/quickswitch and assistant gestures.
|
|
||||||
*/
|
|
||||||
public void updateGestureTouchRegions() {
|
|
||||||
if (!mMode.hasGestures) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mOrientationTouchTransformer.createOrAddTouchRegion(mDefaultDisplay.getInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return whether the coordinates of the {@param event} is in the swipe up gesture region.
|
|
||||||
*/
|
|
||||||
public boolean isInSwipeUpTouchRegion(MotionEvent event) {
|
|
||||||
return mOrientationTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return whether the coordinates of the {@param event} with the given {@param pointerIndex}
|
|
||||||
* is in the swipe up gesture region.
|
|
||||||
*/
|
|
||||||
public boolean isInSwipeUpTouchRegion(MotionEvent event, int pointerIndex) {
|
|
||||||
return mOrientationTouchTransformer.touchInValidSwipeRegions(event.getX(pointerIndex),
|
|
||||||
event.getY(pointerIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the region in screen space where the gestures should be deferred (ie. due to specific
|
* Sets the region in screen space where the gestures should be deferred (ie. due to specific
|
||||||
* nav bar ui).
|
* nav bar ui).
|
||||||
@@ -620,101 +462,13 @@ public class RecentsAnimationDeviceState implements
|
|||||||
public boolean canTriggerAssistantAction(MotionEvent ev, ActivityManager.RunningTaskInfo task) {
|
public boolean canTriggerAssistantAction(MotionEvent ev, ActivityManager.RunningTaskInfo task) {
|
||||||
return mAssistantAvailable
|
return mAssistantAvailable
|
||||||
&& !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
|
&& !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
|
||||||
&& mOrientationTouchTransformer.touchInAssistantRegion(ev)
|
&& mRotationTouchHelper.touchInAssistantRegion(ev)
|
||||||
&& !isLockToAppActive()
|
&& !isLockToAppActive()
|
||||||
&& !isGestureBlockedActivity(task);
|
&& !isGestureBlockedActivity(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public RotationTouchHelper getRotationTouchHelper() {
|
||||||
* *May* apply a transform on the motion event if it lies in the nav bar region for another
|
return mRotationTouchHelper;
|
||||||
* orientation that is currently being tracked as a part of quickstep
|
|
||||||
*/
|
|
||||||
void setOrientationTransformIfNeeded(MotionEvent event) {
|
|
||||||
// negative coordinates bug b/143901881
|
|
||||||
if (event.getX() < 0 || event.getY() < 0) {
|
|
||||||
event.setLocation(Math.max(0, event.getX()), Math.max(0, event.getY()));
|
|
||||||
}
|
|
||||||
mOrientationTouchTransformer.transform(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enableMultipleRegions(boolean enable) {
|
|
||||||
mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
|
|
||||||
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
|
|
||||||
if (enable && !mInOverview && !TestProtocol.sDisableSensorRotation) {
|
|
||||||
// Clear any previous state from sensor manager
|
|
||||||
mSensorRotation = mCurrentAppRotation;
|
|
||||||
mOrientationListener.enable();
|
|
||||||
} else {
|
|
||||||
mOrientationListener.disable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onStartGesture() {
|
|
||||||
if (mTaskListFrozen) {
|
|
||||||
// Prioritize whatever nav bar user touches once in quickstep
|
|
||||||
// This case is specifically when user changes what nav bar they are using mid
|
|
||||||
// quickswitch session before tasks list is unfrozen
|
|
||||||
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void onEndTargetCalculated(GestureState.GestureEndTarget endTarget,
|
|
||||||
BaseActivityInterface activityInterface) {
|
|
||||||
if (endTarget == GestureState.GestureEndTarget.RECENTS) {
|
|
||||||
mInOverview = true;
|
|
||||||
if (!mTaskListFrozen) {
|
|
||||||
// If we're in landscape w/o ever quickswitching, show the navbar in landscape
|
|
||||||
enableMultipleRegions(true);
|
|
||||||
}
|
|
||||||
activityInterface.onExitOverview(this, mExitOverviewRunnable);
|
|
||||||
} else if (endTarget == GestureState.GestureEndTarget.HOME) {
|
|
||||||
enableMultipleRegions(false);
|
|
||||||
} else if (endTarget == GestureState.GestureEndTarget.NEW_TASK) {
|
|
||||||
if (mOrientationTouchTransformer.getQuickStepStartingRotation() == -1) {
|
|
||||||
// First gesture to start quickswitch
|
|
||||||
enableMultipleRegions(true);
|
|
||||||
} else {
|
|
||||||
notifySysuiOfCurrentRotation(
|
|
||||||
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
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.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
|
|
||||||
*/
|
|
||||||
private void toggleSecondaryNavBarsForRotation() {
|
|
||||||
mOrientationTouchTransformer.setSingleActiveRegion(mDefaultDisplay.getInfo());
|
|
||||||
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentActiveRotation() {
|
|
||||||
if (!mMode.hasGestures) {
|
|
||||||
// touch rotation should always match that of display for 3 button
|
|
||||||
return mDisplayRotation;
|
|
||||||
}
|
|
||||||
return mOrientationTouchTransformer.getCurrentActiveRotation();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDisplayRotation() {
|
|
||||||
return mDisplayRotation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dump(PrintWriter pw) {
|
public void dump(PrintWriter pw) {
|
||||||
@@ -726,9 +480,7 @@ public class RecentsAnimationDeviceState implements
|
|||||||
pw.println(" assistantAvailable=" + mAssistantAvailable);
|
pw.println(" assistantAvailable=" + mAssistantAvailable);
|
||||||
pw.println(" assistantDisabled="
|
pw.println(" assistantDisabled="
|
||||||
+ QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
|
+ QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
|
||||||
pw.println(" currentActiveRotation=" + getCurrentActiveRotation());
|
|
||||||
pw.println(" displayRotation=" + getDisplayRotation());
|
|
||||||
pw.println(" isUserUnlocked=" + mIsUserUnlocked);
|
pw.println(" isUserUnlocked=" + mIsUserUnlocked);
|
||||||
mOrientationTouchTransformer.dump(pw);
|
mRotationTouchHelper.dump(pw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,365 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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.quickstep;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||||
|
import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.OrientationEventListener;
|
||||||
|
|
||||||
|
import com.android.launcher3.testing.TestProtocol;
|
||||||
|
import com.android.launcher3.util.DefaultDisplay;
|
||||||
|
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||||
|
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.TaskStackChangeListener;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class RotationTouchHelper implements
|
||||||
|
SysUINavigationMode.NavigationModeChangeListener,
|
||||||
|
DefaultDisplay.DisplayInfoChangeListener {
|
||||||
|
public static final MainThreadInitializedObject<RotationTouchHelper> INSTANCE =
|
||||||
|
new MainThreadInitializedObject<>(RotationTouchHelper::new);
|
||||||
|
|
||||||
|
private final OrientationTouchTransformer mOrientationTouchTransformer;
|
||||||
|
private final DefaultDisplay mDefaultDisplay;
|
||||||
|
private final SysUINavigationMode mSysUiNavMode;
|
||||||
|
private final int mDisplayId;
|
||||||
|
private int mDisplayRotation;
|
||||||
|
|
||||||
|
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
|
||||||
|
|
||||||
|
private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
|
||||||
|
|
||||||
|
private TaskStackChangeListener mFrozenTaskListener = new TaskStackChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onRecentTaskListFrozenChanged(boolean frozen) {
|
||||||
|
mTaskListFrozen = frozen;
|
||||||
|
if (frozen || mInOverview) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 mSensorRotation = 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 Runnable mOnDestroyFrozenTaskRunnable;
|
||||||
|
/**
|
||||||
|
* Set to true when user swipes to recents. In recents, we ignore the state of the recents
|
||||||
|
* task list being frozen or not to allow the user to keep interacting with nav bar rotation
|
||||||
|
* they went into recents with as opposed to defaulting to the default display rotation.
|
||||||
|
* TODO: (b/156984037) For when user rotates after entering overview
|
||||||
|
*/
|
||||||
|
private boolean mInOverview;
|
||||||
|
private boolean mTaskListFrozen;
|
||||||
|
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
|
private RotationTouchHelper(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
Resources resources = mContext.getResources();
|
||||||
|
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
|
||||||
|
mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
|
||||||
|
mDisplayId = mDefaultDisplay.getInfo().id;
|
||||||
|
|
||||||
|
mOrientationTouchTransformer = new OrientationTouchTransformer(resources, mMode,
|
||||||
|
() -> QuickStepContract.getWindowCornerRadius(resources));
|
||||||
|
|
||||||
|
// Register for navigation mode changes
|
||||||
|
onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
|
||||||
|
runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
|
||||||
|
|
||||||
|
mOrientationListener = new OrientationEventListener(context) {
|
||||||
|
@Override
|
||||||
|
public void onOrientationChanged(int degrees) {
|
||||||
|
int newRotation = RecentsOrientedState.getRotationForUserDegreesRotated(degrees,
|
||||||
|
mSensorRotation);
|
||||||
|
if (newRotation == mSensorRotation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSensorRotation = newRotation;
|
||||||
|
mPrioritizeDeviceRotation = true;
|
||||||
|
|
||||||
|
if (newRotation == mCurrentAppRotation) {
|
||||||
|
// When user rotates device to the orientation of the foreground app after
|
||||||
|
// quickstepping
|
||||||
|
toggleSecondaryNavBarsForRotation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupOrientationSwipeHandler() {
|
||||||
|
ActivityManagerWrapper.getInstance().registerTaskStackListener(mFrozenTaskListener);
|
||||||
|
mOnDestroyFrozenTaskRunnable = () -> ActivityManagerWrapper.getInstance()
|
||||||
|
.unregisterTaskStackListener(mFrozenTaskListener);
|
||||||
|
runOnDestroy(mOnDestroyFrozenTaskRunnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void destroyOrientationSwipeHandlerCallback() {
|
||||||
|
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mFrozenTaskListener);
|
||||||
|
mOnDestroyActions.remove(mOnDestroyFrozenTaskRunnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runOnDestroy(Runnable action) {
|
||||||
|
mOnDestroyActions.add(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up all the registered listeners and receivers.
|
||||||
|
*/
|
||||||
|
public void destroy() {
|
||||||
|
for (Runnable r : mOnDestroyActions) {
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTaskListFrozen() {
|
||||||
|
return mTaskListFrozen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean touchInAssistantRegion(MotionEvent ev) {
|
||||||
|
return mOrientationTouchTransformer.touchInAssistantRegion(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the regions for detecting the swipe up/quickswitch and assistant gestures.
|
||||||
|
*/
|
||||||
|
public void updateGestureTouchRegions() {
|
||||||
|
if (!mMode.hasGestures) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mOrientationTouchTransformer.createOrAddTouchRegion(mDefaultDisplay.getInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether the coordinates of the {@param event} is in the swipe up gesture region.
|
||||||
|
*/
|
||||||
|
public boolean isInSwipeUpTouchRegion(MotionEvent event) {
|
||||||
|
return mOrientationTouchTransformer.touchInValidSwipeRegions(event.getX(), event.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether the coordinates of the {@param event} with the given {@param pointerIndex}
|
||||||
|
* is in the swipe up gesture region.
|
||||||
|
*/
|
||||||
|
public boolean isInSwipeUpTouchRegion(MotionEvent event, int pointerIndex) {
|
||||||
|
return mOrientationTouchTransformer.touchInValidSwipeRegions(event.getX(pointerIndex),
|
||||||
|
event.getY(pointerIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
|
||||||
|
mDefaultDisplay.removeChangeListener(this);
|
||||||
|
mDefaultDisplay.addChangeListener(this);
|
||||||
|
onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
|
||||||
|
|
||||||
|
mOrientationTouchTransformer.setNavigationMode(newMode, mDefaultDisplay.getInfo());
|
||||||
|
if (!mMode.hasGestures && newMode.hasGestures) {
|
||||||
|
setupOrientationSwipeHandler();
|
||||||
|
} else if (mMode.hasGestures && !newMode.hasGestures){
|
||||||
|
destroyOrientationSwipeHandlerCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
mMode = newMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDisplayRotation() {
|
||||||
|
return mDisplayRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
|
||||||
|
if (info.id != mDisplayId|| flags == CHANGE_FRAME_DELAY) {
|
||||||
|
// ignore displays that aren't running launcher and frame refresh rate changes
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mDisplayRotation = info.rotation;
|
||||||
|
|
||||||
|
if (!mMode.hasGestures) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateGestureTouchRegions();
|
||||||
|
mOrientationTouchTransformer.createOrAddTouchRegion(info);
|
||||||
|
mCurrentAppRotation = mDisplayRotation;
|
||||||
|
|
||||||
|
/* Update nav bars on the following:
|
||||||
|
* a) if this is coming from an activity rotation OR
|
||||||
|
* aa) we launch an app in the orientation that user is already in
|
||||||
|
* b) We're not in overview, since overview will always be portrait (w/o home rotation)
|
||||||
|
* c) We're actively in quickswitch mode
|
||||||
|
*/
|
||||||
|
if ((mPrioritizeDeviceRotation
|
||||||
|
|| mCurrentAppRotation == mSensorRotation) // switch to an app of orientation user is in
|
||||||
|
&& !mInOverview
|
||||||
|
&& mTaskListFrozen) {
|
||||||
|
toggleSecondaryNavBarsForRotation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *May* apply a transform on the motion event if it lies in the nav bar region for another
|
||||||
|
* orientation that is currently being tracked as a part of quickstep
|
||||||
|
*/
|
||||||
|
void setOrientationTransformIfNeeded(MotionEvent event) {
|
||||||
|
// negative coordinates bug b/143901881
|
||||||
|
if (event.getX() < 0 || event.getY() < 0) {
|
||||||
|
event.setLocation(Math.max(0, event.getX()), Math.max(0, event.getY()));
|
||||||
|
}
|
||||||
|
mOrientationTouchTransformer.transform(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableMultipleRegions(boolean enable) {
|
||||||
|
mOrientationTouchTransformer.enableMultipleRegions(enable, mDefaultDisplay.getInfo());
|
||||||
|
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getQuickStepStartingRotation());
|
||||||
|
if (enable && !mInOverview && !TestProtocol.sDisableSensorRotation) {
|
||||||
|
// Clear any previous state from sensor manager
|
||||||
|
mSensorRotation = mCurrentAppRotation;
|
||||||
|
mOrientationListener.enable();
|
||||||
|
} else {
|
||||||
|
mOrientationListener.disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStartGesture() {
|
||||||
|
if (mTaskListFrozen) {
|
||||||
|
// Prioritize whatever nav bar user touches once in quickstep
|
||||||
|
// This case is specifically when user changes what nav bar they are using mid
|
||||||
|
// quickswitch session before tasks list is unfrozen
|
||||||
|
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onEndTargetCalculated(GestureState.GestureEndTarget endTarget,
|
||||||
|
BaseActivityInterface activityInterface) {
|
||||||
|
if (endTarget == GestureState.GestureEndTarget.RECENTS) {
|
||||||
|
mInOverview = true;
|
||||||
|
if (!mTaskListFrozen) {
|
||||||
|
// If we're in landscape w/o ever quickswitching, show the navbar in landscape
|
||||||
|
enableMultipleRegions(true);
|
||||||
|
}
|
||||||
|
activityInterface.onExitOverview(this, mExitOverviewRunnable);
|
||||||
|
} else if (endTarget == GestureState.GestureEndTarget.HOME) {
|
||||||
|
enableMultipleRegions(false);
|
||||||
|
} else if (endTarget == GestureState.GestureEndTarget.NEW_TASK) {
|
||||||
|
if (mOrientationTouchTransformer.getQuickStepStartingRotation() == -1) {
|
||||||
|
// First gesture to start quickswitch
|
||||||
|
enableMultipleRegions(true);
|
||||||
|
} else {
|
||||||
|
notifySysuiOfCurrentRotation(
|
||||||
|
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
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.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
|
||||||
|
*/
|
||||||
|
private void toggleSecondaryNavBarsForRotation() {
|
||||||
|
mOrientationTouchTransformer.setSingleActiveRegion(mDefaultDisplay.getInfo());
|
||||||
|
notifySysuiOfCurrentRotation(mOrientationTouchTransformer.getCurrentActiveRotation());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentActiveRotation() {
|
||||||
|
if (!mMode.hasGestures) {
|
||||||
|
// touch rotation should always match that of display for 3 button
|
||||||
|
return mDisplayRotation;
|
||||||
|
}
|
||||||
|
return mOrientationTouchTransformer.getCurrentActiveRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dump(PrintWriter pw) {
|
||||||
|
pw.println("RotationTouchHelper:");
|
||||||
|
pw.println(" currentActiveRotation=" + getCurrentActiveRotation());
|
||||||
|
pw.println(" displayRotation=" + getDisplayRotation());
|
||||||
|
mOrientationTouchTransformer.dump(pw);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user