diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 3d6e519d3f..2b13a1e756 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -26,6 +26,7 @@ import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS; import android.annotation.TargetApi; import android.os.Build; import android.util.FloatProperty; +import android.view.Surface; import android.view.View; import android.view.animation.Interpolator; @@ -91,8 +92,9 @@ public final class RecentsViewStateController extends buttonAlpha, LINEAR); View actionsView = mLauncher.getActionsView(); - if (actionsView != null) { - propertySetter.setFloat(actionsView, VIEW_ALPHA, buttonAlpha, actionInterpolator); + int launcherRotation = mRecentsView.getPagedViewOrientedState().getLauncherRotation(); + if (actionsView != null && launcherRotation == Surface.ROTATION_0) { + propertySetter.setViewAlpha(actionsView, buttonAlpha, actionInterpolator); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java index bcfb11c090..fc28da3f5d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -144,7 +144,6 @@ public class OverviewState extends LauncherState { @Override public void onStateTransitionEnd(Launcher launcher) { - launcher.getRotationHelper().setCurrentStateRequest(REQUEST_ROTATE); DiscoveryBounce.showForOverviewIfNeeded(launcher); RecentsView recentsView = launcher.getOverviewPanel(); AccessibilityManagerCompat.sendCustomAccessibilityEvent( diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index dc270566ef..3513ad5386 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -322,13 +322,14 @@ public abstract class BaseSwipeUpHandler } }; - private RotationHelper.ForcedRotationChangedListener mForcedRotationChangedListener = - isForcedRotation -> LauncherRecentsView.this - .disableMultipleLayoutRotations(!isForcedRotation); - public LauncherRecentsView(Context context) { this(context, null); } @@ -344,7 +340,6 @@ public class LauncherRecentsView extends RecentsView super.onAttachedToWindow(); PluginManagerWrapper.INSTANCE.get(getContext()).addPluginListener( mRecentsExtraCardPluginListener, RecentsExtraCard.class); - mActivity.getRotationHelper().addForcedRotationCallback(mForcedRotationChangedListener); } @Override @@ -352,7 +347,6 @@ public class LauncherRecentsView extends RecentsView super.onDetachedFromWindow(); PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener( mRecentsExtraCardPluginListener); - mActivity.getRotationHelper().removeForcedRotationCallback(mForcedRotationChangedListener); } @Override diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index a18f7bae05..e8d314dc95 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -50,6 +50,7 @@ import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.res.Configuration; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.Rect; @@ -72,6 +73,7 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.OrientationEventListener; +import android.view.Surface; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; @@ -128,6 +130,7 @@ import com.android.systemui.shared.recents.IPinnedStackAnimationListener; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.ConfigurationCompat; import com.android.systemui.shared.system.LauncherEventUtil; import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; @@ -172,7 +175,7 @@ public abstract class RecentsView extends PagedView impl } }; - protected final RecentsOrientedState mOrientationState = new RecentsOrientedState(); + protected RecentsOrientedState mOrientationState; private OrientationEventListener mOrientationListener; private int mPreviousRotation; @@ -343,6 +346,7 @@ public abstract class RecentsView extends PagedView impl super(context, attrs, defStyleAttr); setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing)); setEnableFreeScroll(true); + mOrientationState = new RecentsOrientedState(context); mFastFlingVelocity = getResources() .getDimensionPixelSize(R.dimen.recents_fast_fling_velocity); @@ -482,6 +486,7 @@ public abstract class RecentsView extends PagedView impl SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener( mIPinnedStackAnimationListener); setActionsView(); + mOrientationState.init(); } @Override @@ -496,6 +501,7 @@ public abstract class RecentsView extends PagedView impl mIdp.removeOnChangeListener(this); SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null); mIPinnedStackAnimationListener.setActivity(null); + mOrientationState.destroy(); } @Override @@ -549,9 +555,7 @@ public abstract class RecentsView extends PagedView impl } public void setOverviewStateEnabled(boolean enabled) { - if (supportsVerticalLandscape() - && !TestProtocol.sDisableSensorRotation // Ignore hardware dependency for tests - && mOrientationListener.canDetectOrientation()) { + if (canEnableOverviewRotationAnimation()) { if (enabled) { mOrientationListener.enable(); } else { @@ -567,6 +571,13 @@ public abstract class RecentsView extends PagedView impl } } + private boolean canEnableOverviewRotationAnimation() { + return supportsVerticalLandscape() // not 3P launcher + && !TestProtocol.sDisableSensorRotation // Ignore hardware dependency for tests.. + && mOrientationListener.canDetectOrientation() // ..but does the hardware even work? + && !mOrientationState.canLauncherAutoRotate(); // launcher is going to rotate itself + } + public void onDigitalWellbeingToastShown() { if (!mDwbToastShown) { mDwbToastShown = true; @@ -584,6 +595,15 @@ public abstract class RecentsView extends PagedView impl } } + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + int windowConfigurationRotation = ConfigurationCompat + .getWindowConfigurationRotation(getResources().getConfiguration()); + setLayoutInternal(mOrientationState.getTouchRotation(), + mOrientationState.getDisplayRotation(), windowConfigurationRotation); + } + @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); @@ -778,7 +798,7 @@ public abstract class RecentsView extends PagedView impl for (int i = 0; i < taskCount; i++) { getTaskViewAt(i).setFullscreenProgress(mFullscreenProgress); } - if (mActionsView != null) { + if (mActionsView != null && mOrientationState.getLauncherRotation() == Surface.ROTATION_0) { mActionsView.setVisibility(fullscreenProgress == 0 ? VISIBLE : INVISIBLE); } } @@ -1561,11 +1581,17 @@ public abstract class RecentsView extends PagedView impl } public void setLayoutRotation(int touchRotation, int displayRotation) { - if (mOrientationState.update(touchRotation, displayRotation)) { + int launcherRotation = mOrientationState.getLauncherRotation(); + setLayoutInternal(touchRotation, displayRotation, launcherRotation); + } + + private void setLayoutInternal(int touchRotation, int displayRotation, int launcherRotation) { + if (mOrientationState.update(touchRotation, displayRotation, launcherRotation)) { mOrientationHandler = mOrientationState.getOrientationHandler(); mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources()); setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated()); + mActivity.getDragLayer().recreateControllers(); requestLayout(); } } @@ -2022,7 +2048,8 @@ public abstract class RecentsView extends PagedView impl public Consumer getEventDispatcher(float navbarRotation) { float degreesRotated; if (navbarRotation == 0) { - degreesRotated = mOrientationState.getTouchRotationDegrees(); + degreesRotated = mOrientationState.areMultipleLayoutOrientationsDisabled() ? 0 : + mOrientationHandler.getDegreesRotated(); } else { degreesRotated = -navbarRotation; } @@ -2035,7 +2062,8 @@ public abstract class RecentsView extends PagedView impl // PagedOrientationHandler return e -> { if (navbarRotation != 0 - && !mOrientationState.areMultipleLayoutOrientationsDisabled()) { + && !mOrientationState.areMultipleLayoutOrientationsDisabled() + && !mOrientationState.getOrientationHandler().isLayoutNaturalToLauncher()) { mOrientationState.flipVertical(e); super.onTouchEvent(e); mOrientationState.flipVertical(e); diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java index 495c09297e..2e99500435 100644 --- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java +++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java @@ -22,6 +22,7 @@ import static android.view.MotionEvent.ACTION_MOVE; import static android.view.MotionEvent.ACTION_POINTER_DOWN; import static android.view.MotionEvent.ACTION_UP; +import static com.android.launcher3.states.RotationHelper.deltaRotation; import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation; import android.content.res.Resources; @@ -138,7 +139,8 @@ class OrientationTouchTransformer { * @param info The current displayInfo */ void enableMultipleRegions(boolean enableMultipleRegions, DefaultDisplay.Info info) { - mEnableMultipleRegions = enableMultipleRegions; + mEnableMultipleRegions = enableMultipleRegions && + mMode != SysUINavigationMode.Mode.TWO_BUTTONS; if (!enableMultipleRegions) { mQuickStepStartingRotation = -1; resetSwipeRegions(info); @@ -364,16 +366,4 @@ class OrientationTouchTransformer { return false; } } - - /** - * @return how many factors {@param newRotation} is rotated 90 degrees clockwise. - * E.g. 1->Rotated by 90 degrees clockwise, 2->Rotated 180 clockwise... - * A value of 0 means no rotation has been applied - */ - @SurfaceRotation - private static int deltaRotation(int oldRotation, int newRotation) { - int delta = newRotation - oldRotation; - if (delta < 0) delta += 4; - return delta; - } } diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index f72e4588ca..eefe8ac04b 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -16,20 +16,36 @@ package com.android.quickstep.util; +import static android.Manifest.permission.WRITE_SECURE_SETTINGS; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.hardware.camera2.params.OutputConfiguration.ROTATION_180; +import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; +import static com.android.launcher3.config.FeatureFlags.FLAG_ENABLE_FIXED_ROTATION_TRANSFORM; +import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY; +import static com.android.launcher3.states.RotationHelper.FIXED_ROTATION_TRANSFORM_SETTING_NAME; +import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static java.lang.annotation.RetentionPolicy.SOURCE; +import android.content.ContentResolver; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.database.ContentObserver; import android.graphics.Matrix; import android.graphics.RectF; +import android.os.Handler; +import android.provider.Settings; +import android.util.Log; import android.view.MotionEvent; import android.view.Surface; import androidx.annotation.IntDef; +import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.touch.PortraitPagedViewHandler; @@ -44,8 +60,17 @@ import java.lang.annotation.Retention; * This class has initial default state assuming the device and foreground app have * no ({@link Surface#ROTATION_0} rotation. */ -public final class RecentsOrientedState { +public final class RecentsOrientedState implements SharedPreferences.OnSharedPreferenceChangeListener { + private static final String TAG = "RecentsOrientedState"; + private static final boolean DEBUG = false; + + private ContentObserver mSystemAutoRotateObserver = new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + updateAutoRotateSetting(); + } + }; @Retention(SOURCE) @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) public @interface SurfaceRotation {} @@ -54,15 +79,45 @@ public final class RecentsOrientedState { private @SurfaceRotation int mTouchRotation = ROTATION_0; private @SurfaceRotation int mDisplayRotation = ROTATION_0; + private @SurfaceRotation int mLauncherRotation = Surface.ROTATION_0; + /** * If {@code true} we default to {@link PortraitPagedViewHandler} and don't support any fake * launcher orientations. */ private boolean mDisableMultipleOrientations; + private boolean mIsHomeRotationAllowed; + private boolean mIsSystemRotationAllowed; + + private final ContentResolver mContentResolver; + private final SharedPreferences mSharedPrefs; + private final boolean mAllowConfigurationDefaultValue; + private final Matrix mTmpMatrix = new Matrix(); private final Matrix mTmpInverseMatrix = new Matrix(); + public RecentsOrientedState(Context context) { + mContentResolver = context.getContentResolver(); + mSharedPrefs = Utilities.getPrefs(context); + + Resources res = context.getResources(); + int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp + * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE; + mAllowConfigurationDefaultValue = originalSmallestWidth >= 600; + + boolean isForcedRotation = Utilities.getFeatureFlagsPrefs(context) + .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true) + && !mAllowConfigurationDefaultValue; + UI_HELPER_EXECUTOR.execute(() -> { + if (context.checkSelfPermission(WRITE_SECURE_SETTINGS) == PERMISSION_GRANTED) { + Settings.Global.putInt(mContentResolver, FIXED_ROTATION_TRANSFORM_SETTING_NAME, + isForcedRotation ? 1 : 0); + } + }); + disableMultipleOrientations(!isForcedRotation); + } + /** * Sets the appropriate {@link PagedOrientationHandler} for {@link #mOrientationHandler} * @param touchRotation The rotation the nav bar region that is touched is in @@ -72,19 +127,33 @@ public final class RecentsOrientedState { * false otherwise */ public boolean update( - @SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation) { + @SurfaceRotation int touchRotation, @SurfaceRotation int displayRotation, + int launcherRotation) { if (!FeatureFlags.ENABLE_FIXED_ROTATION_TRANSFORM.get()) { return false; } if (mDisableMultipleOrientations) { return false; } - if (mDisplayRotation == displayRotation && mTouchRotation == touchRotation) { + if (mDisplayRotation == displayRotation && mTouchRotation == touchRotation + && launcherRotation == mLauncherRotation) { return false; } + mLauncherRotation = launcherRotation; mDisplayRotation = displayRotation; mTouchRotation = touchRotation; + + if ((mIsHomeRotationAllowed && mIsSystemRotationAllowed) || + mLauncherRotation == mTouchRotation) { + // TODO(b/153476489) Need to determine when launcher is rotated + mOrientationHandler = PagedOrientationHandler.HOME_ROTATED; + if (DEBUG) { + Log.d(TAG, "Set Orientation Handler: " + mOrientationHandler); + } + return true; + } + if (mTouchRotation == ROTATION_90) { mOrientationHandler = PagedOrientationHandler.LANDSCAPE; } else if (mTouchRotation == ROTATION_270) { @@ -92,6 +161,9 @@ public final class RecentsOrientedState { } else { mOrientationHandler = PagedOrientationHandler.PORTRAIT; } + if (DEBUG) { + Log.d(TAG, "Set Orientation Handler: " + mOrientationHandler); + } return true; } @@ -99,8 +171,12 @@ public final class RecentsOrientedState { return mDisableMultipleOrientations; } + public boolean canLauncherAutoRotate() { + return mIsHomeRotationAllowed && mIsSystemRotationAllowed; + } + /** - * Setting this preference will render future calls to {@link #update(int, int)} as a no-op. + * Setting this preference renders future calls to {@link #update(int, int, int)} as a no-op. */ public void disableMultipleOrientations(boolean disable) { mDisableMultipleOrientations = disable; @@ -110,6 +186,39 @@ public final class RecentsOrientedState { } } + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { + updateHomeRotationSetting(); + } + + private void updateAutoRotateSetting() { + try { + mIsSystemRotationAllowed = Settings.System.getInt(mContentResolver, + Settings.System.ACCELEROMETER_ROTATION) == 1; + } catch (Settings.SettingNotFoundException e) { + Log.e(TAG, "autorotate setting not found", e); + } + } + + private void updateHomeRotationSetting() { + mIsHomeRotationAllowed = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, + mAllowConfigurationDefaultValue); + } + + public void init() { + mSharedPrefs.registerOnSharedPreferenceChangeListener(this); + mContentResolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), + false, mSystemAutoRotateObserver); + updateAutoRotateSetting(); + updateHomeRotationSetting(); + } + + public void destroy() { + mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this); + mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver); + } + @SurfaceRotation public int getDisplayRotation() { return mDisplayRotation; @@ -120,6 +229,14 @@ public final class RecentsOrientedState { return mTouchRotation; } + public boolean isHomeRotationAllowed() { + return mIsHomeRotationAllowed; + } + + public int getLauncherRotation() { + return mLauncherRotation; + } + public int getTouchRotationDegrees() { switch (mTouchRotation) { case ROTATION_90: @@ -166,8 +283,12 @@ public final class RecentsOrientedState { } public void mapRectFromNormalOrientation(RectF src, int screenWidth, int screenHeight) { + mapRectFromRotation(mDisplayRotation, src, screenWidth, screenHeight); + } + + public void mapRectFromRotation(int rotation, RectF src, int screenWidth, int screenHeight) { mTmpMatrix.reset(); - postDisplayRotation(mDisplayRotation, screenWidth, screenHeight, mTmpMatrix); + postDisplayRotation(rotation, screenWidth, screenHeight, mTmpMatrix); mTmpMatrix.mapRect(src); } @@ -192,6 +313,10 @@ public final class RecentsOrientedState { } } + public boolean isDisplayPhoneNatural() { + return mDisplayRotation == Surface.ROTATION_0 || mDisplayRotation == Surface.ROTATION_180; + } + /** * Posts the transformation on the matrix representing the provided display rotation */ diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java index 2e0521f34c..3640d8bbde 100644 --- a/src/com/android/launcher3/states/RotationHelper.java +++ b/src/com/android/launcher3/states/RotationHelper.java @@ -15,47 +15,44 @@ */ package com.android.launcher3.states; -import static android.Manifest.permission.WRITE_SECURE_SETTINGS; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE; -import static com.android.launcher3.config.FeatureFlags.FLAG_ENABLE_FIXED_ROTATION_TRANSFORM; -import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; - import android.app.Activity; import android.content.ContentResolver; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.res.Resources; +import android.database.ContentObserver; +import android.os.Handler; import android.provider.Settings; +import android.util.Log; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.UiThreadHelper; -import java.util.ArrayList; -import java.util.List; - /** * Utility class to manage launcher rotation */ public class RotationHelper implements OnSharedPreferenceChangeListener { + private static final String TAG = "RotationHelper"; + public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation"; public static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform"; private final ContentResolver mContentResolver; + private boolean mSystemAutoRotateEnabled; - /** - * Listener to receive changes when {@link #FIXED_ROTATION_TRANSFORM_SETTING_NAME} flag changes. - */ - public interface ForcedRotationChangedListener { - void onForcedRotationChanged(boolean isForcedRotation); - } + private ContentObserver mSystemAutoRotateObserver = new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + updateAutoRotateSetting(); + } + }; public static boolean getAllowRotationDefaultValue() { // If the device's pixel density was scaled (usually via settings for A11y), use the @@ -72,12 +69,9 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { private final Activity mActivity; private final SharedPreferences mSharedPrefs; - private final SharedPreferences mFeatureFlagsPrefs; private boolean mIgnoreAutoRotateSettings; - private boolean mAutoRotateEnabled; - private boolean mForcedRotation; - private List mForcedRotationChangedListeners = new ArrayList<>(); + private boolean mHomeRotationEnabled; /** * Rotation request made by @@ -108,67 +102,35 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { if (!mIgnoreAutoRotateSettings) { mSharedPrefs = Utilities.getPrefs(mActivity); mSharedPrefs.registerOnSharedPreferenceChangeListener(this); - mAutoRotateEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, + mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, getAllowRotationDefaultValue()); } else { mSharedPrefs = null; } mContentResolver = activity.getContentResolver(); - mFeatureFlagsPrefs = Utilities.getFeatureFlagsPrefs(mActivity); - mFeatureFlagsPrefs.registerOnSharedPreferenceChangeListener(this); - updateForcedRotation(true); } - /** - * @param setValueFromPrefs If true, then {@link #mForcedRotation} will get set to the value - * from the home developer settings. Otherwise it will not. - * This is primarily to allow tests to set their own conditions. - */ - private void updateForcedRotation(boolean setValueFromPrefs) { - boolean isForcedRotation = mFeatureFlagsPrefs - .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true) - && !getAllowRotationDefaultValue(); - if (mForcedRotation == isForcedRotation) { - return; + private void updateAutoRotateSetting() { + int autoRotateEnabled = 0; + try { + autoRotateEnabled = Settings.System.getInt(mContentResolver, + Settings.System.ACCELEROMETER_ROTATION); + } catch (Settings.SettingNotFoundException e) { + Log.e(TAG, "autorotate setting not found", e); } - if (setValueFromPrefs) { - mForcedRotation = isForcedRotation; - } - UI_HELPER_EXECUTOR.execute(() -> { - if (mActivity.checkSelfPermission(WRITE_SECURE_SETTINGS) == PERMISSION_GRANTED) { - Settings.Global.putInt(mContentResolver, FIXED_ROTATION_TRANSFORM_SETTING_NAME, - mForcedRotation ? 1 : 0); - } - }); - for (ForcedRotationChangedListener listener : mForcedRotationChangedListeners) { - listener.onForcedRotationChanged(mForcedRotation); - } - } - /** - * will not be called when first registering the listener. - */ - public void addForcedRotationCallback(ForcedRotationChangedListener listener) { - mForcedRotationChangedListeners.add(listener); - } - - public void removeForcedRotationCallback(ForcedRotationChangedListener listener) { - mForcedRotationChangedListeners.remove(listener); + mSystemAutoRotateEnabled = autoRotateEnabled == 1; } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { - if (FLAG_ENABLE_FIXED_ROTATION_TRANSFORM.equals(s)) { - updateForcedRotation(true); - return; - } - - boolean wasRotationEnabled = mAutoRotateEnabled; - mAutoRotateEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, + boolean wasRotationEnabled = mHomeRotationEnabled; + mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, getAllowRotationDefaultValue()); - if (mAutoRotateEnabled != wasRotationEnabled) { + if (mHomeRotationEnabled != wasRotationEnabled) { notifyChange(); + updateAutoRotateSetting(); } } @@ -197,10 +159,6 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { public void forceAllowRotationForTesting(boolean allowRotation) { mIgnoreAutoRotateSettings = allowRotation || mActivity.getResources().getBoolean(R.bool.allow_rotation); - // TODO(b/150214193) Tests currently expect launcher to be able to be rotated - // Modify tests for this new behavior - mForcedRotation = !allowRotation; - updateForcedRotation(false); notifyChange(); } @@ -208,6 +166,11 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { if (!mInitialized) { mInitialized = true; notifyChange(); + + mContentResolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), + false, mSystemAutoRotateObserver); + updateAutoRotateSetting(); } } @@ -217,8 +180,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { if (mSharedPrefs != null) { mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this); } - mForcedRotationChangedListeners.clear(); - mFeatureFlagsPrefs.unregisterOnSharedPreferenceChangeListener(this); + mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver); } } @@ -228,10 +190,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { } final int activityFlags; - if (mForcedRotation) { - // TODO(b/150214193) Properly address this - activityFlags = SCREEN_ORIENTATION_PORTRAIT; - } else if (mStateHandlerRequest != REQUEST_NONE) { + if (mStateHandlerRequest != REQUEST_NONE) { activityFlags = mStateHandlerRequest == REQUEST_LOCK ? SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED; } else if (mCurrentTransitionRequest != REQUEST_NONE) { @@ -240,7 +199,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { } else if (mCurrentStateRequest == REQUEST_LOCK) { activityFlags = SCREEN_ORIENTATION_LOCKED; } else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE - || mAutoRotateEnabled) { + || mHomeRotationEnabled) { activityFlags = SCREEN_ORIENTATION_UNSPECIFIED; } else { // If auto rotation is off, allow rotation on the activity, in case the user is using @@ -253,11 +212,23 @@ public class RotationHelper implements OnSharedPreferenceChangeListener { } } + /** + * @return how many factors {@param newRotation} is rotated 90 degrees clockwise. + * E.g. 1->Rotated by 90 degrees clockwise, 2->Rotated 180 clockwise... + * A value of 0 means no rotation has been applied + */ + public static int deltaRotation(int oldRotation, int newRotation) { + int delta = newRotation - oldRotation; + if (delta < 0) delta += 4; + return delta; + } + @Override public String toString() { return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d," - + " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mAutoRotateEnabled=%b]", + + " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mHomeRotationEnabled=%b," + + " mSystemAutoRotateEnabled=%b]", mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags, - mIgnoreAutoRotateSettings, mAutoRotateEnabled); + mIgnoreAutoRotateSettings, mHomeRotationEnabled, mSystemAutoRotateEnabled); } } diff --git a/src/com/android/launcher3/touch/HomeRotatedPageHandler.java b/src/com/android/launcher3/touch/HomeRotatedPageHandler.java new file mode 100644 index 0000000000..710b676880 --- /dev/null +++ b/src/com/android/launcher3/touch/HomeRotatedPageHandler.java @@ -0,0 +1,49 @@ +/* + * 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.launcher3.touch; + +import android.graphics.RectF; +import android.view.Surface; + +public class HomeRotatedPageHandler extends PortraitPagedViewHandler { + @Override + public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) { + if (launcherRotation == Surface.ROTATION_0) { + super.offsetTaskRect(rect, value, displayRotation, launcherRotation); + } else if (launcherRotation == Surface.ROTATION_90) { + if (displayRotation == Surface.ROTATION_0) { + rect.offset(0, value); + } else if (displayRotation == Surface.ROTATION_90) { + rect.offset(value, 0); + } else if (displayRotation == Surface.ROTATION_180) { + rect.offset(-value, 0); + } else { + rect.offset(-value, 0); + } + } else if (launcherRotation == Surface.ROTATION_270) { + if (displayRotation == Surface.ROTATION_0) { + rect.offset(0, -value); + } else if (displayRotation == Surface.ROTATION_90) { + rect.offset(value, 0); + } else if (displayRotation == Surface.ROTATION_180) { + rect.offset(0, -value); + } else { + rect.offset(value, 0); + } + } // TODO (b/149609488) handle 180 case as well + } +} diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java index bab574774a..f9f3bf4bc1 100644 --- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java @@ -77,6 +77,11 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { return displacement > 0; } + @Override + public boolean isLayoutNaturalToLauncher() { + return false; + } + @Override public void adjustFloatingIconStartVelocity(PointF velocity) { float oldX = velocity.x; @@ -182,7 +187,7 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { } @Override - public void offsetTaskRect(RectF rect, float value, int displayRotation) { + public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) { if (displayRotation == Surface.ROTATION_0) { rect.offset(0, value); } else if (displayRotation == Surface.ROTATION_90) { diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java index 50606ec8ae..ba4c064f5b 100644 --- a/src/com/android/launcher3/touch/PagedOrientationHandler.java +++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java @@ -42,6 +42,7 @@ public interface PagedOrientationHandler { PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler(); PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler(); PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler(); + PagedOrientationHandler HOME_ROTATED = new HomeRotatedPageHandler(); interface Int2DAction { void call(T target, int x, int y); @@ -79,7 +80,7 @@ public interface PagedOrientationHandler { void setMaxScroll(AccessibilityEvent event, int maxScroll); boolean getRecentsRtlSetting(Resources resources); float getDegreesRotated(); - void offsetTaskRect(RectF rect, float value, int delta); + void offsetTaskRect(RectF rect, float value, int delta, int launcherRotation); int getPrimaryValue(int x, int y); int getSecondaryValue(int x, int y); void delegateScrollTo(PagedView pagedView, int secondaryScroll, int primaryScroll); @@ -89,6 +90,7 @@ public interface PagedOrientationHandler { void scrollerStartScroll(OverScroller scroller, int newPosition); void getCurveProperties(PagedView view, Rect insets, CurveProperties out); boolean isGoingUp(float displacement); + boolean isLayoutNaturalToLauncher(); /** * Maps the velocity from the coordinate plane of the foreground app to that diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index 245138f7a1..7c44ebab0c 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -77,6 +77,11 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { return displacement < 0; } + @Override + public boolean isLayoutNaturalToLauncher() { + return true; + } + @Override public void adjustFloatingIconStartVelocity(PointF velocity) { //no-op @@ -180,7 +185,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { } @Override - public void offsetTaskRect(RectF rect, float value, int displayRotation) { + public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) { if (displayRotation == Surface.ROTATION_0) { rect.offset(value, 0); } else if (displayRotation == Surface.ROTATION_90) { diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java index eebd87fc86..5ce8a5763e 100644 --- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java @@ -36,7 +36,7 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler { } @Override - public void offsetTaskRect(RectF rect, float value, int displayRotation) { + public void offsetTaskRect(RectF rect, float value, int displayRotation, int launcherRotation) { if (displayRotation == Surface.ROTATION_0) { rect.offset(0, value); } else if (displayRotation == Surface.ROTATION_90) { diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index e114cf8499..5b3840f756 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -124,7 +124,6 @@ public class FloatingIconView extends FrameLayout implements super.onAttachedToWindow(); if (!mIsOpening) { getViewTreeObserver().addOnGlobalLayoutListener(this); - mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK); } }