Merge remote-tracking branch 'aosp/android12L-release' into 12.1-dev

This commit is contained in:
Suphon Thanakornpakapong
2022-05-08 18:41:13 +07:00
825 changed files with 38324 additions and 29270 deletions
+275 -136
View File
@@ -18,14 +18,10 @@
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.Utilities.pxFromSp;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -35,11 +31,8 @@ import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.util.DisplayMetrics;
import android.view.Surface;
import android.view.WindowInsets;
import android.view.WindowManager;
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.DevicePaddings.DevicePadding;
@@ -47,6 +40,7 @@ import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.WindowBounds;
@@ -60,6 +54,8 @@ import app.lawnchair.preferences2.PreferenceManager2;
public class DeviceProfile {
private static final int DEFAULT_DOT_SIZE = 100;
// Ratio of empty space, qsb should take up to appear visually centered.
private static final float QSB_CENTER_FACTOR = .325f;
public final InvariantDeviceProfile inv;
private final Info mInfo;
@@ -70,7 +66,6 @@ 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;
@@ -86,6 +81,7 @@ public class DeviceProfile {
public final float aspectRatio;
public final boolean isScalableGrid;
private final int mTypeIndex;
/**
* The maximum amount of left/right workspace padding as a percentage of the screen width.
@@ -103,10 +99,10 @@ public class DeviceProfile {
private static final int PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER = 4;
// Workspace
public final int desiredWorkspaceLeftRightOriginalPx;
public int desiredWorkspaceLeftRightMarginPx;
public final int cellLayoutBorderSpacingOriginalPx;
public int cellLayoutBorderSpacingPx;
public final int desiredWorkspaceHorizontalMarginOriginalPx;
public int desiredWorkspaceHorizontalMarginPx;
public Point cellLayoutBorderSpaceOriginalPx;
public Point cellLayoutBorderSpacePx;
public final int cellLayoutPaddingLeftRightPx;
public final int cellLayoutBottomPaddingPx;
public final int edgeMarginPx;
@@ -143,7 +139,8 @@ public class DeviceProfile {
public int folderIconOffsetYPx;
// Folder content
public int folderCellLayoutBorderSpacingPx;
public Point folderCellLayoutBorderSpacePx;
public int folderCellLayoutBorderSpaceOriginalPx;
public int folderContentPaddingLeftRight;
public int folderContentPaddingTop;
@@ -168,26 +165,38 @@ public class DeviceProfile {
// Start is the side next to the nav bar, end is the side next to the workspace
public final int hotseatBarSidePaddingStartPx;
public final int hotseatBarSidePaddingEndPx;
public final int hotseatQsbHeight;
public final float qsbBottomMarginOriginalPx;
public int qsbBottomMarginPx;
// All apps
public Point allAppsCellSpacePx;
public int allAppsOpenVerticalTranslate;
public int allAppsCellHeightPx;
public int allAppsCellWidthPx;
public int allAppsIconSizePx;
public int allAppsIconDrawablePaddingPx;
public int allAppsLeftRightPadding;
public final int numShownAllAppsColumns;
public float allAppsIconTextSizePx;
private float allAppsCellHeightMultiplier;
// Overview
public final boolean overviewShowAsGrid;
public int overviewTaskMarginPx;
public int overviewTaskMarginGridPx;
public int overviewTaskIconSizePx;
public int overviewTaskIconDrawableSizePx;
public int overviewTaskIconDrawableSizeGridPx;
public int overviewTaskThumbnailTopMarginPx;
public final int overviewActionsMarginThreeButtonPx;
public final int overviewActionsMarginGesturePx;
public final int overviewActionsTopMarginGesturePx;
public final int overviewActionsBottomMarginGesturePx;
public final int overviewActionsButtonSpacing;
public int overviewPageSpacing;
public int overviewRowSpacing;
public int overviewGridSideMargin;
// Widgets
public final PointF appWidgetScale = new PointF(1.0f, 1.0f);
@@ -208,22 +217,19 @@ public class DeviceProfile {
public DotRenderer mDotRendererWorkSpace;
public DotRenderer mDotRendererAllApps;
private final Context mContext;
// Taskbar
// Taskbar
public boolean isTaskbarPresent;
// Whether Taskbar will inset the bottom of apps by taskbarSize.
public boolean isTaskbarPresentInApps;
public int taskbarSize;
// How much of the bottom inset is due to Taskbar rather than other system elements.
public int nonOverlappingTaskbarInset;
// DragController
public int flingToDeleteThresholdVelocity;
/** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */
DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
boolean useTwoPanels) {
mContext = context;
PreferenceManager2 preferenceManager2 = PreferenceManager2.INSTANCE.get(context);
allAppsCellHeightMultiplier = PreferenceExtensionsKt.firstBlocking(preferenceManager2.getDrawerCellHeightFactor());
@@ -240,15 +246,10 @@ public class DeviceProfile {
widthPx = windowBounds.bounds.width();
heightPx = windowBounds.bounds.height();
availableWidthPx = windowBounds.availableSize.x;
int nonFinalAvailableHeightPx = windowBounds.availableSize.y;
availableHeightPx = windowBounds.availableSize.y;
mInfo = info;
// 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);
isTablet = info.isTablet(windowBounds);
isPhone = !isTablet;
isTwoPanels = isTablet && useTwoPanels;
@@ -262,31 +263,31 @@ public class DeviceProfile {
mMetrics = context.getResources().getDisplayMetrics();
final Resources res = context.getResources();
isTaskbarPresent = isTablet && FeatureFlags.ENABLE_TASKBAR.get();
if (isTaskbarPresent) {
// Taskbar will be added later, but provides bottom insets that we should subtract
// from availableHeightPx.
taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size);
WindowInsets windowInsets =
context.createWindowContext(
context.getSystemService(DisplayManager.class).getDisplay(mInfo.id),
TYPE_APPLICATION, null)
.getSystemService(WindowManager.class)
.getCurrentWindowMetrics().getWindowInsets();
nonOverlappingTaskbarInset = taskbarSize - windowInsets.getSystemWindowInsetBottom();
if (nonOverlappingTaskbarInset > 0) {
nonFinalAvailableHeightPx -= nonOverlappingTaskbarInset;
if (isTwoPanels) {
if (isLandscape) {
mTypeIndex = InvariantDeviceProfile.INDEX_TWO_PANEL_LANDSCAPE;
} else {
mTypeIndex = InvariantDeviceProfile.INDEX_TWO_PANEL_PORTRAIT;
}
} else {
if (isLandscape) {
mTypeIndex = InvariantDeviceProfile.INDEX_LANDSCAPE;
} else {
mTypeIndex = InvariantDeviceProfile.INDEX_DEFAULT;
}
}
availableHeightPx = nonFinalAvailableHeightPx;
hotseatQsbHeight = res.getDimensionPixelSize(R.dimen.qsb_widget_height);
isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS
&& FeatureFlags.ENABLE_TASKBAR.get();
if (isTaskbarPresent) {
taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size);
}
edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
desiredWorkspaceLeftRightMarginPx = isVerticalBarLayout() ? 0 : isScalableGrid
? res.getDimensionPixelSize(R.dimen.scalable_grid_left_right_margin)
: res.getDimensionPixelSize(R.dimen.dynamic_grid_left_right_margin);
desiredWorkspaceLeftRightOriginalPx = desiredWorkspaceLeftRightMarginPx;
desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
allAppsOpenVerticalTranslate = res.getDimensionPixelSize(
R.dimen.all_apps_open_vertical_translate);
@@ -296,9 +297,14 @@ public class DeviceProfile {
res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right);
folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_content_padding_top);
setCellLayoutBorderSpacing(pxFromDp(inv.borderSpacing, mMetrics, 1f));
cellLayoutBorderSpacingOriginalPx = cellLayoutBorderSpacingPx;
folderCellLayoutBorderSpacingPx = cellLayoutBorderSpacingPx;
cellLayoutBorderSpacePx = getCellLayoutBorderSpace(inv);
allAppsCellSpacePx = new Point(
pxFromDp(inv.borderSpaces[InvariantDeviceProfile.INDEX_ALL_APPS].x, mMetrics, 1f),
pxFromDp(inv.borderSpaces[InvariantDeviceProfile.INDEX_ALL_APPS].y, mMetrics, 1f));
cellLayoutBorderSpaceOriginalPx = new Point(cellLayoutBorderSpacePx);
folderCellLayoutBorderSpaceOriginalPx = pxFromDp(inv.folderBorderSpace, mMetrics, 1f);
folderCellLayoutBorderSpacePx = new Point(folderCellLayoutBorderSpaceOriginalPx,
folderCellLayoutBorderSpaceOriginalPx);
int cellLayoutPaddingLeftRightMultiplier = !isVerticalBarLayout() && isTablet
? PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER : 1;
@@ -307,8 +313,7 @@ public class DeviceProfile {
: res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding);
if (isTwoPanels) {
cellLayoutPaddingLeftRightPx =
res.getDimensionPixelSize(R.dimen.two_panel_home_side_padding);
cellLayoutPaddingLeftRightPx = 0;
cellLayoutBottomPaddingPx = 0;
} else if (isLandscape) {
cellLayoutPaddingLeftRightPx = 0;
@@ -366,23 +371,64 @@ public class DeviceProfile {
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding);
// Add a bit of space between nav bar and hotseat in vertical bar layout.
hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
hotseatExtraVerticalSize = res.getDimensionPixelSize(hotseatExtraVerticalSizeRes);
updateHotseatIconSize(pxFromDp(inv.iconSize, mMetrics, 1f));
hotseatExtraVerticalSize =
res.getDimensionPixelSize(hotseatExtraVerticalSizeRes);
updateHotseatIconSize(
pxFromDp(inv.iconSize[InvariantDeviceProfile.INDEX_DEFAULT], mMetrics, 1f));
qsbBottomMarginOriginalPx = isScalableGrid
? res.getDimensionPixelSize(R.dimen.scalable_grid_qsb_bottom_margin)
: 0;
overviewTaskMarginPx = res.getDimensionPixelSize(R.dimen.overview_task_margin);
overviewTaskIconSizePx =
isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get() ? res.getDimensionPixelSize(
R.dimen.task_thumbnail_icon_size_grid) : res.getDimensionPixelSize(
R.dimen.task_thumbnail_icon_size);
overviewShowAsGrid = isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get();
overviewTaskMarginPx = overviewShowAsGrid
? res.getDimensionPixelSize(R.dimen.overview_task_margin_focused)
: res.getDimensionPixelSize(R.dimen.overview_task_margin);
overviewTaskMarginGridPx = res.getDimensionPixelSize(R.dimen.overview_task_margin_grid);
overviewTaskIconSizePx = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
overviewTaskIconDrawableSizePx =
res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size);
overviewTaskIconDrawableSizeGridPx =
res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size_grid);
overviewTaskThumbnailTopMarginPx = overviewTaskIconSizePx + overviewTaskMarginPx * 2;
overviewActionsMarginGesturePx = res.getDimensionPixelSize(
R.dimen.overview_actions_bottom_margin_gesture);
if (overviewShowAsGrid) {
if (isLandscape) {
overviewActionsTopMarginGesturePx = res.getDimensionPixelSize(
R.dimen.overview_actions_top_margin_gesture_grid_landscape);
overviewActionsBottomMarginGesturePx = res.getDimensionPixelSize(
R.dimen.overview_actions_bottom_margin_gesture_grid_landscape);
overviewPageSpacing = res.getDimensionPixelSize(
R.dimen.overview_page_spacing_grid_landscape);
} else {
overviewActionsTopMarginGesturePx = res.getDimensionPixelSize(
R.dimen.overview_actions_top_margin_gesture_grid_portrait);
overviewActionsBottomMarginGesturePx = res.getDimensionPixelSize(
R.dimen.overview_actions_bottom_margin_gesture_grid_portrait);
overviewPageSpacing = res.getDimensionPixelSize(
R.dimen.overview_page_spacing_grid_portrait);
}
overviewActionsButtonSpacing = res.getDimensionPixelSize(
R.dimen.overview_actions_button_spacing_grid);
} else {
overviewActionsTopMarginGesturePx = res.getDimensionPixelSize(
R.dimen.overview_actions_margin_gesture);
overviewActionsBottomMarginGesturePx = overviewActionsTopMarginGesturePx;
overviewActionsButtonSpacing = res.getDimensionPixelSize(
R.dimen.overview_actions_button_spacing);
overviewPageSpacing = res.getDimensionPixelSize(R.dimen.overview_page_spacing);
}
overviewActionsMarginThreeButtonPx = res.getDimensionPixelSize(
R.dimen.overview_actions_bottom_margin_three_button);
R.dimen.overview_actions_margin_three_button);
// Grid task's top margin is only overviewTaskIconSizePx + overviewTaskMarginGridPx, but
// overviewTaskThumbnailTopMarginPx is applied to all TaskThumbnailView, so exclude the
// extra margin when calculating row spacing.
int extraTopMargin = overviewTaskThumbnailTopMarginPx - overviewTaskIconSizePx
- overviewTaskMarginGridPx;
overviewRowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing)
- extraTopMargin;
overviewGridSideMargin = isLandscape
? res.getDimensionPixelSize(R.dimen.overview_grid_side_margin_landscape)
: res.getDimensionPixelSize(R.dimen.overview_grid_side_margin_portrait);
// Calculate all of the remaining variables.
extraSpace = updateAvailableDimensions(res);
@@ -448,6 +494,16 @@ public class DeviceProfile {
new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE);
}
private int getHorizontalMarginPx(InvariantDeviceProfile idp, Resources res) {
if (isVerticalBarLayout()) {
return 0;
}
return isScalableGrid
? pxFromDp(idp.horizontalMargin[mTypeIndex], mMetrics)
: res.getDimensionPixelSize(R.dimen.dynamic_grid_left_right_margin);
}
private void updateHotseatIconSize(int hotseatIconSizePx) {
// Ensure there is enough space for folder icons, which have a slightly larger radius.
hotseatCellHeightPx = (int) Math.ceil(hotseatIconSizePx * ICON_OVERLAP_FACTOR);
@@ -461,8 +517,24 @@ public class DeviceProfile {
}
}
private void setCellLayoutBorderSpacing(int borderSpacing) {
cellLayoutBorderSpacingPx = isScalableGrid ? borderSpacing : 0;
private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp) {
if (!isScalableGrid) {
return new Point(0, 0);
}
int horizontalSpacePx = pxFromDp(idp.borderSpaces[mTypeIndex].x, mMetrics);
int verticalSpacePx = pxFromDp(idp.borderSpaces[mTypeIndex].y, mMetrics);
return new Point(horizontalSpacePx, verticalSpacePx);
}
private Point getCellLayoutBorderSpaceScaled(InvariantDeviceProfile idp, float scale) {
Point original = getCellLayoutBorderSpace(idp);
return new Point((int) (original.x * scale), (int) (original.y * scale));
}
public Info getDisplayInfo() {
return mInfo;
}
/**
@@ -475,10 +547,10 @@ public class DeviceProfile {
// Check all sides to ensure that the widget won't overlap into another cell, or into
// status bar.
return workspaceTopPadding > widgetPadding.top
&& cellLayoutBorderSpacingPx > widgetPadding.left
&& cellLayoutBorderSpacingPx > widgetPadding.top
&& cellLayoutBorderSpacingPx > widgetPadding.right
&& cellLayoutBorderSpacingPx > widgetPadding.bottom;
&& cellLayoutBorderSpacePx.x > widgetPadding.left
&& cellLayoutBorderSpacePx.y > widgetPadding.top
&& cellLayoutBorderSpacePx.x > widgetPadding.right
&& cellLayoutBorderSpacePx.y > widgetPadding.bottom;
}
public Builder toBuilder(Context context) {
@@ -544,13 +616,24 @@ public class DeviceProfile {
int baseCellHeight = allAppsIconSizePx + allAppsIconDrawablePaddingPx + textHeight + (topBottomPadding * 2);
allAppsCellHeightPx = (int) (baseCellHeight * allAppsCellHeightMultiplier);
if (allAppsIconTextSizePx == 0) {
int leftRightPadding = desiredWorkspaceLeftRightMarginPx + cellLayoutPaddingLeftRightPx;
int leftRightPadding = desiredWorkspaceHorizontalMarginPx + cellLayoutPaddingLeftRightPx;
int drawerWidth = availableWidthPx - leftRightPadding * 2;
allAppsCellHeightPx = (int) (drawerWidth / inv.numAllAppsColumns * allAppsCellHeightMultiplier);
allAppsIconDrawablePaddingPx = 0;
}
}
private void updateAllAppsWidth() {
if (isTwoPanels) {
int usedWidth = (allAppsCellWidthPx * numShownAllAppsColumns)
+ (allAppsCellSpacePx.x * (numShownAllAppsColumns + 1));
allAppsLeftRightPadding = Math.max(1, (availableWidthPx - usedWidth) / 2);
} else {
allAppsLeftRightPadding =
desiredWorkspaceHorizontalMarginPx + cellLayoutPaddingLeftRightPx;
}
}
/**
* Returns the amount of extra (or unused) vertical space.
*/
@@ -571,9 +654,10 @@ public class DeviceProfile {
// We scale to fit the cellWidth and cellHeight in the available space.
// The benefit of scalable grids is that we can get consistent aspect ratios between
// devices.
float usedWidth = (cellWidthPx * inv.numColumns)
+ (cellLayoutBorderSpacingPx * (inv.numColumns - 1))
+ (desiredWorkspaceLeftRightMarginPx * 2);
int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns;
float usedWidth = (cellWidthPx * numColumns)
+ (cellLayoutBorderSpacePx.x * (numColumns - 1))
+ (desiredWorkspaceHorizontalMarginPx * 2);
// We do not subtract padding here, as we also scale the workspace padding if needed.
scaleX = availableWidthPx / usedWidth;
shouldScale = true;
@@ -590,7 +674,7 @@ public class DeviceProfile {
}
private int getCellLayoutHeight() {
return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacingPx * (inv.numRows - 1));
return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacePx.y * (inv.numRows - 1));
}
/**
@@ -603,24 +687,25 @@ public class DeviceProfile {
iconScale = Math.min(1f, scale);
cellScaleToFit = scale;
// Workspace
final boolean isVerticalLayout = isVerticalBarLayout();
float invIconSizeDp = isLandscape ? inv.landscapeIconSize : inv.iconSize;
float invIconSizeDp = inv.iconSize[mTypeIndex];
float invIconTextSizeSp = inv.iconTextSize[mTypeIndex];
iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, iconScale));
float invIconTextSizeSp = isLandscape ? inv.landscapeIconTextSize : inv.iconTextSize;
iconTextSizePx = (int) (pxFromSp(invIconTextSizeSp, mMetrics) * iconScale);
iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * iconScale);
setCellLayoutBorderSpacing((int) (cellLayoutBorderSpacingOriginalPx * scale));
cellLayoutBorderSpacePx = getCellLayoutBorderSpaceScaled(inv, scale);
if (isScalableGrid) {
cellWidthPx = pxFromDp(inv.minCellWidth, mMetrics, scale);
cellHeightPx = pxFromDp(inv.minCellHeight, mMetrics, scale);
cellWidthPx = pxFromDp(inv.minCellSize[mTypeIndex].x, mMetrics, scale);
cellHeightPx = pxFromDp(inv.minCellSize[mTypeIndex].y, mMetrics, scale);
int cellContentHeight = iconSizePx + iconDrawablePaddingPx
+ Utilities.calculateTextHeight(iconTextSizePx);
cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2;
desiredWorkspaceLeftRightMarginPx = (int) (desiredWorkspaceLeftRightOriginalPx * scale);
desiredWorkspaceHorizontalMarginPx =
(int) (desiredWorkspaceHorizontalMarginOriginalPx * scale);
} else {
cellWidthPx = iconSizePx + iconDrawablePaddingPx;
cellHeightPx = (int) Math.ceil(iconSizePx * ICON_OVERLAP_FACTOR)
@@ -638,11 +723,14 @@ public class DeviceProfile {
}
// All apps
allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mMetrics);
allAppsIconTextSizePx = pxFromSp(inv.allAppsIconTextSize, mMetrics);
allAppsIconSizePx =
pxFromDp(inv.iconSize[InvariantDeviceProfile.INDEX_ALL_APPS], mMetrics);
allAppsIconTextSizePx =
pxFromSp(inv.iconTextSize[InvariantDeviceProfile.INDEX_ALL_APPS], mMetrics);
allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
autoResizeAllAppsCells();
allAppsCellWidthPx = allAppsIconSizePx + allAppsIconDrawablePaddingPx;
updateAllAppsWidth();
if (isVerticalLayout) {
hideWorkspaceLabelsIfNotEnoughSpace();
@@ -679,14 +767,14 @@ public class DeviceProfile {
// Check if the icons fit within the available height.
float contentUsedHeight = folderCellHeightPx * inv.numFolderRows
+ ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacingPx);
+ ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacePx.y);
int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderBottomPanelSize
- folderMargin - folderContentPaddingTop;
float scaleY = contentMaxHeight / contentUsedHeight;
// Check if the icons fit within the available width.
float contentUsedWidth = folderCellWidthPx * inv.numFolderColumns
+ ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacingPx);
+ ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacePx.x);
int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x - folderMargin
- folderContentPaddingLeftRight * 2;
float scaleX = contentMaxWidth / contentUsedWidth;
@@ -698,9 +786,12 @@ public class DeviceProfile {
}
private void updateFolderCellSize(float scale, Resources res) {
float invIconSizeDp = isVerticalBarLayout() ? inv.landscapeIconSize : inv.iconSize;
float invIconSizeDp = isVerticalBarLayout()
? inv.iconSize[InvariantDeviceProfile.INDEX_LANDSCAPE]
: inv.iconSize[InvariantDeviceProfile.INDEX_DEFAULT];
folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
folderChildTextSizePx = pxFromSp(inv.iconTextSize, mMetrics, scale);
folderChildTextSizePx =
pxFromSp(inv.iconTextSize[InvariantDeviceProfile.INDEX_DEFAULT], mMetrics, scale);
folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale);
int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
@@ -712,10 +803,10 @@ public class DeviceProfile {
folderCellWidthPx = (int) Math.max(minWidth, cellWidthPx * scale);
folderCellHeightPx = (int) Math.max(minHeight, cellHeightPx * scale);
int borderSpacing = (int) (cellLayoutBorderSpacingOriginalPx * scale);
folderCellLayoutBorderSpacingPx = borderSpacing;
folderContentPaddingLeftRight = borderSpacing;
folderContentPaddingTop = borderSpacing;
int scaledSpace = (int) (folderCellLayoutBorderSpaceOriginalPx * scale);
folderCellLayoutBorderSpacePx = new Point(scaledSpace, scaledSpace);
folderContentPaddingLeftRight = scaledSpace;
folderContentPaddingTop = scaledSpace;
} else {
int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding)
* scale);
@@ -751,16 +842,29 @@ public class DeviceProfile {
if (result == null) {
result = new Point();
}
// Since we are only concerned with the overall padding, layout direction does
// not matter.
Point padding = getTotalWorkspacePadding();
result.x = calculateCellWidth(availableWidthPx - padding.x
- cellLayoutPaddingLeftRightPx * 2, cellLayoutBorderSpacingPx, inv.numColumns);
int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns;
int screenWidthPx = getWorkspaceWidth(padding);
result.x = calculateCellWidth(screenWidthPx, cellLayoutBorderSpacePx.x, numColumns);
result.y = calculateCellHeight(availableHeightPx - padding.y
- cellLayoutBottomPaddingPx, cellLayoutBorderSpacingPx, inv.numRows);
- cellLayoutBottomPaddingPx, cellLayoutBorderSpacePx.y, inv.numRows);
return result;
}
public int getWorkspaceWidth() {
return getWorkspaceWidth(getTotalWorkspacePadding());
}
public int getWorkspaceWidth(Point workspacePadding) {
int cellLayoutTotalPadding =
isTwoPanels ? 4 * cellLayoutPaddingLeftRightPx : 2 * cellLayoutPaddingLeftRightPx;
return availableWidthPx - workspacePadding.x - cellLayoutTotalPadding;
}
public Point getTotalWorkspacePadding() {
updateWorkspacePadding();
return new Point(workspacePadding.left + workspacePadding.right,
@@ -784,38 +888,22 @@ public class DeviceProfile {
padding.right = hotseatBarSizePx;
}
} else {
int hotseatTop = isTaskbarPresent ? taskbarSize : hotseatBarSizePx;
// Pad the bottom of the workspace with search/hotseat bar sizes
int hotseatTop = hotseatBarSizePx;
int paddingBottom = hotseatTop + workspacePageIndicatorHeight
+ workspaceBottomPadding - mWorkspacePageIndicatorOverlapWorkspace;
if (isTablet) {
// Pad the left and right of the workspace to ensure consistent spacing
// between all icons
// The amount of screen space available for left/right padding.
int availablePaddingX = Math.max(0, widthPx - ((inv.numColumns * cellWidthPx) +
((inv.numColumns - 1) * cellWidthPx)));
availablePaddingX = (int) Math.min(availablePaddingX,
widthPx * MAX_HORIZONTAL_PADDING_PERCENT);
int hotseatVerticalPadding = isTaskbarPresent ? 0
: hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx;
int availablePaddingY = Math.max(0, heightPx - edgeMarginPx - paddingBottom
- (2 * inv.numRows * cellHeightPx) - hotseatVerticalPadding);
padding.set(availablePaddingX / 2, edgeMarginPx + availablePaddingY / 2,
availablePaddingX / 2, paddingBottom + availablePaddingY / 2);
if (isTwoPanels) {
padding.set(0, padding.top, 0, padding.bottom);
}
} else {
// Pad the top and bottom of the workspace with search/hotseat bar sizes
padding.set(desiredWorkspaceLeftRightMarginPx,
workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx),
desiredWorkspaceLeftRightMarginPx,
paddingBottom);
}
padding.set(desiredWorkspaceHorizontalMarginPx,
workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx),
desiredWorkspaceHorizontalMarginPx,
paddingBottom);
}
}
public Rect getHotseatLayoutPadding() {
/**
* Returns the padding for hotseat view
*/
public Rect getHotseatLayoutPadding(Context context) {
if (isVerticalBarLayout()) {
if (isSeascape()) {
mHotseatPadding.set(mInsets.left + hotseatBarSidePaddingStartPx,
@@ -824,6 +912,30 @@ public class DeviceProfile {
mHotseatPadding.set(hotseatBarSidePaddingEndPx, mInsets.top,
mInsets.right + hotseatBarSidePaddingStartPx, mInsets.bottom);
}
} else if (isTaskbarPresent) {
int hotseatHeight = workspacePadding.bottom;
int taskbarOffset = getTaskbarOffsetY();
int hotseatTopDiff = hotseatHeight - taskbarOffset;
int endOffset = ApiWrapper.getHotseatEndOffset(context);
int requiredWidth = iconSizePx * numShownHotseatIcons;
Resources res = context.getResources();
float taskbarIconSize = res.getDimension(R.dimen.taskbar_icon_size);
float taskbarIconSpacing = 2 * res.getDimension(R.dimen.taskbar_icon_spacing);
int maxSize = (int) (requiredWidth
* (taskbarIconSize + taskbarIconSpacing) / taskbarIconSize);
int hotseatSize = Math.min(maxSize, availableWidthPx - endOffset);
int sideSpacing = (availableWidthPx - hotseatSize) / 2;
mHotseatPadding.set(sideSpacing, hotseatTopDiff, sideSpacing, taskbarOffset);
if (endOffset > sideSpacing) {
int diff = Utilities.isRtl(context.getResources())
? sideSpacing - endOffset
: endOffset - sideSpacing;
mHotseatPadding.left -= diff;
mHotseatPadding.right += diff;
}
} else {
// We want the edges of the hotseat to line up with the edges of the workspace, but the
// icons in the hotseat are a different size, and so don't line up perfectly. To account
@@ -844,6 +956,30 @@ public class DeviceProfile {
return mHotseatPadding;
}
/**
* Returns the number of pixels the QSB is translated from the bottom of the screen.
*/
public int getQsbOffsetY() {
int freeSpace = isTaskbarPresent
? workspacePadding.bottom
: hotseatBarSizePx - hotseatCellHeightPx - hotseatQsbHeight;
if (isScalableGrid && qsbBottomMarginPx > mInsets.bottom) {
// Note that taskbarSize = 0 unless isTaskbarPresent.
return Math.min(qsbBottomMarginPx + taskbarSize, freeSpace);
} else {
return (int) (freeSpace * QSB_CENTER_FACTOR)
+ (isTaskbarPresent ? taskbarSize : mInsets.bottom);
}
}
/**
* Returns the number of pixels the taskbar is translated from the bottom of the screen.
*/
public int getTaskbarOffsetY() {
return (getQsbOffsetY() - taskbarSize) / 2;
}
/**
* @return the bounds for which the open folders should be contained within
*/
@@ -868,6 +1004,7 @@ public class DeviceProfile {
public static int calculateCellWidth(int width, int borderSpacing, int countX) {
return (width - ((countX - 1) * borderSpacing)) / countX;
}
public static int calculateCellHeight(int height, int borderSpacing, int countY) {
return (height - ((countY - 1) * borderSpacing)) / countY;
}
@@ -928,7 +1065,6 @@ 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:"
@@ -950,11 +1086,10 @@ public class DeviceProfile {
writer.println(prefix + "\tisScalableGrid:" + isScalableGrid);
writer.println(prefix + "\tinv.minCellWidth:" + inv.minCellWidth + "dp");
writer.println(prefix + "\tinv.minCellHeight:" + inv.minCellHeight + "dp");
writer.println(prefix + "\tinv.numColumns: " + inv.numColumns);
writer.println(prefix + "\tinv.numRows: " + inv.numRows);
writer.println(prefix + "\tinv.numColumns:" + inv.numColumns);
writer.println(prefix + "\tinv.numRows:" + inv.numRows);
writer.println(prefix + "\tminCellSize: " + inv.minCellSize[mTypeIndex] + "dp");
writer.println(prefix + pxToDpStr("cellWidthPx", cellWidthPx));
writer.println(prefix + pxToDpStr("cellHeightPx", cellHeightPx));
@@ -962,7 +1097,11 @@ public class DeviceProfile {
writer.println(prefix + pxToDpStr("getCellSize().x", getCellSize().x));
writer.println(prefix + pxToDpStr("getCellSize().y", getCellSize().y));
writer.println(prefix + "\tinv.iconSize:" + inv.iconSize + "dp");
writer.println(prefix + pxToDpStr("cellLayoutBorderSpacePx Horizontal",
cellLayoutBorderSpacePx.x));
writer.println(prefix + pxToDpStr("cellLayoutBorderSpacePx Vertical",
cellLayoutBorderSpacePx.y));
writer.println(prefix + pxToDpStr("iconSizePx", iconSizePx));
writer.println(prefix + pxToDpStr("iconTextSizePx", iconTextSizePx));
writer.println(prefix + pxToDpStr("iconDrawablePaddingPx", iconDrawablePaddingPx));
@@ -973,13 +1112,12 @@ public class DeviceProfile {
writer.println(prefix + pxToDpStr("folderChildTextSizePx", folderChildTextSizePx));
writer.println(prefix + pxToDpStr("folderChildDrawablePaddingPx",
folderChildDrawablePaddingPx));
writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacingPx",
folderCellLayoutBorderSpacingPx));
writer.println(prefix + pxToDpStr("cellLayoutBorderSpacingPx",
cellLayoutBorderSpacingPx));
writer.println(prefix + pxToDpStr("desiredWorkspaceLeftRightMarginPx",
desiredWorkspaceLeftRightMarginPx));
writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpaceOriginalPx",
folderCellLayoutBorderSpaceOriginalPx));
writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Horizontal",
folderCellLayoutBorderSpacePx.x));
writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Vertical",
folderCellLayoutBorderSpacePx.y));
writer.println(prefix + pxToDpStr("allAppsIconSizePx", allAppsIconSizePx));
writer.println(prefix + pxToDpStr("allAppsIconTextSizePx", allAppsIconTextSizePx));
@@ -999,11 +1137,11 @@ public class DeviceProfile {
writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons);
writer.println(prefix + "\tisTaskbarPresent:" + isTaskbarPresent);
writer.println(prefix + "\tisTaskbarPresentInApps:" + isTaskbarPresentInApps);
writer.println(prefix + pxToDpStr("taskbarSize", taskbarSize));
writer.println(prefix + pxToDpStr("nonOverlappingTaskbarInset",
nonOverlappingTaskbarInset));
writer.println(prefix + pxToDpStr("desiredWorkspaceHorizontalMarginPx",
desiredWorkspaceHorizontalMarginPx));
writer.println(prefix + pxToDpStr("workspacePadding.left", workspacePadding.left));
writer.println(prefix + pxToDpStr("workspacePadding.top", workspacePadding.top));
writer.println(prefix + pxToDpStr("workspacePadding.right", workspacePadding.right));
@@ -1012,6 +1150,7 @@ public class DeviceProfile {
writer.println(prefix + pxToDpStr("iconScale", iconScale));
writer.println(prefix + pxToDpStr("cellScaleToFit ", cellScaleToFit));
writer.println(prefix + pxToDpStr("extraSpace", extraSpace));
writer.println(prefix + pxToDpStr("unscaled extraSpace", extraSpace / iconScale));
if (inv.devicePaddings != null) {
int unscaledExtraSpace = (int) (extraSpace / iconScale);