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:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan" android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified" 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:resizeableActivity="true"
android:resumeWhilePausing="true" android:resumeWhilePausing="true"
android:taskAffinity="" android:taskAffinity=""

View File

@ -49,7 +49,7 @@
android:stateNotNeeded="true" android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan" android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified" 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:resizeableActivity="true"
android:resumeWhilePausing="true" android:resumeWhilePausing="true"
android:taskAffinity="" android:taskAffinity=""

View File

@ -49,7 +49,7 @@
android:stateNotNeeded="true" android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan" android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified" 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:resizeableActivity="true"
android:resumeWhilePausing="true" android:resumeWhilePausing="true"
android:taskAffinity="" android:taskAffinity=""

View File

@ -71,7 +71,7 @@
android:stateNotNeeded="true" android:stateNotNeeded="true"
android:theme="@style/LauncherTheme" android:theme="@style/LauncherTheme"
android:screenOrientation="unspecified" 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:resizeableActivity="true"
android:resumeWhilePausing="true" android:resumeWhilePausing="true"
android:taskAffinity=""/> android:taskAffinity=""/>

View File

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

View File

@ -16,7 +16,6 @@
package com.android.quickstep.util; package com.android.quickstep.util;
import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN; import static android.view.OrientationEventListener.ORIENTATION_UNKNOWN;
import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180; 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.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.PointF; import android.graphics.PointF;
@ -46,7 +44,6 @@ import androidx.annotation.NonNull;
import com.android.launcher3.DeviceProfile; import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler; 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 * This class has initial default state assuming the device and foreground app have
* no ({@link Surface#ROTATION_0} rotation. * 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 String TAG = "RecentsOrientedState";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
@ -125,6 +123,7 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
private int mFlags; private int mFlags;
private int mPreviousRotation = ROTATION_0; private int mPreviousRotation = ROTATION_0;
private boolean mListenersInitialized = false;
// Combined int which encodes the full state. // Combined int which encodes the full state.
private int mStateId = 0; private int mStateId = 0;
@ -152,18 +151,31 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
mFlags = sizeStrategy.rotationSupportedByActivity mFlags = sizeStrategy.rotationSupportedByActivity
? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0; ? 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; mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
mSettingsCache = SettingsCache.INSTANCE.get(mContext); mSettingsCache = SettingsCache.INSTANCE.get(mContext);
initFlags(); 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. * Sets the rotation for the recents activity, which could affect the appearance of task view.
* @see #update(int, int) * @see #update(int, int)
@ -287,14 +299,24 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
updateHomeRotationSetting(); 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 * Initializes any system values and registers corresponding change listeners. It must be
* paired with {@link #destroyListeners()} call * paired with {@link #destroyListeners()} call
*/ */
public void initListeners() { public void initListeners() {
mListenersInitialized = true;
if (isMultipleOrientationSupportedByDevice()) { if (isMultipleOrientationSupportedByDevice()) {
mSharedPrefs.registerOnSharedPreferenceChangeListener(this); initMultipleOrientationListeners();
mSettingsCache.register(ROTATION_SETTING_URI, mRotationChangeListener);
} }
initFlags(); initFlags();
} }
@ -303,9 +325,9 @@ public final class RecentsOrientedState implements SharedPreferences.OnSharedPre
* Unregisters any previously registered listeners. * Unregisters any previously registered listeners.
*/ */
public void destroyListeners() { public void destroyListeners() {
mListenersInitialized = false;
if (isMultipleOrientationSupportedByDevice()) { if (isMultipleOrientationSupportedByDevice()) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this); destroyMultipleOrientationListeners();
mSettingsCache.unregister(ROTATION_SETTING_URI, mRotationChangeListener);
} }
setRotationWatcherEnabled(false); setRotationWatcherEnabled(false);
} }

View File

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

View File

@ -1244,13 +1244,51 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override @Override
public void setInsets(Rect insets) { public void setInsets(Rect insets) {
mInsets.set(insets); mInsets.set(insets);
resetPaddingFromTaskSize();
// Update DeviceProfile dependant state.
DeviceProfile dp = mActivity.getDeviceProfile(); DeviceProfile dp = mActivity.getDeviceProfile();
setOverviewGridEnabled(
mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
// Propagate DeviceProfile change event.
mLiveTileTaskViewSimulator.setDp(dp); mLiveTileTaskViewSimulator.setDp(dp);
mActionsView.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(); DeviceProfile dp = mActivity.getDeviceProfile();
getTaskSize(mTempRect); getTaskSize(mTempRect);
mTaskWidth = mTempRect.width(); 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() { public RecentsOrientedState getPagedViewOrientedState() {
return mOrientationState; return mOrientationState;
} }
@ -3668,7 +3684,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
public void onSecondaryWindowBoundsChanged() { public void onSecondaryWindowBoundsChanged() {
// Invalidate the task view size // Invalidate the task view size
setInsets(mInsets); 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with 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 http://www.apache.org/licenses/LICENSE-2.0
@ -15,13 +15,6 @@
--> -->
<resources> <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 --> <!-- DragController -->
<dimen name="drag_flingToDeleteMinVelocity">-1000dp</dimen> <dimen name="drag_flingToDeleteMinVelocity">-1000dp</dimen>
</resources> </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> <resources>
<!-- Miscellaneous --> <!-- Miscellaneous -->
<bool name="config_largeHeap">false</bool> <bool name="config_largeHeap">false</bool>
<bool name="allow_rotation">false</bool>
<integer name="extracted_color_gradient_alpha">153</integer> <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_icon_size">40dp</dimen>
<dimen name="widget_section_vertical_padding">8dp</dimen> <dimen name="widget_section_vertical_padding">8dp</dimen>
<dimen name="widget_section_horizontal_padding">16dp</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_padding">8dp</dimen>
<dimen name="widget_row_divider">2dp</dimen> <dimen name="widget_row_divider">2dp</dimen>

View File

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

View File

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

View File

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

View File

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

View File

@ -22,6 +22,7 @@ import android.view.VelocityTracker;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import com.android.launcher3.ButtonDropTarget; import com.android.launcher3.ButtonDropTarget;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DropTarget; import com.android.launcher3.DropTarget;
import com.android.launcher3.Launcher; import com.android.launcher3.Launcher;
import com.android.launcher3.R; import com.android.launcher3.R;
@ -35,15 +36,12 @@ public class FlingToDeleteHelper {
private static final float MAX_FLING_DEGREES = 35f; private static final float MAX_FLING_DEGREES = 35f;
private final Launcher mLauncher; private final Launcher mLauncher;
private final int mFlingToDeleteThresholdVelocity;
private ButtonDropTarget mDropTarget; private ButtonDropTarget mDropTarget;
private VelocityTracker mVelocityTracker; private VelocityTracker mVelocityTracker;
public FlingToDeleteHelper(Launcher launcher) { public FlingToDeleteHelper(Launcher launcher) {
mLauncher = launcher; mLauncher = launcher;
mFlingToDeleteThresholdVelocity = launcher.getResources()
.getDimensionPixelSize(R.dimen.drag_flingToDeleteMinVelocity);
} }
public void recordMotionEvent(MotionEvent ev) { public void recordMotionEvent(MotionEvent ev) {
@ -91,12 +89,13 @@ public class FlingToDeleteHelper {
mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity()); mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity());
PointF vel = new PointF(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity()); PointF vel = new PointF(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
float theta = MAX_FLING_DEGREES + 1; 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 // Do a quick dot product test to ensure that we are flinging upwards
PointF upVec = new PointF(0f, -1f); PointF upVec = new PointF(0f, -1f);
theta = getAngleBetweenVectors(vel, upVec); theta = getAngleBetweenVectors(vel, upVec);
} else if (mLauncher.getDeviceProfile().isVerticalBarLayout() && } 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. // Remove icon is on left side instead of top, so check if we are flinging to the left.
PointF leftVec = new PointF(-1f, 0f); PointF leftVec = new PointF(-1f, 0f);
theta = getAngleBetweenVectors(vel, leftVec); 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 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.ALLOW_ROTATION_PREFERENCE_KEY;
import static com.android.launcher3.states.RotationHelper.getAllowRotationDefaultValue;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
@ -38,6 +37,8 @@ import androidx.preference.PreferenceGroup.PreferencePositionCallback;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherFiles; import com.android.launcher3.LauncherFiles;
import com.android.launcher3.R; import com.android.launcher3.R;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
@ -169,12 +170,14 @@ public class SettingsActivity extends FragmentActivity
return !WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS; return !WidgetsModel.GO_DISABLE_NOTIFICATION_DOTS;
case ALLOW_ROTATION_PREFERENCE_KEY: 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. // Launcher supports rotation by default. No need to show this setting.
return false; return false;
} }
// Initialize the UI once // Initialize the UI once
preference.setDefaultValue(getAllowRotationDefaultValue()); preference.setDefaultValue(false);
return true; return true;
case FLAGS_PREFERENCE_KEY: 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_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 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;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; 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.Utilities;
import com.android.launcher3.util.UiThreadHelper; import com.android.launcher3.util.UiThreadHelper;
/** /**
* Utility class to manage launcher rotation * Utility class to manage launcher rotation
*/ */
public class RotationHelper implements OnSharedPreferenceChangeListener { public class RotationHelper implements OnSharedPreferenceChangeListener,
DeviceProfile.OnDeviceProfileChangeListener {
private static final String TAG = "RotationHelper"; private static final String TAG = "RotationHelper";
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation"; 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_NONE = 0;
public static final int REQUEST_ROTATE = 1; public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2; public static final int REQUEST_LOCK = 2;
private Activity mActivity; private BaseActivity mActivity;
private final SharedPreferences mSharedPrefs; private SharedPreferences mSharedPrefs = null;
private boolean mIgnoreAutoRotateSettings; private boolean mIgnoreAutoRotateSettings;
private boolean mForceAllowRotationForTesting;
private boolean mHomeRotationEnabled; private boolean mHomeRotationEnabled;
/** /**
@ -79,18 +70,25 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
// Initialize mLastActivityFlags to a value not used by SCREEN_ORIENTATION flags // Initialize mLastActivityFlags to a value not used by SCREEN_ORIENTATION flags
private int mLastActivityFlags = -999; private int mLastActivityFlags = -999;
public RotationHelper(Activity activity) { public RotationHelper(BaseActivity activity) {
mActivity = activity; mActivity = activity;
}
private void setIgnoreAutoRotateSettings(boolean ignoreAutoRotateSettings) {
// On large devices we do not handle auto-rotate differently. // On large devices we do not handle auto-rotate differently.
mIgnoreAutoRotateSettings = mActivity.getResources().getBoolean(R.bool.allow_rotation); mIgnoreAutoRotateSettings = ignoreAutoRotateSettings;
if (!mIgnoreAutoRotateSettings) { if (!mIgnoreAutoRotateSettings) {
mSharedPrefs = Utilities.getPrefs(mActivity); if (mSharedPrefs == null) {
mSharedPrefs.registerOnSharedPreferenceChangeListener(this); mSharedPrefs = Utilities.getPrefs(mActivity);
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
}
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue()); mActivity.getDeviceProfile().allowRotation);
} else { } else {
mSharedPrefs = null; if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
mSharedPrefs = null;
}
} }
} }
@ -99,12 +97,21 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
if (mDestroyed) return; if (mDestroyed) return;
boolean wasRotationEnabled = mHomeRotationEnabled; boolean wasRotationEnabled = mHomeRotationEnabled;
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
getAllowRotationDefaultValue()); mActivity.getDeviceProfile().allowRotation);
if (mHomeRotationEnabled != wasRotationEnabled) { if (mHomeRotationEnabled != wasRotationEnabled) {
notifyChange(); notifyChange();
} }
} }
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
boolean ignoreAutoRotateSettings = dp.allowRotation;
if (mIgnoreAutoRotateSettings != ignoreAutoRotateSettings) {
setIgnoreAutoRotateSettings(ignoreAutoRotateSettings);
notifyChange();
}
}
public void setStateHandlerRequest(int request) { public void setStateHandlerRequest(int request) {
if (mStateHandlerRequest != request) { if (mStateHandlerRequest != request) {
mStateHandlerRequest = request; mStateHandlerRequest = request;
@ -128,14 +135,15 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
// Used by tests only. // Used by tests only.
public void forceAllowRotationForTesting(boolean allowRotation) { public void forceAllowRotationForTesting(boolean allowRotation) {
mIgnoreAutoRotateSettings = mForceAllowRotationForTesting = allowRotation;
allowRotation || mActivity.getResources().getBoolean(R.bool.allow_rotation);
notifyChange(); notifyChange();
} }
public void initialize() { public void initialize() {
if (!mInitialized) { if (!mInitialized) {
mInitialized = true; mInitialized = true;
setIgnoreAutoRotateSettings(mActivity.getDeviceProfile().allowRotation);
mActivity.addOnDeviceProfileChangeListener(this);
notifyChange(); notifyChange();
} }
} }
@ -143,6 +151,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
public void destroy() { public void destroy() {
if (!mDestroyed) { if (!mDestroyed) {
mDestroyed = true; mDestroyed = true;
mActivity.removeOnDeviceProfileChangeListener(this);
mActivity = null; mActivity = null;
if (mSharedPrefs != null) { if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this); mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
@ -165,7 +174,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener {
} else if (mCurrentStateRequest == REQUEST_LOCK) { } else if (mCurrentStateRequest == REQUEST_LOCK) {
activityFlags = SCREEN_ORIENTATION_LOCKED; activityFlags = SCREEN_ORIENTATION_LOCKED;
} else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE } else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE
|| mHomeRotationEnabled) { || mHomeRotationEnabled || mForceAllowRotationForTesting) {
activityFlags = SCREEN_ORIENTATION_UNSPECIFIED; activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
} else { } else {
// If auto rotation is off, allow rotation on the activity, in case the user is using // 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 @Override
public String toString() { public String toString() {
return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d," return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d, "
+ " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mHomeRotationEnabled=%b]", + "mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, "
+ "mHomeRotationEnabled=%b, mForceAllowRotationForTesting=%b]",
mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags, mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags,
mIgnoreAutoRotateSettings, mHomeRotationEnabled); mIgnoreAutoRotateSettings, mHomeRotationEnabled, mForceAllowRotationForTesting);
} }
} }

View File

@ -47,7 +47,6 @@ public final class WidgetsListTableViewHolderBinder
private int mMaxSpansPerRow = 4; private int mMaxSpansPerRow = 4;
private final LayoutInflater mLayoutInflater; private final LayoutInflater mLayoutInflater;
private final int mIndent;
private final OnClickListener mIconClickListener; private final OnClickListener mIconClickListener;
private final OnLongClickListener mIconLongClickListener; private final OnLongClickListener mIconLongClickListener;
private final WidgetPreviewLoader mWidgetPreviewLoader; private final WidgetPreviewLoader mWidgetPreviewLoader;
@ -62,7 +61,6 @@ public final class WidgetsListTableViewHolderBinder
WidgetPreviewLoader widgetPreviewLoader, WidgetPreviewLoader widgetPreviewLoader,
WidgetsListAdapter listAdapter) { WidgetsListAdapter listAdapter) {
mLayoutInflater = layoutInflater; mLayoutInflater = layoutInflater;
mIndent = context.getResources().getDimensionPixelSize(R.dimen.widget_section_indent);
mIconClickListener = iconClickListener; mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener; mIconLongClickListener = iconLongClickListener;
mWidgetPreviewLoader = widgetPreviewLoader; mWidgetPreviewLoader = widgetPreviewLoader;
@ -90,11 +88,6 @@ public final class WidgetsListTableViewHolderBinder
ViewGroup container = (ViewGroup) mLayoutInflater.inflate( ViewGroup container = (ViewGroup) mLayoutInflater.inflate(
R.layout.widgets_table_container, parent, false); 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); return new WidgetsRowViewHolder(container);
} }

View File

@ -109,7 +109,7 @@
<activity <activity
android:name="com.android.launcher3.testcomponent.TestLauncherActivity" android:name="com.android.launcher3.testcomponent.TestLauncherActivity"
android:clearTaskOnLaunch="true" 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:enabled="false"
android:label="Test launcher" android:label="Test launcher"
android:launchMode="singleTask" android:launchMode="singleTask"