Merge "Converting BaseIconCache to kotlin" into main
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 80da467..5a8fba6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -41,6 +41,7 @@
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.taskbar.bubbles.BubbleBarController;
+import com.android.launcher3.taskbar.bubbles.BubbleControllers;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory;
@@ -86,7 +87,7 @@
private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
dp -> {
onStashedInAppChanged(dp);
- adjustHotseatForBubbleBar();
+ postAdjustHotseatForBubbleBar();
if (mControllers != null && mControllers.taskbarViewController != null) {
mControllers.taskbarViewController.onRotationChanged(dp);
}
@@ -275,13 +276,16 @@
}
}
- private void adjustHotseatForBubbleBar() {
+ private void postAdjustHotseatForBubbleBar() {
Hotseat hotseat = mLauncher.getHotseat();
- if (mControllers.bubbleControllers.isEmpty() || hotseat == null) return;
- boolean hiddenForBubbles =
- mControllers.bubbleControllers.get().bubbleBarViewController.isHiddenForNoBubbles();
- if (hiddenForBubbles) return;
- hotseat.post(() -> adjustHotseatForBubbleBar(/* isBubbleBarVisible= */ true));
+ if (hotseat == null || !isBubbleBarVisible()) return;
+ hotseat.post(() -> adjustHotseatForBubbleBar(isBubbleBarVisible()));
+ }
+
+ private boolean isBubbleBarVisible() {
+ BubbleControllers bubbleControllers = mControllers.bubbleControllers.orElse(null);
+ return bubbleControllers != null
+ && bubbleControllers.bubbleBarViewController.isBubbleBarVisible();
}
/**
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
index c81edcd..089706f 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
@@ -470,7 +470,7 @@
// Stops requesting focused after first view gets focused.
recentsView.getTaskViewAt(keyboardTaskFocusIndex).requestFocus() ||
recentsView.nextTaskView.requestFocus() ||
- recentsView.getTaskViewAt(0).requestFocus() ||
+ recentsView.getFirstTaskView().requestFocus() ||
recentsView.requestFocus()
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index dbd7273..4660c51 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3169,7 +3169,7 @@
* Skips rebalance.
*/
private void updateGridProperties() {
- updateGridProperties(Integer.MAX_VALUE);
+ updateGridProperties(null);
}
/**
@@ -3179,10 +3179,10 @@
* This method only calculates the potential position and depends on {@link #setGridProgress} to
* apply the actual scaling and translation.
*
- * @param startRebalanceAfter which view index to start rebalancing from. Use Integer.MAX_VALUE
- * to skip rebalance
+ * @param lastVisibleTaskViewDuringDismiss which TaskView to start rebalancing from. Use
+ * `null` to skip rebalance.
*/
- private void updateGridProperties(int startRebalanceAfter) {
+ private void updateGridProperties(TaskView lastVisibleTaskViewDuringDismiss) {
if (!hasTaskViews()) {
return;
}
@@ -3195,19 +3195,10 @@
float topAccumulatedTranslationX = 0;
float bottomAccumulatedTranslationX = 0;
- // Contains whether the child index is in top or bottom of grid (for non-focused task)
- // Different from mTopRowIdSet, which contains the taskViewId of what task is in top row
- IntSet topSet = new IntSet();
- IntSet bottomSet = new IntSet();
-
- final int taskCount = getTaskViewCount();
- // Horizontal grid translation for each task
- float[] gridTranslations = new float[taskCount];
+ // Horizontal grid translation for each task.
+ Map<TaskView, Float> gridTranslations = new HashMap<>();
TaskView lastLargeTaskView = mUtils.getLastLargeTaskView();
- int lastLargeTaskIndex =
- (lastLargeTaskView == null) ? Integer.MAX_VALUE : indexOfChild(lastLargeTaskView);
- Set<Integer> largeTasksIndices = new HashSet<>();
int focusedTaskShift = 0;
int largeTaskWidthAndSpacing = 0;
int snappedTaskRowWidth = 0;
@@ -3220,29 +3211,46 @@
if (!mAnyTaskHasBeenDismissed) {
mTopRowIdSet.clear();
}
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+
+ // Consecutive task views in the top row or bottom row, which means another one set will
+ // be cleared up while starting to add TaskViews to one of them. Also means only one of
+ // them can be non-empty at most.
+ Set<TaskView> lastTopTaskViews = new HashSet<>();
+ Set<TaskView> lastBottomTaskViews = new HashSet<>();
+
+ int largeTasksCount = 0;
+ // True if the last large TaskView has been visited during the TaskViews iteration.
+ boolean encounteredLastLargeTaskView = false;
+ // True if the highest index visible TaskView has been visited during the TaskViews
+ // iteration.
+ boolean encounteredLastVisibleTaskView = false;
+ for (TaskView taskView : getTaskViews()) {
+ if (taskView == lastLargeTaskView) {
+ encounteredLastLargeTaskView = true;
+ }
+ if (taskView == lastVisibleTaskViewDuringDismiss) {
+ encounteredLastVisibleTaskView = true;
+ }
+ float gridTranslation = 0f;
int taskWidthAndSpacing = taskView.getLayoutParams().width + mPageSpacing;
// Evenly distribute tasks between rows unless rearranging due to task dismissal, in
// which case keep tasks in their respective rows. For the running task, don't join
// the grid.
- boolean isLargeTile = taskView.isLargeTile();
-
- if (isLargeTile) {
+ if (taskView.isLargeTile()) {
+ largeTasksCount++;
// DesktopTaskView`s are hidden during split select state, so we shouldn't count
// them when calculating row width.
if (!(taskView instanceof DesktopTaskView && isSplitSelectionActive())) {
topRowWidth += taskWidthAndSpacing;
bottomRowWidth += taskWidthAndSpacing;
}
- gridTranslations[i] += focusedTaskShift;
- gridTranslations[i] += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
+ gridTranslation += focusedTaskShift;
+ gridTranslation += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
// Center view vertically in case it's from different orientation.
taskView.setGridTranslationY((mLastComputedTaskSize.height() + taskTopMargin
- taskView.getLayoutParams().height) / 2f);
- largeTasksIndices.add(i);
largeTaskWidthAndSpacing = taskWidthAndSpacing;
if (taskView == snappedTaskView) {
@@ -3250,9 +3258,9 @@
snappedTaskRowWidth = taskWidthAndSpacing;
}
} else {
- if (i > lastLargeTaskIndex) {
+ if (encounteredLastLargeTaskView) {
// For tasks after the last large task, shift by large task's width and spacing.
- gridTranslations[i] +=
+ gridTranslation +=
mIsRtl ? largeTaskWidthAndSpacing : -largeTaskWidthAndSpacing;
} else {
// For task before the focused task, accumulate the width and spacing to
@@ -3261,10 +3269,10 @@
}
int taskViewId = taskView.getTaskViewId();
- // Rebalance the grid starting after a certain index
boolean isTopRow;
if (mAnyTaskHasBeenDismissed) {
- if (i > startRebalanceAfter) {
+ // Rebalance the grid starting after a certain index.
+ if (encounteredLastVisibleTaskView) {
mTopRowIdSet.remove(taskViewId);
isTopRow = topRowWidth <= bottomRowWidth;
} else {
@@ -3281,47 +3289,43 @@
} else {
topRowWidth += taskWidthAndSpacing;
}
- topSet.add(i);
mTopRowIdSet.add(taskViewId);
-
taskView.setGridTranslationY(mTaskGridVerticalDiff);
// Move horizontally into empty space.
float widthOffset = 0;
- for (int j = i - 1; !topSet.contains(j) && j >= 0; j--) {
- if (largeTasksIndices.contains(j)) {
- continue;
- }
- widthOffset += requireTaskViewAt(j).getLayoutParams().width + mPageSpacing;
+ for (TaskView bottomTaskView : lastBottomTaskViews) {
+ widthOffset += bottomTaskView.getLayoutParams().width + mPageSpacing;
}
float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
- gridTranslations[i] += topAccumulatedTranslationX + currentTaskTranslationX;
+ gridTranslation += topAccumulatedTranslationX + currentTaskTranslationX;
topAccumulatedTranslationX += currentTaskTranslationX;
+ lastTopTaskViews.add(taskView);
+ lastBottomTaskViews.clear();
} else {
bottomRowWidth += taskWidthAndSpacing;
- bottomSet.add(i);
// Move into bottom row.
taskView.setGridTranslationY(mTopBottomRowHeightDiff + mTaskGridVerticalDiff);
// Move horizontally into empty space.
float widthOffset = 0;
- for (int j = i - 1; !bottomSet.contains(j) && j >= 0; j--) {
- if (largeTasksIndices.contains(j)) {
- continue;
- }
- widthOffset += requireTaskViewAt(j).getLayoutParams().width + mPageSpacing;
+ for (TaskView topTaskView : lastTopTaskViews) {
+ widthOffset += topTaskView.getLayoutParams().width + mPageSpacing;
}
float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
- gridTranslations[i] += bottomAccumulatedTranslationX + currentTaskTranslationX;
+ gridTranslation += bottomAccumulatedTranslationX + currentTaskTranslationX;
bottomAccumulatedTranslationX += currentTaskTranslationX;
+ lastBottomTaskViews.add(taskView);
+ lastTopTaskViews.clear();
}
if (taskView == snappedTaskView) {
snappedTaskRowWidth = isTopRow ? topRowWidth : bottomRowWidth;
}
}
+ gridTranslations.put(taskView, gridTranslation);
}
// We need to maintain snapped task's page scroll invariant between quick switch and
@@ -3332,22 +3336,22 @@
if (snappedTaskView != null) {
snappedTaskNonGridScrollAdjustment = snappedTaskView.getScrollAdjustment(
/*gridEnabled=*/false);
- snappedTaskGridTranslationX = gridTranslations[snappedPage];
+ snappedTaskGridTranslationX = gridTranslations.get(snappedTaskView);
}
// Use the accumulated translation of the row containing the last task.
- float clearAllAccumulatedTranslation = topSet.contains(taskCount - 1)
+ float clearAllAccumulatedTranslation = !lastTopTaskViews.isEmpty()
? topAccumulatedTranslationX : bottomAccumulatedTranslationX;
// If the last task is on the shorter row, ClearAllButton will embed into the shorter row
// which is not what we want. Compensate the width difference of the 2 rows in that case.
float shorterRowCompensation = 0;
if (topRowWidth <= bottomRowWidth) {
- if (topSet.contains(taskCount - 1)) {
+ if (!lastTopTaskViews.isEmpty()) {
shorterRowCompensation = bottomRowWidth - topRowWidth;
}
} else {
- if (bottomSet.contains(taskCount - 1)) {
+ if (!lastBottomTaskViews.isEmpty()) {
shorterRowCompensation = topRowWidth - bottomRowWidth;
}
}
@@ -3363,8 +3367,7 @@
// for ClearAllButton translation. The space at the left side of the large task will be
// empty and it should be move ClearAllButton further away as well.
// TODO(b/359573248): Validate the translation for ClearAllButton for grid only.
- boolean hasOnlyLargeTasks = taskCount == largeTasksIndices.size();
- if (enableLargeDesktopWindowingTile() && hasOnlyLargeTasks) {
+ if (enableLargeDesktopWindowingTile() && largeTasksCount == getTaskViewCount()) {
longRowWidth = largeTaskWidthAndSpacing;
}
@@ -3388,7 +3391,7 @@
float clearAllTotalTranslationX =
clearAllAccumulatedTranslation + clearAllShorterRowCompensation
+ clearAllShortTotalWidthTranslation + snappedTaskNonGridScrollAdjustment;
- if (!largeTasksIndices.isEmpty()) {
+ if (largeTasksCount > 0) {
// Shift by focused task's width and spacing if a task is focused.
clearAllTotalTranslationX +=
mIsRtl ? largeTaskWidthAndSpacing : -largeTaskWidthAndSpacing;
@@ -3412,10 +3415,10 @@
}
}
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
- taskView.setGridTranslationX(gridTranslations[i] - snappedTaskGridTranslationX
- + snappedTaskNonGridScrollAdjustment);
+ for (TaskView taskView : getTaskViews()) {
+ taskView.setGridTranslationX(
+ gridTranslations.get(taskView) - snappedTaskGridTranslationX
+ + snappedTaskNonGridScrollAdjustment);
}
final TaskView runningTask = getRunningTaskView();
@@ -4154,7 +4157,8 @@
// Rebalance tasks in the grid
int highestVisibleTaskIndex = getHighestVisibleTaskIndex();
if (highestVisibleTaskIndex < Integer.MAX_VALUE) {
- TaskView taskView = requireTaskViewAt(highestVisibleTaskIndex);
+ final TaskView taskView = requireTaskViewAt(
+ highestVisibleTaskIndex);
boolean shouldRebalance;
int screenStart = getPagedOrientationHandler().getPrimaryScroll(
@@ -4182,7 +4186,7 @@
}
if (shouldRebalance) {
- updateGridProperties(highestVisibleTaskIndex);
+ updateGridProperties(taskView);
updateScrollSynchronously();
}
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index 5471072..2f773b3 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -245,6 +245,10 @@
animator.onStashStateChangingWhileAnimating()
}
+ // The physics animation test util posts the cancellation to the looper thread, so we have
+ // to wait again and let it finish.
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync()
+
// verify that the hide animation was canceled
assertThat(animatorScheduler.delayedBlock).isNull()
assertThat(animator.isAnimating).isFalse()
@@ -1296,7 +1300,7 @@
animator.animateBubbleInForStashed(updatedBubble, isExpanding = false)
}
- // since animation was interrupted there shouldn`t be additional calls to adjust window
+ // since animation was interrupted there shouldn't be additional calls to adjust window
assertThat(bubbleBarParentViewController.timesInvoked).isEqualTo(1)
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml
index 0e2c19a..a19d13a 100644
--- a/res/layout/work_apps_edu.xml
+++ b/res/layout/work_apps_edu.xml
@@ -46,6 +46,8 @@
android:layout_width="@dimen/rounded_button_width"
android:layout_height="@dimen/rounded_button_width"
android:layout_marginTop="@dimen/work_edu_card_button_margin_top"
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_close"
android:gravity="center"
android:background="@drawable/inset_rounded_action_button">
<ImageButton
@@ -54,7 +56,7 @@
android:clickable="false"
android:scaleType="centerInside"
android:layout_gravity="center"
- android:contentDescription="@string/accessibility_close"
+ android:importantForAccessibility="no"
android:background="@android:color/transparent"
android:src="@drawable/ic_close_work_edu" />
</FrameLayout>
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index ba6ed66..81d6631 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -305,7 +305,6 @@
info.spanX, info.spanY);
host.requestLayout();
mContext.getModelWriter().updateItemInDatabase(info);
- announceConfirmation(mContext.getString(R.string.widget_resized, info.spanX, info.spanY));
return true;
}
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index 84d6a6f..65b0662 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -114,9 +114,7 @@
LauncherAccessibilityDelegate.DragInfo dragInfo = mDelegate.getDragInfo();
View child = mView.getChildAt(x, y);
- if (child == null || child == dragInfo.item) {
- return mContext.getString(R.string.item_moved);
- } else {
+ if (child != null && child != dragInfo.item) {
ItemInfo info = (ItemInfo) child.getTag();
if (Folder.willAccept(info)) {
return mContext.getString(R.string.folder_created);
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 5defef3..e68e3c9 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -680,6 +680,7 @@
closeOpenFolder(openFolder);
mContent.bindItems(items);
+ mContent.setCanAnnouncePageDescriptionForFolder(true);
centerAboutIcon();
mItemsInvalidated = true;
updateTextViewFocus();
@@ -813,6 +814,7 @@
@Override
protected void handleClose(boolean animate) {
mIsOpen = false;
+ mContent.setCanAnnouncePageDescriptionForFolder(false);
if (!animate && mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
mCurrentAnimator.cancel();
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index fe26194..8d751e6 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -100,6 +100,8 @@
// animating or is open.
private boolean mViewsBound = false;
+ private boolean mCanAnnouncePageDescription;
+
public FolderPagedView(Context context, AttributeSet attrs) {
this(
context,
@@ -170,6 +172,19 @@
mViewsBound = true;
}
+ void setCanAnnouncePageDescriptionForFolder(boolean canAnnounce) {
+ mCanAnnouncePageDescription = canAnnounce;
+ }
+
+ private boolean canAnnouncePageDescriptionForFolder() {
+ return mCanAnnouncePageDescription;
+ }
+
+ @Override
+ protected boolean canAnnouncePageDescription() {
+ return super.canAnnouncePageDescription() && canAnnouncePageDescriptionForFolder();
+ }
+
/**
* Removes all the icons from the folder
*/