Merge "Re-enable home screen rotation" into ub-launcher3-rvc-dev

This commit is contained in:
Vinit Nayak 2020-04-18 05:22:26 +00:00 committed by Android (Google) Code Review
commit 8699bf5626
15 changed files with 294 additions and 123 deletions

View File

@ -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);
}
}

View File

@ -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(

View File

@ -322,13 +322,14 @@ public abstract class BaseSwipeUpHandler<T extends BaseDraggingActivity, Q exten
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);

View File

@ -160,9 +160,9 @@ public class AppWindowAnimationHelper {
}
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 @@ public class AppWindowAnimationHelper {
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);
}
}

View File

@ -88,10 +88,6 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
}
};
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<BaseQuickstepLauncher>
super.onAttachedToWindow();
PluginManagerWrapper.INSTANCE.get(getContext()).addPluginListener(
mRecentsExtraCardPluginListener, RecentsExtraCard.class);
mActivity.getRotationHelper().addForcedRotationCallback(mForcedRotationChangedListener);
}
@Override
@ -352,7 +347,6 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
super.onDetachedFromWindow();
PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(
mRecentsExtraCardPluginListener);
mActivity.getRotationHelper().removeForcedRotationCallback(mForcedRotationChangedListener);
}
@Override

View File

@ -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<T extends BaseActivity> 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<T extends BaseActivity> 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<T extends BaseActivity> extends PagedView impl
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
mIPinnedStackAnimationListener);
setActionsView();
mOrientationState.init();
}
@Override
@ -496,6 +501,7 @@ public abstract class RecentsView<T extends BaseActivity> 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<T extends BaseActivity> 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<T extends BaseActivity> 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<T extends BaseActivity> 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<T extends BaseActivity> 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<T extends BaseActivity> 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<T extends BaseActivity> extends PagedView impl
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 @@ public abstract class RecentsView<T extends BaseActivity> 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);

View File

@ -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;
}
}

View File

@ -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
*/

View File

@ -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<ForcedRotationChangedListener> 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);
}
}

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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<T> {
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

View File

@ -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) {

View File

@ -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) {

View File

@ -124,7 +124,6 @@ public class FloatingIconView extends FrameLayout implements
super.onAttachedToWindow();
if (!mIsOpening) {
getViewTreeObserver().addOnGlobalLayoutListener(this);
mLauncher.getRotationHelper().setCurrentTransitionRequest(REQUEST_LOCK);
}
}