Add fixed_rotation_transform to home settings
This sets the feature flag on launcher side
and also updates the setting in Settings.Global
Launcher DOES NOT listen to the Settings.Global
change from adb anymore. This should take
preference over setting it from command line.
Also fix a related swipe to home animation bug
that happened w/ merge conflict.
Fixes: 150260456
Test: Set and unset, visually verified behavior.
Tested w/ autorotate on and off.
Checked Settings.Global value correctly updated
via "adb shell settings get global
fixed_rotation_transform"
TODO: Update tests to reflect this new
default-on fixed rotation behavior.
Change-Id: Id95f006eb1e92a59e24b05567298fd21b1409b13
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 608d60c..e38631d 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -72,8 +72,6 @@
private static final String TAG = "PagedView";
private static final boolean DEBUG = false;
- public static boolean sFlagForcedRotation = false;
-
public static final int INVALID_PAGE = -1;
protected static final ComputePageScrollsLogic SIMPLE_SCROLL_LOGIC = (v) -> v.getVisibility() != GONE;
@@ -199,8 +197,6 @@
if (Utilities.ATLEAST_OREO) {
setDefaultFocusHighlightEnabled(false);
}
-
- sFlagForcedRotation = Utilities.isForcedRotation(context);
}
protected void setDefaultInterpolator(Interpolator interpolator) {
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 9780630..122b393 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -17,7 +17,6 @@
package com.android.launcher3;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED;
-import static com.android.launcher3.states.RotationHelper.FIXED_ROTATION_TRANSFORM_SETTING_NAME;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
@@ -61,6 +60,7 @@
import android.view.ViewConfiguration;
import android.view.animation.Interpolator;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.graphics.TintedDrawableSpan;
@@ -128,11 +128,6 @@
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
}
- public static boolean isForcedRotation(Context context) {
- return Settings.Global.getInt(context.getContentResolver(),
- FIXED_ROTATION_TRANSFORM_SETTING_NAME, 0) != 0;
- }
-
// An intent extra to indicate the horizontal scroll of the wallpaper.
public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET";
public static final String EXTRA_WALLPAPER_FLAVOR = "com.android.launcher3.WALLPAPER_FLAVOR";
@@ -481,6 +476,15 @@
LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE);
}
+ /**
+ * @return {@link SharedPreferences} that backs {@link FeatureFlags}
+ */
+ public static SharedPreferences getFeatureFlagsPrefs(Context context) {
+ // Use application context for shared preferences, so that we use a single cached instance
+ return context.getApplicationContext().getSharedPreferences(
+ FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE);
+ }
+
public static boolean areAnimationsEnabled(Context context) {
return ATLEAST_OREO
? ValueAnimator.areAnimatorsEnabled()
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index a6f9e6b..471a743 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -36,6 +36,8 @@
private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
public static final String FLAGS_PREF_NAME = "featureFlags";
+ public static final String FLAG_ENABLE_FIXED_ROTATION_TRANSFORM =
+ "ENABLE_FIXED_ROTATION_TRANSFORM";
private FeatureFlags() { }
@@ -153,6 +155,10 @@
"ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false,
"Always use hardware optimization for folder animations.");
+ public static final BooleanFlag ENABLE_FIXED_ROTATION_TRANSFORM = getDebugFlag(
+ FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true,
+ "Launch/close apps without rotation animation. Fix Launcher to portrait");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/model/PagedViewOrientedState.java b/src/com/android/launcher3/model/PagedViewOrientedState.java
index 1349eff..e48b8c1 100644
--- a/src/com/android/launcher3/model/PagedViewOrientedState.java
+++ b/src/com/android/launcher3/model/PagedViewOrientedState.java
@@ -50,7 +50,16 @@
*/
private boolean mDisableMultipleOrientations;
+ /**
+ * Sets the appropriate {@link PagedOrientationHandler} for {@link #mOrientationHandler}
+ * @param touchRotation The rotation the nav bar region that is touched is in
+ * @param displayRotation Rotation of the display/device
+ */
public void update(int touchRotation, int displayRotation) {
+ if (mDisableMultipleOrientations) {
+ return;
+ }
+
mDisplayRotation = displayRotation;
mTouchRotation = touchRotation;
if (mTouchRotation == Surface.ROTATION_90) {
@@ -62,20 +71,13 @@
}
}
- /**
- * @return {@code true} if the area where the user touched the nav bar is the expected
- * location for the given display rotation. Ex. bottom of phone in portrait, or left side of
- * phone in landscape, right side in seascape, etc.
- * False otherwise
- */
- public boolean isTouchRegionNaturalForDisplay() {
- return mTouchRotation == mDisplayRotation;
- }
-
public boolean areMultipleLayoutOrientationsDisabled() {
return mDisableMultipleOrientations;
}
+ /**
+ * Setting this preference will render future calls to {@link #update(int, int)} as a no-op.
+ */
public void disableMultipleOrientations(boolean disable) {
mDisableMultipleOrientations = disable;
if (disable) {
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 43d54eb..fae0fe2 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -21,13 +21,13 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.config.FeatureFlags.FLAG_ENABLE_FIXED_ROTATION_TRANSFORM;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.content.ContentResolver;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
-import android.database.ContentObserver;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -72,26 +72,13 @@
return originalSmallestWidth >= 600;
}
-
- private final ContentObserver mContentObserver =
- new ContentObserver(MAIN_EXECUTOR.getHandler()) {
- @Override
- public void onChange(boolean selfChange) {
- boolean forcedRotation = Utilities.isForcedRotation(mLauncher);
- PagedView.sFlagForcedRotation = forcedRotation;
- updateForcedRotation();
- for (ForcedRotationChangedListener listener : mForcedRotationChangedListeners) {
- listener.onForcedRotationChanged(forcedRotation);
- }
- }
- };
-
public static final int REQUEST_NONE = 0;
public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2;
private final Launcher mLauncher;
- private final SharedPreferences mPrefs;
+ private final SharedPreferences mSharedPrefs;
+ private final SharedPreferences mFeatureFlagsPrefs;
private boolean mIgnoreAutoRotateSettings;
private boolean mAutoRotateEnabled;
@@ -125,24 +112,42 @@
// On large devices we do not handle auto-rotate differently.
mIgnoreAutoRotateSettings = mLauncher.getResources().getBoolean(R.bool.allow_rotation);
- updateForcedRotation();
if (!mIgnoreAutoRotateSettings) {
- mPrefs = Utilities.getPrefs(mLauncher);
- mPrefs.registerOnSharedPreferenceChangeListener(this);
- mAutoRotateEnabled = mPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ mSharedPrefs = Utilities.getPrefs(mLauncher);
+ mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
+ mAutoRotateEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue());
} else {
- mPrefs = null;
+ mSharedPrefs = null;
}
- // TODO(b/150260456) Add this in home settings as well
mContentResolver = launcher.getContentResolver();
- mContentResolver.registerContentObserver(Settings.Global.getUriFor(
- FIXED_ROTATION_TRANSFORM_SETTING_NAME), false, mContentObserver);
+ mFeatureFlagsPrefs = Utilities.getFeatureFlagsPrefs(mLauncher);
+ mFeatureFlagsPrefs.registerOnSharedPreferenceChangeListener(this);
+ updateForcedRotation(true);
}
- private void updateForcedRotation() {
- mForcedRotation = !getAllowRotationDefaultValue() && Utilities.isForcedRotation(mLauncher);
+ /**
+ * @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;
+ }
+ if (setValueFromPrefs) {
+ mForcedRotation = isForcedRotation;
+ }
+ UI_HELPER_EXECUTOR.execute(
+ () -> Settings.Global.putInt(mContentResolver, FIXED_ROTATION_TRANSFORM_SETTING_NAME,
+ mForcedRotation ? 1 : 0));
+ for (ForcedRotationChangedListener listener : mForcedRotationChangedListeners) {
+ listener.onForcedRotationChanged(mForcedRotation);
+ }
}
/**
@@ -181,8 +186,13 @@
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
+ if (FLAG_ENABLE_FIXED_ROTATION_TRANSFORM.equals(s)) {
+ updateForcedRotation(true);
+ return;
+ }
+
boolean wasRotationEnabled = mAutoRotateEnabled;
- mAutoRotateEnabled = mPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
+ mAutoRotateEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue());
if (mAutoRotateEnabled != wasRotationEnabled) {
@@ -218,6 +228,10 @@
public void forceAllowRotationForTesting(boolean allowRotation) {
mIgnoreAutoRotateSettings =
allowRotation || mLauncher.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();
}
@@ -232,13 +246,11 @@
public void destroy() {
if (!mDestroyed) {
mDestroyed = true;
- if (mPrefs != null) {
- mPrefs.unregisterOnSharedPreferenceChangeListener(this);
- }
- if (mContentResolver != null) {
- mContentResolver.unregisterContentObserver(mContentObserver);
+ if (mSharedPrefs != null) {
+ mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
}
mForcedRotationChangedListeners.clear();
+ mFeatureFlagsPrefs.unregisterOnSharedPreferenceChangeListener(this);
}
}
@@ -293,7 +305,7 @@
return degrees;
}
- public static int getRotationFromDegrees(int degrees) {
+ public static int getRotationFromDegrees(float degrees) {
int threshold = 70;
if (degrees >= (360 - threshold) || degrees < (threshold)) {
return Surface.ROTATION_0;
@@ -318,11 +330,30 @@
}
/**
+ * For landscape, since the navbar is already in a vertical position, we don't have to do any
+ * rotations as the change in Y coordinate is what is read. We only flip the sign of the
+ * y coordinate to make it match existing behavior of swipe to the top to go previous
+ */
+ public static void transformEventForNavBar(MotionEvent ev, boolean inverse) {
+ // TODO(b/151269990): Use a temp matrix
+ Matrix m = new Matrix();
+ m.setScale(1, -1);
+ if (inverse) {
+ Matrix inv = new Matrix();
+ m.invert(inv);
+ ev.transform(inv);
+ } else {
+ ev.transform(m);
+ }
+ }
+
+ /**
* Creates a matrix to transform the given motion event specified by degrees.
* If {@param inverse} is {@code true}, the inverse of that matrix will be applied
*/
public static void transformEvent(float degrees, MotionEvent ev, boolean inverse) {
Matrix transform = new Matrix();
+ // TODO(b/151269990): Use a temp matrix
transform.setRotate(degrees);
if (inverse) {
Matrix inv = new Matrix();
@@ -344,6 +375,7 @@
*/
public static Matrix getRotationMatrix(int screenWidth, int screenHeight, int displayRotation) {
Matrix m = new Matrix();
+ // TODO(b/151269990): Use a temp matrix
switch (displayRotation) {
case Surface.ROTATION_0:
return m;