326d93bd56
Launcher home screen rotation now works with fixed transform. When using Quickstep while holding the phone from an orientation different than the orientation of the touch, the overview shown will be that of the phone orientation, not the touch orientation. Easier to see this be quickswitching from portrait to landscape app, turning phone, then going to overview from the original region you swiped. Fixes: 150214193 Test: Created test apps and fixed them to various rotations to test. Change-Id: Ic6565cd0ed33c951f45ccb97278045c6070e438e
235 lines
8.6 KiB
Java
235 lines
8.6 KiB
Java
/*
|
|
* Copyright (C) 2018 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.states;
|
|
|
|
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_UNSPECIFIED;
|
|
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
|
|
|
|
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;
|
|
|
|
/**
|
|
* 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;
|
|
|
|
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
|
|
// original dimensions to determine if rotation is allowed of not.
|
|
Resources res = Resources.getSystem();
|
|
int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
|
|
* res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
|
|
return originalSmallestWidth >= 600;
|
|
}
|
|
|
|
public static final int REQUEST_NONE = 0;
|
|
public static final int REQUEST_ROTATE = 1;
|
|
public static final int REQUEST_LOCK = 2;
|
|
|
|
private final Activity mActivity;
|
|
private final SharedPreferences mSharedPrefs;
|
|
|
|
private boolean mIgnoreAutoRotateSettings;
|
|
private boolean mHomeRotationEnabled;
|
|
|
|
/**
|
|
* Rotation request made by
|
|
* {@link com.android.launcher3.util.ActivityTracker.SchedulerCallback}.
|
|
* This supersedes any other request.
|
|
*/
|
|
private int mStateHandlerRequest = REQUEST_NONE;
|
|
/**
|
|
* Rotation request made by an app transition
|
|
*/
|
|
private int mCurrentTransitionRequest = REQUEST_NONE;
|
|
/**
|
|
* Rotation request made by a Launcher State
|
|
*/
|
|
private int mCurrentStateRequest = REQUEST_NONE;
|
|
|
|
// This is used to defer setting rotation flags until the activity is being created
|
|
private boolean mInitialized;
|
|
private boolean mDestroyed;
|
|
|
|
private int mLastActivityFlags = -1;
|
|
|
|
public RotationHelper(Activity activity) {
|
|
mActivity = activity;
|
|
|
|
// On large devices we do not handle auto-rotate differently.
|
|
mIgnoreAutoRotateSettings = mActivity.getResources().getBoolean(R.bool.allow_rotation);
|
|
if (!mIgnoreAutoRotateSettings) {
|
|
mSharedPrefs = Utilities.getPrefs(mActivity);
|
|
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
|
|
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
|
|
getAllowRotationDefaultValue());
|
|
} else {
|
|
mSharedPrefs = null;
|
|
}
|
|
|
|
mContentResolver = activity.getContentResolver();
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
mSystemAutoRotateEnabled = autoRotateEnabled == 1;
|
|
}
|
|
|
|
@Override
|
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
|
|
boolean wasRotationEnabled = mHomeRotationEnabled;
|
|
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
|
|
getAllowRotationDefaultValue());
|
|
if (mHomeRotationEnabled != wasRotationEnabled) {
|
|
notifyChange();
|
|
updateAutoRotateSetting();
|
|
}
|
|
}
|
|
|
|
public void setStateHandlerRequest(int request) {
|
|
if (mStateHandlerRequest != request) {
|
|
mStateHandlerRequest = request;
|
|
notifyChange();
|
|
}
|
|
}
|
|
|
|
public void setCurrentTransitionRequest(int request) {
|
|
if (mCurrentTransitionRequest != request) {
|
|
mCurrentTransitionRequest = request;
|
|
notifyChange();
|
|
}
|
|
}
|
|
|
|
public void setCurrentStateRequest(int request) {
|
|
if (mCurrentStateRequest != request) {
|
|
mCurrentStateRequest = request;
|
|
notifyChange();
|
|
}
|
|
}
|
|
|
|
// Used by tests only.
|
|
public void forceAllowRotationForTesting(boolean allowRotation) {
|
|
mIgnoreAutoRotateSettings =
|
|
allowRotation || mActivity.getResources().getBoolean(R.bool.allow_rotation);
|
|
notifyChange();
|
|
}
|
|
|
|
public void initialize() {
|
|
if (!mInitialized) {
|
|
mInitialized = true;
|
|
notifyChange();
|
|
|
|
mContentResolver.registerContentObserver(
|
|
Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
|
|
false, mSystemAutoRotateObserver);
|
|
updateAutoRotateSetting();
|
|
}
|
|
}
|
|
|
|
public void destroy() {
|
|
if (!mDestroyed) {
|
|
mDestroyed = true;
|
|
if (mSharedPrefs != null) {
|
|
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
|
|
}
|
|
mContentResolver.unregisterContentObserver(mSystemAutoRotateObserver);
|
|
}
|
|
}
|
|
|
|
private void notifyChange() {
|
|
if (!mInitialized || mDestroyed) {
|
|
return;
|
|
}
|
|
|
|
final int activityFlags;
|
|
if (mStateHandlerRequest != REQUEST_NONE) {
|
|
activityFlags = mStateHandlerRequest == REQUEST_LOCK ?
|
|
SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED;
|
|
} else if (mCurrentTransitionRequest != REQUEST_NONE) {
|
|
activityFlags = mCurrentTransitionRequest == REQUEST_LOCK ?
|
|
SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED;
|
|
} else if (mCurrentStateRequest == REQUEST_LOCK) {
|
|
activityFlags = SCREEN_ORIENTATION_LOCKED;
|
|
} else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE
|
|
|| mHomeRotationEnabled) {
|
|
activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
|
|
} else {
|
|
// If auto rotation is off, allow rotation on the activity, in case the user is using
|
|
// forced rotation.
|
|
activityFlags = SCREEN_ORIENTATION_NOSENSOR;
|
|
}
|
|
if (activityFlags != mLastActivityFlags) {
|
|
mLastActivityFlags = activityFlags;
|
|
UiThreadHelper.setOrientationAsync(mActivity, activityFlags);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @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, mHomeRotationEnabled=%b,"
|
|
+ " mSystemAutoRotateEnabled=%b]",
|
|
mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags,
|
|
mIgnoreAutoRotateSettings, mHomeRotationEnabled, mSystemAutoRotateEnabled);
|
|
}
|
|
}
|