Merge "Adding support for overriding long-press menu in Launcher" into sc-v2-dev
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index f29d68a..7fb8e16 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -107,10 +107,9 @@
public RecentsView getVisibleRecentsView() {
RecentsActivity activity = getCreatedActivity();
if (activity != null) {
- RecentsView recentsView = activity.getOverviewPanel();
- if (activity.hasBeenResumed() || (ENABLE_QUICKSTEP_LIVE_TILE.get() && isInLiveTileMode()
- && recentsView.getRunningTaskId() == -1)) {
- return recentsView;
+ if (activity.hasBeenResumed()
+ || (ENABLE_QUICKSTEP_LIVE_TILE.get() && isInLiveTileMode())) {
+ return activity.getOverviewPanel();
}
}
return null;
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index b5b8b62..2b8b9fa 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -122,7 +122,7 @@
<string name="allow_rotation_title" msgid="7728578836261442095">"السماح بتدوير الشاشة الرئيسية"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"عند تدوير الهاتف"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"نقاط الإشعارات"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"مفعّل"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"مفعّلة"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"غير مفعّل"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"يلزم تمكين الوصول إلى الإشعارات"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"لعرض نقاط الإشعارات، يجب تفعيل إشعارات التطبيق في <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index d3558ec..673a446 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -105,7 +105,7 @@
<string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item atau lebih"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpaper"</string>
<string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper & gaya"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Setelan layar utama"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Setelan Layar utama"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dinonaktifkan oleh admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Izinkan Layar utama diputar"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Saat ponsel diputar"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 85d7db6..2415542 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -75,7 +75,7 @@
<string name="all_apps_button_label" msgid="8130441508702294465">"Список приложений"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Открыть список личных приложений"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Открыть список приложений для работы"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"Убрать"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Удалить"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Удалить"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"О приложении"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Установить"</string>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 010d15b..838d0ec 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -29,7 +29,8 @@
<dimen name="dynamic_grid_cell_layout_padding">5.5dp</dimen>
<dimen name="dynamic_grid_cell_padding_x">8dp</dimen>
- <dimen name="two_panel_home_side_padding">18dp</dimen>
+ <dimen name="two_panels_home_side_padding_landscape">36dp</dimen>
+ <dimen name="two_panels_home_side_padding_portrait">9dp</dimen>
<!-- Hotseat -->
<dimen name="dynamic_grid_hotseat_top_padding">8dp</dimen>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 740bf5a..d2d00c8 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -94,6 +94,8 @@
private static final float TALL_DEVICE_ASPECT_RATIO_THRESHOLD = 2.0f;
private static final float TALLER_DEVICE_ASPECT_RATIO_THRESHOLD = 2.15f;
+ private static final float TALL_DEVICE_EXTRA_SPACE_THRESHOLD_DP = 252;
+ private static final float TALL_DEVICE_MORE_EXTRA_SPACE_THRESHOLD_DP = 268;
// To evenly space the icons, increase the left/right margins for tablets in portrait mode.
private static final int PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER = 4;
@@ -257,7 +259,8 @@
final Resources res = context.getResources();
hotseatQsbHeight = res.getDimensionPixelSize(R.dimen.qsb_widget_height);
- isTaskbarPresent = isTablet && FeatureFlags.ENABLE_TASKBAR.get();
+ isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS
+ && FeatureFlags.ENABLE_TASKBAR.get();
if (isTaskbarPresent) {
// Taskbar will be added later, but provides bottom insets that we should subtract
// from availableHeightPx.
@@ -302,8 +305,10 @@
: res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding);
if (isTwoPanels) {
- cellLayoutPaddingLeftRightPx =
- res.getDimensionPixelSize(R.dimen.two_panel_home_side_padding);
+ cellLayoutPaddingLeftRightPx = res.getDimensionPixelSize(
+ isLandscape
+ ? R.dimen.two_panels_home_side_padding_landscape
+ : R.dimen.two_panels_home_side_padding_portrait);
cellLayoutBottomPaddingPx = 0;
} else if (isLandscape) {
cellLayoutPaddingLeftRightPx = 0;
@@ -407,11 +412,17 @@
} else if (!isVerticalBarLayout() && isPhone && isTallDevice) {
// We increase the hotseat size when there is extra space.
- if (Float.compare(aspectRatio, TALLER_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0) {
- // For taller devices, we will take a third of the extra space from each row,
+ if (Float.compare(aspectRatio, TALLER_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0
+ && extraSpace >= Utilities.dpToPx(TALL_DEVICE_EXTRA_SPACE_THRESHOLD_DP)) {
+ // For taller devices, we will take a piece of the extra space from each row,
// and add it to the space above and below the hotseat.
+
+ // For devices with more extra space, we take a larger piece from each cell.
+ int piece = extraSpace < Utilities.dpToPx(TALL_DEVICE_MORE_EXTRA_SPACE_THRESHOLD_DP)
+ ? 5 : 3;
+
int extraSpace = ((getCellSize().y - iconSizePx - iconDrawablePaddingPx * 2)
- * inv.numRows) / 3;
+ * inv.numRows) / piece;
int halfExtraSpace = extraSpace / 2;
hotseatBarTopPaddingPx += halfExtraSpace;
@@ -752,8 +763,14 @@
// 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);
+ // availableWidthPx is the screen width of the device. In 2 panels mode, each panel should
+ // only have half of the screen width. In addition, there is only cellLayoutPadding in the
+ // left side of the left panel and the right side of the right panel. There is no
+ // cellLayoutPadding in the middle.
+ int screenWidthPx = isTwoPanels
+ ? availableWidthPx / 2 - padding.x - cellLayoutPaddingLeftRightPx
+ : availableWidthPx - padding.x - cellLayoutPaddingLeftRightPx * 2;
+ result.x = calculateCellWidth(screenWidthPx, cellLayoutBorderSpacingPx, inv.numColumns);
result.y = calculateCellHeight(availableHeightPx - padding.y
- cellLayoutBottomPaddingPx, cellLayoutBorderSpacingPx, inv.numRows);
return result;
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 3f7a3ad..242e3e3 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -238,10 +238,6 @@
return getChildAt(index);
}
- protected int indexToPage(int index) {
- return index;
- }
-
/**
* Updates the scroll of the current page immediately to its final scroll position. We use this
* in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of
@@ -322,18 +318,56 @@
*/
@VisibleForTesting(otherwise = PACKAGE_PRIVATE)
public IntSet getVisiblePageIndices() {
- IntSet visiblePageIndices = new IntSet();
+ return getPageIndices(mCurrentPage);
+ }
+
+ /**
+ * In case the panelCount is 1 this just returns the same page index in an IntSet.
+ * But in cases where the panelCount > 1 this will return all the page indices that belong
+ * together, i.e. on the Workspace they are next to each other and shown at the same time.
+ */
+ private IntSet getPageIndices(int pageIndex) {
+ // we want to make sure the pageIndex is the leftmost page
+ pageIndex = getLeftmostVisiblePageForIndex(pageIndex);
+
+ IntSet pageIndices = new IntSet();
int panelCount = getPanelCount();
int pageCount = getPageCount();
-
- // If a device goes from one panel to two panel (i.e. unfolding a foldable device) while
- // an odd indexed page is the current page, then the new leftmost visible page will be
- // different from the old mCurrentPage.
- int currentPage = getLeftmostVisiblePageForIndex(mCurrentPage);
- for (int page = currentPage; page < currentPage + panelCount && page < pageCount; page++) {
- visiblePageIndices.add(page);
+ for (int page = pageIndex; page < pageIndex + panelCount && page < pageCount; page++) {
+ pageIndices.add(page);
}
- return visiblePageIndices;
+ return pageIndices;
+ }
+
+ /**
+ * Returns an IntSet with the indices of the neighbour pages that are in the focus direction.
+ */
+ private IntSet getNeighbourPageIndices(int focus) {
+ int panelCount = getPanelCount();
+ // getNextPage is more reliable than getCurrentPage
+ int currentPage = getNextPage();
+
+ int nextPage;
+ if (focus == View.FOCUS_LEFT) {
+ nextPage = currentPage - panelCount;
+ } else if (focus == View.FOCUS_RIGHT) {
+ nextPage = currentPage + panelCount;
+ } else {
+ // no neighbours to those direction
+ return new IntSet();
+ }
+ nextPage = validateNewPage(nextPage);
+ if (nextPage == currentPage) {
+ // We reached the end of the pages
+ return new IntSet();
+ }
+
+ int pageCount = getPageCount();
+ IntSet neighbourIndices = new IntSet();
+ for (int page = nextPage; page < nextPage + panelCount && page < pageCount; page++) {
+ neighbourIndices.add(page);
+ }
+ return neighbourIndices;
}
/**
@@ -352,7 +386,14 @@
* Returns true if the view is on one of the current pages, false otherwise.
*/
public boolean isVisible(View child) {
- return getLeftmostVisiblePageForIndex(indexOfChild(child)) == mCurrentPage;
+ return isVisible(indexOfChild(child));
+ }
+
+ /**
+ * Returns true if the page with the given index is currently visible, false otherwise.
+ */
+ private boolean isVisible(int pageIndex) {
+ return getLeftmostVisiblePageForIndex(pageIndex) == mCurrentPage;
}
/**
@@ -817,8 +858,8 @@
@Override
public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
- int page = indexToPage(indexOfChild(child));
- if (page != mCurrentPage || !mScroller.isFinished()) {
+ int page = indexOfChild(child);
+ if (!isVisible(page) || !mScroller.isFinished()) {
if (immediate) {
setCurrentPage(page);
} else {
@@ -857,21 +898,25 @@
direction = View.FOCUS_LEFT;
}
}
- if (direction == View.FOCUS_LEFT) {
- if (getCurrentPage() > 0) {
- int nextPage = validateNewPage(getCurrentPage() - 1);
- snapToPage(nextPage);
- getChildAt(nextPage).requestFocus(direction);
- return true;
- }
- } else if (direction == View.FOCUS_RIGHT) {
- if (getCurrentPage() < getPageCount() - 1) {
- int nextPage = validateNewPage(getCurrentPage() + 1);
- snapToPage(nextPage);
- getChildAt(nextPage).requestFocus(direction);
- return true;
+
+ int currentPage = getNextPage();
+ int closestNeighbourIndex = -1;
+ int closestNeighbourDistance = Integer.MAX_VALUE;
+ // Find the closest neighbour page
+ for (int neighbourPageIndex : getNeighbourPageIndices(direction)) {
+ int distance = Math.abs(neighbourPageIndex - currentPage);
+ if (closestNeighbourDistance > distance) {
+ closestNeighbourDistance = distance;
+ closestNeighbourIndex = neighbourPageIndex;
}
}
+ if (closestNeighbourIndex != -1) {
+ View page = getPageAt(closestNeighbourIndex);
+ snapToPage(closestNeighbourIndex);
+ page.requestFocus(direction);
+ return true;
+ }
+
return false;
}
@@ -881,28 +926,12 @@
return;
}
- // Add the current page's views as focusable and the next possible page's too. If the
- // last focus change action was left then the left neighbour's views will be added, and
- // if it was right then the right neighbour's views will be added.
- // Unfortunately mCurrentPage can be outdated if there were multiple control actions in a
- // short period of time, but mNextPage is up to date because it is always updated by
- // method snapToPage.
- int nextPage = getNextPage();
- // XXX-RTL: This will be fixed in a future CL
- if (nextPage >= 0 && nextPage < getPageCount()) {
- getPageAt(nextPage).addFocusables(views, direction, focusableMode);
- }
- if (direction == View.FOCUS_LEFT) {
- if (nextPage > 0) {
- nextPage = validateNewPage(nextPage - 1);
- getPageAt(nextPage).addFocusables(views, direction, focusableMode);
- }
- } else if (direction == View.FOCUS_RIGHT) {
- if (nextPage < getPageCount() - 1) {
- nextPage = validateNewPage(nextPage + 1);
- getPageAt(nextPage).addFocusables(views, direction, focusableMode);
- }
- }
+ // nextPage is more reliable when multiple control movements have been done in a short
+ // period of time
+ getPageIndices(getNextPage())
+ .addAll(getNeighbourPageIndices(direction))
+ .forEach(pageIndex ->
+ getPageAt(pageIndex).addFocusables(views, direction, focusableMode));
}
/**
@@ -1482,8 +1511,8 @@
setCurrentPage(nextPage);
}
- int page = indexToPage(indexOfChild(child));
- if (page >= 0 && page != getCurrentPage() && !isInTouchMode()) {
+ int page = indexOfChild(child);
+ if (page >= 0 && !isVisible(page) && !isInTouchMode()) {
snapToPage(page);
}
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 5200456..9a8b80d 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -327,8 +327,6 @@
int paddingLeftRight = grid.cellLayoutPaddingLeftRightPx;
int paddingBottom = grid.cellLayoutBottomPaddingPx;
- int twoPanelLandscapeSidePadding = paddingLeftRight * 2;
- int twoPanelPortraitSidePadding = paddingLeftRight / 2;
int panelCount = getPanelCount();
for (int i = mWorkspaceScreens.size() - 1; i >= 0; i--) {
@@ -336,13 +334,11 @@
int paddingRight = paddingLeftRight;
if (panelCount > 1) {
if (i % panelCount == 0) { // left side panel
- paddingLeft = grid.isLandscape ? twoPanelLandscapeSidePadding
- : twoPanelPortraitSidePadding;
+ paddingLeft = paddingLeftRight;
paddingRight = 0;
} else if (i % panelCount == panelCount - 1) { // right side panel
paddingLeft = 0;
- paddingRight = grid.isLandscape ? twoPanelLandscapeSidePadding
- : twoPanelPortraitSidePadding;
+ paddingRight = paddingLeftRight;
} else { // middle panel
paddingLeft = 0;
paddingRight = 0;
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 944a41f..5106992 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -102,8 +102,11 @@
return getUIProperty(Bundle::putParcelable, a -> {
WindowInsets insets = a.getWindow()
.getDecorView().getRootWindowInsets();
- return Insets.max(
- insets.getSystemGestureInsets(), insets.getSystemWindowInsets());
+ return Insets.subtract(
+ Insets.max(
+ insets.getSystemGestureInsets(),
+ insets.getSystemWindowInsets()),
+ Insets.of(0, 0, 0, mDeviceProfile.nonOverlappingTaskbarInset));
}, this::getCurrentActivity);
}
diff --git a/src/com/android/launcher3/util/IntSet.java b/src/com/android/launcher3/util/IntSet.java
index e5b4f59..4fd06fe 100644
--- a/src/com/android/launcher3/util/IntSet.java
+++ b/src/com/android/launcher3/util/IntSet.java
@@ -37,6 +37,15 @@
}
/**
+ * Appends the specified IntSet's values to the set if they does not exist, then returns the
+ * original set that now also contains the new values.
+ */
+ public IntSet addAll(IntSet other) {
+ other.forEach(this::add);
+ return this;
+ }
+
+ /**
* Removes the specified value from the set if it exist.
*/
public void remove(int value) {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index e36ea90..be83f9a 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -402,7 +402,10 @@
private boolean updateMaxSpansPerRow() {
if (getMeasuredWidth() == 0) return false;
- int maxHorizontalSpans = computeMaxHorizontalSpans(mContent,
+ View content = mHasWorkProfile
+ ? mViewPager
+ : mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView;
+ int maxHorizontalSpans = computeMaxHorizontalSpans(content,
mWidgetSheetContentHorizontalPadding);
if (mMaxSpansPerRow != maxHorizontalSpans) {
mMaxSpansPerRow = maxHorizontalSpans;
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 93c921e..49934f7 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -728,18 +728,23 @@
// otherwise waitForIdle may return immediately in case when there was a big enough
// pause in accessibility events prior to pressing Home.
final String action;
- final boolean launcherWasVisible = isLauncherVisible();
if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
checkForAnomaly();
final Point displaySize = getRealDisplaySize();
+ boolean gestureStartFromLauncher = isTablet()
+ ? !isLauncher3() || hasLauncherObject(WORKSPACE_RES_ID)
+ : isLauncherVisible();
+ GestureScope gestureScope = gestureStartFromLauncher
+ ? GestureScope.INSIDE_TO_OUTSIDE
+ : GestureScope.OUTSIDE_WITH_PILFER;
if (hasLauncherObject(CONTEXT_MENU_RES_ID)) {
linearGesture(
displaySize.x / 2, displaySize.y - 1,
displaySize.x / 2, 0,
ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME,
- false, GestureScope.INSIDE_TO_OUTSIDE);
+ false, gestureScope);
try (LauncherInstrumentation.Closable c1 = addContextLayer(
"Swiped up from context menu to home")) {
waitUntilLauncherObjectGone(CONTEXT_MENU_RES_ID);
@@ -760,9 +765,7 @@
displaySize.x / 2, displaySize.y - 1,
displaySize.x / 2, 0,
ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME, NORMAL_STATE_ORDINAL,
- launcherWasVisible || isTablet()
- ? GestureScope.INSIDE_TO_OUTSIDE
- : GestureScope.OUTSIDE_WITH_PILFER);
+ gestureScope);
}
} else {
log("Hierarchy before clicking home:");
@@ -1115,9 +1118,9 @@
"swiping");
}
- private int getBottomGestureSize() {
- return ResourceUtils.getNavbarSize(
- ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, getResources()) + 1;
+ int getBottomGestureSize() {
+ return Math.max(getTargetInsets().bottom, ResourceUtils.getNavbarSize(
+ ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, getResources())) + 1;
}
int getBottomGestureMarginInContainer(UiObject2 container) {
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index 2acf7b4..db2e250 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -34,7 +34,6 @@
import androidx.test.uiautomator.Direction;
import androidx.test.uiautomator.UiObject2;
-import com.android.launcher3.ResourceUtils;
import com.android.launcher3.testing.TestProtocol;
import java.util.regex.Pattern;
@@ -72,8 +71,7 @@
mLauncher.addContextLayer("want to switch from workspace to all apps")) {
verifyActiveContainer();
final int deviceHeight = mLauncher.getDevice().getDisplayHeight();
- final int bottomGestureMargin = ResourceUtils.getNavbarSize(
- ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources());
+ final int bottomGestureMargin = mLauncher.getBottomGestureSize();
final int windowCornerRadius = (int) Math.ceil(mLauncher.getWindowCornerRadius());
final int startY = deviceHeight - Math.max(bottomGestureMargin, windowCornerRadius) - 1;
final int swipeHeight = mLauncher.getTestInfo(