blob: 0a70bd6cfef06383a34d724b62b3a816e9d72fad [file] [log] [blame]
/*
* Copyright (C) 2019 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.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;
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.THREE_BUTTONS;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.Region;
import android.os.Process;
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;
import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Manages the state of the system during a swipe up gesture.
*/
public class RecentsAnimationDeviceState implements
NavigationModeChangeListener,
DefaultDisplay.DisplayInfoChangeListener {
private final Context mContext;
private final SysUINavigationMode mSysUiNavMode;
private final DefaultDisplay mDefaultDisplay;
private final int mDisplayId;
private int mDisplayRotation;
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
private @SystemUiStateFlags int mSystemUiStateFlags;
private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
private NavBarPosition mNavBarPosition;
private final Region mDeferredGestureRegion = new Region();
private boolean mAssistantAvailable;
private float mAssistantVisibility;
private boolean mIsUserUnlocked;
private final ArrayList<Runnable> mUserUnlockedActions = new ArrayList<>();
private final BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_USER_UNLOCKED.equals(intent.getAction())) {
mIsUserUnlocked = true;
notifyUserUnlocked();
}
}
};
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 SystemGestureExclusionListenerCompat mExclusionListener;
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;
public RecentsAnimationDeviceState(Context context) {
mContext = context;
mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
mDefaultDisplay = DefaultDisplay.INSTANCE.get(context);
mDisplayId = mDefaultDisplay.getInfo().id;
runOnDestroy(() -> mDefaultDisplay.removeChangeListener(this));
// Register for user unlocked if necessary
mIsUserUnlocked = context.getSystemService(UserManager.class)
.isUserUnlocked(Process.myUserHandle());
if (!mIsUserUnlocked) {
mContext.registerReceiver(mUserUnlockedReceiver,
new IntentFilter(ACTION_USER_UNLOCKED));
}
runOnDestroy(() -> Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver));
// Register for exclusion updates
mExclusionListener = new SystemGestureExclusionListenerCompat(mDisplayId) {
@Override
@BinderThread
public void onExclusionChanged(Region region) {
// Assignments are atomic, it should be safe on binder thread
mExclusionRegion = region;
}
};
runOnDestroy(mExclusionListener::unregister);
Resources resources = mContext.getResources();
mOrientationTouchTransformer = new OrientationTouchTransformer(resources, mMode,
() -> QuickStepContract.getWindowCornerRadius(resources));
// Register for navigation mode changes
onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
// Add any blocked activities
String[] blockingActivities;
try {
blockingActivities =
context.getResources().getStringArray(R.array.gesture_blocking_activities);
} catch (Resources.NotFoundException e) {
blockingActivities = new String[0];
}
mGestureBlockedActivities = new ArrayList<>(blockingActivities.length);
for (String blockingActivity : blockingActivities) {
if (!TextUtils.isEmpty(blockingActivity)) {
mGestureBlockedActivities.add(
ComponentName.unflattenFromString(blockingActivity));
}
}
SecureSettingsObserver userSetupObserver = new SecureSettingsObserver(
context.getContentResolver(),
e -> mIsUserSetupComplete = e,
Settings.Secure.USER_SETUP_COMPLETE,
0);
mIsUserSetupComplete = userSetupObserver.getValue();
if (!mIsUserSetupComplete) {
userSetupObserver.register();
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) {
mOnDestroyActions.add(action);
}
/**
* Cleans up all the registered listeners and receivers.
*/
public void destroy() {
for (Runnable r : mOnDestroyActions) {
r.run();
}
}
/**
* Adds a listener for the nav mode change, guaranteed to be called after the device state's
* mode has changed.
*/
public void addNavigationModeChangedCallback(NavigationModeChangeListener listener) {
listener.onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(listener));
runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(listener));
}
@Override
public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
mDefaultDisplay.removeChangeListener(this);
mDefaultDisplay.addChangeListener(this);
onDisplayInfoChanged(mDefaultDisplay.getInfo(), CHANGE_ALL);
if (newMode == NO_BUTTON) {
mExclusionListener.register();
} else {
mExclusionListener.unregister();
}
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;
}
@Override
public void onDisplayInfoChanged(DefaultDisplay.Info info, int flags) {
if (info.id != getDisplayId() || flags == CHANGE_FRAME_DELAY) {
// ignore displays that aren't running launcher and frame refresh rate changes
return;
}
mDisplayRotation = info.rotation;
if (!mMode.hasGestures) {
return;
}
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();
}
}
/**
* @return the current navigation mode for the device.
*/
public SysUINavigationMode.Mode getNavMode() {
return mMode;
}
/**
* @return the nav bar position for the current nav bar mode and display rotation.
*/
public NavBarPosition getNavBarPosition() {
return mNavBarPosition;
}
/**
* @return whether the current nav mode is fully gestural.
*/
public boolean isFullyGesturalNavMode() {
return mMode == NO_BUTTON;
}
/**
* @return whether the current nav mode has some gestures (either 2 or 0 button mode).
*/
public boolean isGesturalNavMode() {
return mMode == TWO_BUTTONS || mMode == NO_BUTTON;
}
/**
* @return whether the current nav mode is button-based.
*/
public boolean isButtonNavMode() {
return mMode == THREE_BUTTONS;
}
/**
* @return the display id for the display that Launcher is running on.
*/
public int getDisplayId() {
return mDisplayId;
}
/**
* Adds a callback for when a user is unlocked. If the user is already unlocked, this listener
* will be called back immediately.
*/
public void runOnUserUnlocked(Runnable action) {
if (mIsUserUnlocked) {
action.run();
} else {
mUserUnlockedActions.add(action);
}
}
/**
* @return whether the user is unlocked.
*/
public boolean isUserUnlocked() {
return mIsUserUnlocked;
}
/**
* @return whether the user has completed setup wizard
*/
public boolean isUserSetupComplete() {
return mIsUserSetupComplete;
}
private void notifyUserUnlocked() {
for (Runnable action : mUserUnlockedActions) {
action.run();
}
mUserUnlockedActions.clear();
Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver);
}
/**
* @return whether the given running task info matches the gesture-blocked activity.
*/
public boolean isGestureBlockedActivity(ActivityManager.RunningTaskInfo runningTaskInfo) {
return runningTaskInfo != null
&& mGestureBlockedActivities.contains(runningTaskInfo.topActivity);
}
/**
* @return the packages of gesture-blocked activities.
*/
public List<String> getGestureBlockedActivityPackages() {
return mGestureBlockedActivities.stream().map(ComponentName::getPackageName)
.collect(Collectors.toList());
}
/**
* Updates the system ui state flags from SystemUI.
*/
public void setSystemUiFlags(int stateFlags) {
mSystemUiStateFlags = stateFlags;
}
/**
* @return the system ui state flags.
*/
// TODO(141886704): See if we can remove this
public @SystemUiStateFlags int getSystemUiStateFlags() {
return mSystemUiStateFlags;
}
/**
* @return whether SystemUI is in a state where we can start a system gesture.
*/
public boolean canStartSystemGesture() {
boolean canStartWithNavHidden = (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
|| mTaskListFrozen;
return canStartWithNavHidden
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
&& (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
&& ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
|| (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
}
/**
* @return whether the keyguard is showing and is occluded by an app showing above the keyguard
* (like camera or maps)
*/
public boolean isKeyguardShowingOccluded() {
return (mSystemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
}
/**
* @return whether screen pinning is enabled and active
*/
public boolean isScreenPinningActive() {
return (mSystemUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
}
/**
* @return whether the bubble stack is expanded
*/
public boolean isBubblesExpanded() {
return (mSystemUiStateFlags & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
}
/**
* @return whether the global actions dialog is showing
*/
public boolean isGlobalActionsShowing() {
return (mSystemUiStateFlags & SYSUI_STATE_GLOBAL_ACTIONS_SHOWING) != 0;
}
/**
* @return whether lock-task mode is active
*/
public boolean isLockToAppActive() {
return ActivityManagerWrapper.getInstance().isLockToAppActive();
}
/**
* @return whether the accessibility menu is available.
*/
public boolean isAccessibilityMenuAvailable() {
return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
}
/**
* @return whether the accessibility menu shortcut is available.
*/
public boolean isAccessibilityMenuShortcutAvailable() {
return (mSystemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
}
/**
* @return whether home is disabled (either by SUW/SysUI/device policy)
*/
public boolean isHomeDisabled() {
return (mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
}
/**
* @return whether overview is disabled (either by SUW/SysUI/device policy)
*/
public boolean isOverviewDisabled() {
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
* nav bar ui).
*/
public void setDeferredGestureRegion(Region deferredGestureRegion) {
mDeferredGestureRegion.set(deferredGestureRegion);
}
/**
* @return whether the given {@param event} is in the deferred gesture region indicating that
* the Launcher should not immediately start the recents animation until the gesture
* passes a certain threshold.
*/
public boolean isInDeferredGestureRegion(MotionEvent event) {
return mDeferredGestureRegion.contains((int) event.getX(), (int) event.getY());
}
/**
* @return whether the given {@param event} is in the app-requested gesture-exclusion region.
* This is only used for quickswitch, and not swipe up.
*/
public boolean isInExclusionRegion(MotionEvent event) {
// mExclusionRegion can change on binder thread, use a local instance here.
Region exclusionRegion = mExclusionRegion;
return mMode == NO_BUTTON && exclusionRegion != null
&& exclusionRegion.contains((int) event.getX(), (int) event.getY());
}
/**
* Sets whether the assistant is available.
*/
public void setAssistantAvailable(boolean assistantAvailable) {
mAssistantAvailable = assistantAvailable;
}
/**
* Sets the visibility fraction of the assistant.
*/
public void setAssistantVisibility(float visibility) {
mAssistantVisibility = visibility;
}
/**
* @return the visibility fraction of the assistant.
*/
public float getAssistantVisibility() {
return mAssistantVisibility;
}
/**
* @param ev An ACTION_DOWN motion event
* @param task Info for the currently running task
* @return whether the given motion event can trigger the assistant over the current task.
*/
public boolean canTriggerAssistantAction(MotionEvent ev, ActivityManager.RunningTaskInfo task) {
return mAssistantAvailable
&& !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
&& mOrientationTouchTransformer.touchInAssistantRegion(ev)
&& !isLockToAppActive()
&& !isGestureBlockedActivity(task);
}
/**
* *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 int getDisplayRotation() {
return mDisplayRotation;
}
public void dump(PrintWriter pw) {
pw.println("DeviceState:");
pw.println(" canStartSystemGesture=" + canStartSystemGesture());
pw.println(" systemUiFlags=" + mSystemUiStateFlags);
pw.println(" systemUiFlagsDesc="
+ QuickStepContract.getSystemUiStateString(mSystemUiStateFlags));
pw.println(" assistantAvailable=" + mAssistantAvailable);
pw.println(" assistantDisabled="
+ QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags));
pw.println(" currentActiveRotation=" + getCurrentActiveRotation());
pw.println(" displayRotation=" + getDisplayRotation());
pw.println(" isUserUnlocked=" + mIsUserUnlocked);
mOrientationTouchTransformer.dump(pw);
}
}