Merge "Handle config changes in Launcher" into sc-dev

This commit is contained in:
TreeHugger Robot 2021-05-11 10:58:48 +00:00 committed by Android (Google) Code Review
commit 95ff5cf63e
24 changed files with 160 additions and 171 deletions

View File

@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""

View File

@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|uiMode"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density|uiMode"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""

View File

@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""

View File

@ -71,7 +71,7 @@
android:stateNotNeeded="true"
android:theme="@style/LauncherTheme"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""/>

View File

@ -26,7 +26,7 @@
android:key="pref_allowRotation"
android:title="@string/allow_rotation_title"
android:summary="@string/allow_rotation_desc"
android:defaultValue="@bool/allow_rotation"
android:defaultValue="false"
android:persistent="true" />
</PreferenceScreen>

View File

@ -16,7 +16,6 @@
package com.android.quickstep.util;
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
@ -31,7 +30,6 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
@ -46,7 +44,6 @@ import androidx.annotation.NonNull;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
@ -67,7 +64,8 @@ import java.util.function.IntConsumer;
* This class has initial default state assuming the device and foreground app have
* no ({@link Surface#ROTATION_0} rotation.
*/
public final class RecentsOrientedState implements SharedPreferences.OnSharedPreferenceChangeListener {
public final class RecentsOrientedState implements
SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "RecentsOrientedState";
private static final boolean DEBUG = false;
@ -125,6 +123,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
private int mFlags;
private int mPreviousRotation = ROTATION_0;
private boolean mListenersInitialized = false;
// Combined int which encodes the full state.
private int mStateId = 0;
@ -152,18 +151,31 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
mFlags = sizeStrategy.rotationSupportedByActivity
? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
Resources res = context.getResources();
int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
* res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
if (originalSmallestWidth < 600 && !mContext.getResources().getBoolean(
R.bool.allow_rotation)) {
mFlags |= FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY;
}
mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
mSettingsCache = SettingsCache.INSTANCE.get(mContext);
initFlags();
}
/**
* Sets the device profile for the current state.
*/
public void setDeviceProfile(DeviceProfile deviceProfile) {
boolean oldMultipleOrientationsSupported = isMultipleOrientationSupportedByDevice();
setFlag(FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY, !deviceProfile.allowRotation);
if (mListenersInitialized) {
boolean newMultipleOrientationsSupported = isMultipleOrientationSupportedByDevice();
// If isMultipleOrientationSupportedByDevice is changed, init or destroy listeners
// accordingly.
if (newMultipleOrientationsSupported != oldMultipleOrientationsSupported) {
if (newMultipleOrientationsSupported) {
initMultipleOrientationListeners();
} else {
destroyMultipleOrientationListeners();
}
}
}
}
/**
* Sets the rotation for the recents activity, which could affect the appearance of task view.
* @see #update(int, int)
@ -287,14 +299,24 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
updateHomeRotationSetting();
}
private void initMultipleOrientationListeners() {
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
mSettingsCache.register(ROTATION_SETTING_URI, mRotationChangeListener);
}
private void destroyMultipleOrientationListeners() {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
mSettingsCache.unregister(ROTATION_SETTING_URI, mRotationChangeListener);
}
/**
* Initializes any system values and registers corresponding change listeners. It must be
* paired with {@link #destroyListeners()} call
*/
public void initListeners() {
mListenersInitialized = true;
if (isMultipleOrientationSupportedByDevice()) {
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
mSettingsCache.register(ROTATION_SETTING_URI, mRotationChangeListener);
initMultipleOrientationListeners();
}
initFlags();
}
@ -303,9 +325,9 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
* Unregisters any previously registered listeners.
*/
public void destroyListeners() {
mListenersInitialized = false;
if (isMultipleOrientationSupportedByDevice()) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
mSettingsCache.unregister(ROTATION_SETTING_URI, mRotationChangeListener);
destroyMultipleOrientationListeners();
}
setRotationWatcherEnabled(false);
}

View File

@ -112,6 +112,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
public void setDp(DeviceProfile dp) {
mDp = dp;
mLayoutValid = false;
mOrientationState.setDeviceProfile(dp);
}
/**

View File

@ -1244,13 +1244,51 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override
public void setInsets(Rect insets) {
mInsets.set(insets);
resetPaddingFromTaskSize();
// Update DeviceProfile dependant state.
DeviceProfile dp = mActivity.getDeviceProfile();
setOverviewGridEnabled(
mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
// Propagate DeviceProfile change event.
mLiveTileTaskViewSimulator.setDp(dp);
mActionsView.setDp(dp);
mOrientationState.setDeviceProfile(dp);
// Update RecentsView adn TaskView's DeviceProfile dependent layout.
updateOrientationHandler();
}
private void resetPaddingFromTaskSize() {
private void updateOrientationHandler() {
// Handle orientation changes.
mOrientationHandler = mOrientationState.getOrientationHandler();
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
setLayoutDirection(mIsRtl
? View.LAYOUT_DIRECTION_RTL
: View.LAYOUT_DIRECTION_LTR);
mClearAllButton.setLayoutDirection(mIsRtl
? View.LAYOUT_DIRECTION_LTR
: View.LAYOUT_DIRECTION_RTL);
mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
mActivity.getDragLayer().recreateControllers();
boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
|| mOrientationState.getRecentsActivityRotation() != ROTATION_0;
mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
!mOrientationState.canRecentsActivityRotate() && isInLandscape);
// Update TaskView's DeviceProfile dependent layout.
updateChildTaskOrientations();
// Recalculate DeviceProfile dependent layout.
updateSizeAndPadding();
requestLayout();
// Reapply the current page to update page scrolls.
setCurrentPage(mCurrentPage);
}
// Update task size and padding that are dependent on DeviceProfile and insets.
private void updateSizeAndPadding() {
DeviceProfile dp = mActivity.getDeviceProfile();
getTaskSize(mTempRect);
mTaskWidth = mTempRect.width();
@ -2566,28 +2604,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
private void updateOrientationHandler() {
mOrientationHandler = mOrientationState.getOrientationHandler();
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
setLayoutDirection(mIsRtl
? View.LAYOUT_DIRECTION_RTL
: View.LAYOUT_DIRECTION_LTR);
mClearAllButton.setLayoutDirection(mIsRtl
? View.LAYOUT_DIRECTION_LTR
: View.LAYOUT_DIRECTION_RTL);
mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
mActivity.getDragLayer().recreateControllers();
boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
|| mOrientationState.getRecentsActivityRotation() != ROTATION_0;
mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
!mOrientationState.canRecentsActivityRotate() && isInLandscape);
updateChildTaskOrientations();
resetPaddingFromTaskSize();
requestLayout();
// Reapply the current page to update page scrolls.
setCurrentPage(mCurrentPage);
}
public RecentsOrientedState getPagedViewOrientedState() {
return mOrientationState;
}
@ -3668,7 +3684,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
public void onSecondaryWindowBoundsChanged() {
// Invalidate the task view size
setInsets(mInsets);
requestLayout();
}
/**

View File

@ -1,3 +0,0 @@
<resources>
<bool name="allow_rotation">true</bool>
</resources>

View File

@ -3,7 +3,7 @@
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
You may obtain a copy of the License at`
http://www.apache.org/licenses/LICENSE-2.0
@ -15,13 +15,6 @@
-->
<resources>
<!-- All Apps -->
<dimen name="all_apps_background_canvas_width">850dp</dimen>
<dimen name="all_apps_background_canvas_height">525dp</dimen>
<!-- Widget tray -->
<dimen name="widget_section_indent">56dp</dimen>
<!-- DragController -->
<dimen name="drag_flingToDeleteMinVelocity">-1000dp</dimen>
</resources>

View File

@ -1,6 +0,0 @@
<resources>
<!-- All Apps & Widgets -->
<!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
<integer name="config_workspaceSpringLoadShrinkPercentage">90</integer>
</resources>

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 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.
-->
<resources>
<!-- All Apps -->
<dimen name="all_apps_empty_search_message_top_offset">64dp</dimen>
<dimen name="all_apps_empty_search_bg_top_offset">180dp</dimen>
<!-- Fast scroll -->
<dimen name="fastscroll_popup_width">75dp</dimen>
<dimen name="fastscroll_popup_height">62dp</dimen>
<dimen name="fastscroll_popup_padding">13dp</dimen>
<dimen name="fastscroll_popup_text_size">32dp</dimen>
</resources>

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2008 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.
*/
-->
<resources>
<!-- Workspace -->
<style name="DropTargetButton" parent="DropTargetButtonBase">
<item name="android:paddingLeft">60dp</item>
<item name="android:paddingRight">60dp</item>
<item name="android:shadowDx">0.0</item>
<item name="android:shadowDy">0.0</item>
<item name="android:shadowRadius">2.0</item>
</style>
</resources>

View File

@ -1,7 +1,6 @@
<resources>
<!-- Miscellaneous -->
<bool name="config_largeHeap">false</bool>
<bool name="allow_rotation">false</bool>
<integer name="extracted_color_gradient_alpha">153</integer>

View File

@ -138,7 +138,6 @@
<dimen name="widget_section_icon_size">40dp</dimen>
<dimen name="widget_section_vertical_padding">8dp</dimen>
<dimen name="widget_section_horizontal_padding">16dp</dimen>
<dimen name="widget_section_indent">0dp</dimen>
<dimen name="widget_row_padding">8dp</dimen>
<dimen name="widget_row_divider">2dp</dimen>

View File

@ -45,7 +45,7 @@
android:key="pref_allowRotation"
android:title="@string/allow_rotation_title"
android:summary="@string/allow_rotation_desc"
android:defaultValue="@bool/allow_rotation"
android:defaultValue="false"
android:persistent="true"
launcher:logIdOn="615"
launcher:logIdOff="616" />

View File

@ -74,7 +74,6 @@ public abstract class ButtonDropTarget extends TextView
protected final Launcher mLauncher;
private int mBottomDragPadding;
protected DropTargetBar mDropTargetBar;
/** Whether this drop target is active for the current drag */
@ -103,7 +102,6 @@ public abstract class ButtonDropTarget extends TextView
mLauncher = Launcher.getLauncher(context);
Resources resources = getResources();
mBottomDragPadding = resources.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
}
@ -276,7 +274,7 @@ public abstract class ButtonDropTarget extends TextView
@Override
public void getHitRectRelativeToDragLayer(android.graphics.Rect outRect) {
super.getHitRect(outRect);
outRect.bottom += mBottomDragPadding;
outRect.bottom += mLauncher.getDeviceProfile().dropTargetDragPaddingPx;
sTempCords[0] = sTempCords[1] = 0;
mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, sTempCords);

View File

@ -16,10 +16,12 @@
package com.android.launcher3;
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static com.android.launcher3.ResourceUtils.pxFromDp;
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
import android.content.Context;
@ -61,6 +63,7 @@ public class DeviceProfile {
public final boolean isPhone;
public final boolean transposeLayoutWithOrientation;
public final boolean isTwoPanels;
public final boolean allowRotation;
// Device properties in current orientation
public final boolean isLandscape;
@ -172,6 +175,8 @@ public class DeviceProfile {
// Drop Target
public int dropTargetBarSizePx;
public int dropTargetDragPaddingPx;
public int dropTargetTextSizePx;
// Insets
private final Rect mInsets = new Rect();
@ -190,6 +195,9 @@ public class DeviceProfile {
// How much of the bottom inset is due to Taskbar rather than other system elements.
public int nonOverlappingTaskbarInset;
// DragController
public int flingToDeleteThresholdVelocity;
DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
boolean useTwoPanels) {
@ -210,7 +218,12 @@ public class DeviceProfile {
int nonFinalAvailableHeightPx = windowBounds.availableSize.y;
mInfo = info;
isTablet = info.isTablet(windowBounds);
// 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.
float originalSmallestWidth = dpiFromPx(Math.min(widthPx, heightPx), DENSITY_DEVICE_STABLE);
allowRotation = originalSmallestWidth >= MIN_TABLET_WIDTH;
// Tablet UI does not support emulated landscape.
isTablet = allowRotation && info.isTablet(windowBounds);
isPhone = !isTablet;
isTwoPanels = isTablet && useTwoPanels;
@ -287,7 +300,11 @@ public class DeviceProfile {
iconDrawablePaddingOriginalPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding);
dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size);
dropTargetDragPaddingPx = res.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
dropTargetTextSizePx = res.getDimensionPixelSize(R.dimen.drop_target_text_size);
workspaceSpringLoadedBottomSpace =
res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
@ -354,6 +371,9 @@ public class DeviceProfile {
}
updateWorkspacePadding();
flingToDeleteThresholdVelocity = res.getDimensionPixelSize(
R.dimen.drag_flingToDeleteMinVelocity);
// This is done last, after iconSizePx is calculated above.
Path dotPath = GraphicsUtils.getShapePath(DEFAULT_DOT_SIZE);
mDotRendererWorkSpace = new DotRenderer(iconSizePx, dotPath, DEFAULT_DOT_SIZE);
@ -821,6 +841,7 @@ public class DeviceProfile {
writer.println(prefix + "DeviceProfile:");
writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
writer.println(prefix + "\tallowRotation:" + allowRotation);
writer.println(prefix + "\tisTablet:" + isTablet);
writer.println(prefix + "\tisPhone:" + isPhone);
writer.println(prefix + "\ttransposeLayoutWithOrientation:"

View File

@ -25,6 +25,7 @@ import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewDebug;
@ -114,6 +115,7 @@ public class DropTargetBar extends FrameLayout
}
setLayoutParams(lp);
for (ButtonDropTarget button : mDropTargets) {
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.dropTargetTextSizePx);
button.setToolTipLocation(tooltipLocation);
}
}

View File

@ -22,6 +22,7 @@ import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import com.android.launcher3.ButtonDropTarget;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
@ -35,15 +36,12 @@ public class FlingToDeleteHelper {
private static final float MAX_FLING_DEGREES = 35f;
private final Launcher mLauncher;
private final int mFlingToDeleteThresholdVelocity;
private ButtonDropTarget mDropTarget;
private VelocityTracker mVelocityTracker;
public FlingToDeleteHelper(Launcher launcher) {
mLauncher = launcher;
mFlingToDeleteThresholdVelocity = launcher.getResources()
.getDimensionPixelSize(R.dimen.drag_flingToDeleteMinVelocity);
}
public void recordMotionEvent(MotionEvent ev) {
@ -91,12 +89,13 @@ public class FlingToDeleteHelper {
mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
PointF vel = new PointF(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
float theta = MAX_FLING_DEGREES + 1;
if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) {
DeviceProfile deviceProfile = mLauncher.getDeviceProfile();
if (mVelocityTracker.getYVelocity() < deviceProfile.flingToDeleteThresholdVelocity) {
// Do a quick dot product test to ensure that we are flinging upwards
PointF upVec = new PointF(0f, -1f);
theta = getAngleBetweenVectors(vel, upVec);
} else if (mLauncher.getDeviceProfile().isVerticalBarLayout() &&
mVelocityTracker.getXVelocity() < mFlingToDeleteThresholdVelocity) {
mVelocityTracker.getXVelocity() < deviceProfile.flingToDeleteThresholdVelocity) {
// Remove icon is on left side instead of top, so check if we are flinging to the left.
PointF leftVec = new PointF(-1f, 0f);
theta = getAngleBetweenVectors(vel, leftVec);

View File

@ -19,7 +19,6 @@ package com.android.launcher3.settings;
import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS;
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
import static com.android.launcher3.states.RotationHelper.getAllowRotationDefaultValue;
import android.content.SharedPreferences;
import android.os.Bundle;
@ -38,6 +37,8 @@ import androidx.preference.PreferenceGroup.PreferencePositionCallback;
import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherFiles;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@ -169,12 +170,14 @@ public class SettingsActivity extends FragmentActivity
return !WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS;
case ALLOW_ROTATION_PREFERENCE_KEY:
if (getResources().getBoolean(R.bool.allow_rotation)) {
DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE.get(
getContext()).getDeviceProfile(getContext());
if (deviceProfile.allowRotation) {
// Launcher supports rotation by default. No need to show this setting.
return false;
}
// Initialize the UI once
preference.setDefaultValue(getAllowRotationDefaultValue());
preference.setDefaultValue(false);
return true;
case FLAGS_PREFERENCE_KEY:

View File

@ -18,43 +18,34 @@ 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.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Resources;
import com.android.launcher3.R;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.UiThreadHelper;
/**
* Utility class to manage launcher rotation
*/
public class RotationHelper implements OnSharedPreferenceChangeListener {
public class RotationHelper implements OnSharedPreferenceChangeListener,
DeviceProfile.OnDeviceProfileChangeListener {
private static final String TAG = "RotationHelper";
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
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 Activity mActivity;
private final SharedPreferences mSharedPrefs;
private BaseActivity mActivity;
private SharedPreferences mSharedPrefs = null;
private boolean mIgnoreAutoRotateSettings;
private boolean mForceAllowRotationForTesting;
private boolean mHomeRotationEnabled;
/**
@ -79,18 +70,25 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
// Initialize mLastActivityFlags to a value not used by SCREEN_ORIENTATION flags
private int mLastActivityFlags = -999;
public RotationHelper(Activity activity) {
public RotationHelper(BaseActivity activity) {
mActivity = activity;
}
private void setIgnoreAutoRotateSettings(boolean ignoreAutoRotateSettings) {
// On large devices we do not handle auto-rotate differently.
mIgnoreAutoRotateSettings = mActivity.getResources().getBoolean(R.bool.allow_rotation);
mIgnoreAutoRotateSettings = ignoreAutoRotateSettings;
if (!mIgnoreAutoRotateSettings) {
mSharedPrefs = Utilities.getPrefs(mActivity);
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
if (mSharedPrefs == null) {
mSharedPrefs = Utilities.getPrefs(mActivity);
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
}
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue());
mActivity.getDeviceProfile().allowRotation);
} else {
mSharedPrefs = null;
if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
mSharedPrefs = null;
}
}
}
@ -99,12 +97,21 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
if (mDestroyed) return;
boolean wasRotationEnabled = mHomeRotationEnabled;
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue());
mActivity.getDeviceProfile().allowRotation);
if (mHomeRotationEnabled != wasRotationEnabled) {
notifyChange();
}
}
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
boolean ignoreAutoRotateSettings = dp.allowRotation;
if (mIgnoreAutoRotateSettings != ignoreAutoRotateSettings) {
setIgnoreAutoRotateSettings(ignoreAutoRotateSettings);
notifyChange();
}
}
public void setStateHandlerRequest(int request) {
if (mStateHandlerRequest != request) {
mStateHandlerRequest = request;
@ -128,14 +135,15 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
// Used by tests only.
public void forceAllowRotationForTesting(boolean allowRotation) {
mIgnoreAutoRotateSettings =
allowRotation || mActivity.getResources().getBoolean(R.bool.allow_rotation);
mForceAllowRotationForTesting = allowRotation;
notifyChange();
}
public void initialize() {
if (!mInitialized) {
mInitialized = true;
setIgnoreAutoRotateSettings(mActivity.getDeviceProfile().allowRotation);
mActivity.addOnDeviceProfileChangeListener(this);
notifyChange();
}
}
@ -143,6 +151,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
public void destroy() {
if (!mDestroyed) {
mDestroyed = true;
mActivity.removeOnDeviceProfileChangeListener(this);
mActivity = null;
if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
@ -165,7 +174,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
} else if (mCurrentStateRequest == REQUEST_LOCK) {
activityFlags = SCREEN_ORIENTATION_LOCKED;
} else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE
|| mHomeRotationEnabled) {
|| mHomeRotationEnabled || mForceAllowRotationForTesting) {
activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
} else {
// If auto rotation is off, allow rotation on the activity, in case the user is using
@ -191,9 +200,10 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
@Override
public String toString() {
return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d,"
+ " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mHomeRotationEnabled=%b]",
return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d, "
+ "mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, "
+ "mHomeRotationEnabled=%b, mForceAllowRotationForTesting=%b]",
mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags,
mIgnoreAutoRotateSettings, mHomeRotationEnabled);
mIgnoreAutoRotateSettings, mHomeRotationEnabled, mForceAllowRotationForTesting);
}
}

View File

@ -47,7 +47,6 @@ public final class WidgetsListTableViewHolderBinder
private int mMaxSpansPerRow = 4;
private final LayoutInflater mLayoutInflater;
private final int mIndent;
private final OnClickListener mIconClickListener;
private final OnLongClickListener mIconLongClickListener;
private final WidgetPreviewLoader mWidgetPreviewLoader;
@ -62,7 +61,6 @@ public final class WidgetsListTableViewHolderBinder
WidgetPreviewLoader widgetPreviewLoader,
WidgetsListAdapter listAdapter) {
mLayoutInflater = layoutInflater;
mIndent = context.getResources().getDimensionPixelSize(R.dimen.widget_section_indent);
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
mWidgetPreviewLoader = widgetPreviewLoader;
@ -90,11 +88,6 @@ public final class WidgetsListTableViewHolderBinder
ViewGroup container = (ViewGroup) mLayoutInflater.inflate(
R.layout.widgets_table_container, parent, false);
// if the end padding is 0, then container view (horizontal scroll view) doesn't respect
// the end of the linear layout width + the start padding and doesn't allow scrolling.
container.findViewById(R.id.widgets_table).setPaddingRelative(mIndent, 0, 1, 0);
return new WidgetsRowViewHolder(container);
}

View File

@ -109,7 +109,7 @@
<activity
android:name="com.android.launcher3.testcomponent.TestLauncherActivity"
android:clearTaskOnLaunch="true"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:enabled="false"
android:label="Test launcher"
android:launchMode="singleTask"