Merge "Re-enable home screen rotation" into ub-launcher3-rvc-dev
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 3d6e519..2b13a1e 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 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 @@
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 bcfb11c..fc28da3 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 @@
@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 dc27056..3513ad5 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 @@
mAppWindowAnimationHelper.updateHomeBounds(getStackBounds(dp));
}
int displayRotation = 0;
- if (mOrientedState != null) {
+ if (mOrientedState != null && !mOrientedState.areMultipleLayoutOrientationsDisabled()) {
// TODO(b/150300347): The first recents animation after launcher is started with the
// foreground app not in landscape will look funky until that bug is fixed
displayRotation = mOrientedState.getDisplayRotation();
RectF tempRectF = new RectF(TEMP_RECT);
- mOrientedState.mapRectFromNormalOrientation(tempRectF, dp.widthPx, dp.heightPx);
+ mOrientedState.mapRectFromRotation(displayRotation,
+ tempRectF, dp.widthPx, dp.heightPx);
tempRectF.roundOut(TEMP_RECT);
}
mAppWindowAnimationHelper.updateTargetRect(TEMP_RECT);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
index 75a5976..b739838 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/AppWindowAnimationHelper.java
@@ -160,9 +160,9 @@
}
private float getSrcToTargetScale() {
- if (mOrientedState == null ||
- (mOrientedState.getDisplayRotation() == Surface.ROTATION_0
- || mOrientedState.getDisplayRotation() == Surface.ROTATION_180)) {
+ if (mOrientedState == null
+ || mOrientedState.isHomeRotationAllowed()
+ || mOrientedState.isDisplayPhoneNatural()) {
return mSourceRect.width() / mTargetRect.width();
} else {
return mSourceRect.height() / mTargetRect.height();
@@ -277,8 +277,9 @@
mCurrentRect.offset(params.mOffset, 0);
} else {
int displayRotation = mOrientedState.getDisplayRotation();
+ int launcherRotation = mOrientedState.getLauncherRotation();
mOrientedState.getOrientationHandler().offsetTaskRect(mCurrentRect,
- params.mOffset, displayRotation);
+ params.mOffset, displayRotation, launcherRotation);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 98eb29a..87b0ad2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -88,10 +88,6 @@
}
};
- private RotationHelper.ForcedRotationChangedListener mForcedRotationChangedListener =
- isForcedRotation -> LauncherRecentsView.this
- .disableMultipleLayoutRotations(!isForcedRotation);
-
public LauncherRecentsView(Context context) {
this(context, null);
}
@@ -344,7 +340,6 @@
super.onAttachedToWindow();
PluginManagerWrapper.INSTANCE.get(getContext()).addPluginListener(
mRecentsExtraCardPluginListener, RecentsExtraCard.class);
- mActivity.getRotationHelper().addForcedRotationCallback(mForcedRotationChangedListener);
}
@Override
@@ -352,7 +347,6 @@
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 a18f7ba..e8d314d 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.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.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.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 @@
}
};
- protected final RecentsOrientedState mOrientationState = new RecentsOrientedState();
+ protected RecentsOrientedState mOrientationState;
private OrientationEventListener mOrientationListener;
private int mPreviousRotation;
@@ -343,6 +346,7 @@
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 @@
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
mIPinnedStackAnimationListener);
setActionsView();
+ mOrientationState.init();
}
@Override
@@ -496,6 +501,7 @@
mIdp.removeOnChangeListener(this);
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
mIPinnedStackAnimationListener.setActivity(null);
+ mOrientationState.destroy();
}
@Override
@@ -549,9 +555,7 @@
}
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 @@
}
}
+ 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;
@@ -585,6 +596,15 @@
}
@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);
final int x = (int) ev.getX();
@@ -778,7 +798,7 @@
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 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 Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
float degreesRotated;
if (navbarRotation == 0) {
- degreesRotated = mOrientationState.getTouchRotationDegrees();
+ degreesRotated = mOrientationState.areMultipleLayoutOrientationsDisabled() ? 0 :
+ mOrientationHandler.getDegreesRotated();
} else {
degreesRotated = -navbarRotation;
}
@@ -2035,7 +2062,8 @@
// 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 495c092..2e99500 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_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 @@
* @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 @@
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 f72e458..eefe8ac 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 @@
* 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 @@
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 @@
* 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 @@
} else {
mOrientationHandler = PagedOrientationHandler.PORTRAIT;
}
+ if (DEBUG) {
+ Log.d(TAG, "Set Orientation Handler: " + mOrientationHandler);
+ }
return true;
}
@@ -99,8 +171,12 @@
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 @@
}
}
+ @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 @@
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 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 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 2e0521f..3640d8b 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 @@
private final Activity mActivity;
private final SharedPreferences mSharedPrefs;
- private final SharedPreferences mFeatureFlagsPrefs;
private boolean mIgnoreAutoRotateSettings;
- private boolean mAutoRotateEnabled;
- private boolean mForcedRotation;
- private List<ForcedRotationChangedListener> mForcedRotationChangedListeners = new ArrayList<>();
+ private boolean mHomeRotationEnabled;
/**
* Rotation request made by
@@ -108,67 +102,35 @@
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 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 @@
if (!mInitialized) {
mInitialized = true;
notifyChange();
+
+ mContentResolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
+ false, mSystemAutoRotateObserver);
+ updateAutoRotateSetting();
}
}
@@ -217,8 +180,7 @@
if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
}
- mForcedRotationChangedListeners.clear();
- mFeatureFlagsPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
}
}
@@ -228,10 +190,7 @@
}
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 @@
} 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 @@
}
}
+ /**
+ * @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 0000000..710b676
--- /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 bab5747..f9f3bf4 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -78,6 +78,11 @@
}
@Override
+ public boolean isLayoutNaturalToLauncher() {
+ return false;
+ }
+
+ @Override
public void adjustFloatingIconStartVelocity(PointF velocity) {
float oldX = velocity.x;
float oldY = velocity.y;
@@ -182,7 +187,7 @@
}
@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 50606ec..ba4c064 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -42,6 +42,7 @@
PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler();
PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler();
PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler();
+ PagedOrientationHandler HOME_ROTATED = new HomeRotatedPageHandler();
interface Int2DAction<T> {
void call(T target, int x, int y);
@@ -79,7 +80,7 @@
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 @@
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 245138f..7c44eba 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -78,6 +78,11 @@
}
@Override
+ public boolean isLayoutNaturalToLauncher() {
+ return true;
+ }
+
+ @Override
public void adjustFloatingIconStartVelocity(PointF velocity) {
//no-op
}
@@ -180,7 +185,7 @@
}
@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 eebd87f..5ce8a57 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -36,7 +36,7 @@
}
@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 e114cf8..5b3840f 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -124,7 +124,6 @@
super.onAttachedToWindow();
if (!mIsOpening) {
getViewTreeObserver().addOnGlobalLayoutListener(this);
- mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK);
}
}