Merge "Do not add arrow to OptionsPopupView." into sc-dev
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index b124b33..84e2304 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -25,7 +25,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/taskbar_background"
- android:gravity="center"
- android:animateLayoutChanges="true"/>
+ android:gravity="center"/>
</com.android.launcher3.taskbar.TaskbarContainerView>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 9773366..2a24624 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -16,20 +16,30 @@
<resources>
- <dimen name="task_thumbnail_top_margin">24dp</dimen>
- <dimen name="task_thumbnail_half_top_margin">12dp</dimen>
+ <dimen name="task_thumbnail_top_margin">80dp</dimen>
+ <dimen name="task_thumbnail_half_top_margin">40dp</dimen>
<dimen name="task_thumbnail_icon_size">48dp</dimen>
- <dimen name="task_icon_top_margin">-16dp</dimen>
+ <dimen name="task_icon_top_margin">16dp</dimen>
<!-- For screens without rounded corners -->
<dimen name="task_corner_radius_small">2dp</dimen>
+ <dimen name="overview_proactive_row_height">48dp</dimen>
+ <dimen name="overview_proactive_row_bottom_margin">16dp</dimen>
+
+ <dimen name="overview_minimum_next_prev_size">48dp</dimen>
+ <dimen name="overview_task_margin">16dp</dimen>
+
<!-- Overrideable in overlay that provides the Overview Actions. -->
- <dimen name="overview_actions_height">66dp</dimen>
- <dimen name="overview_actions_bottom_margin_gesture">16dp</dimen>
+ <dimen name="overview_actions_height">48dp</dimen>
+ <dimen name="overview_actions_bottom_margin_gesture">12dp</dimen>
<dimen name="overview_actions_bottom_margin_three_button">8dp</dimen>
<dimen name="overview_actions_horizontal_margin">16dp</dimen>
- <dimen name="recents_row_spacing">48dp</dimen>
+ <dimen name="overview_grid_top_margin">77dp</dimen>
+ <dimen name="overview_grid_bottom_margin">90dp</dimen>
+ <dimen name="overview_grid_side_margin">54dp</dimen>
+ <dimen name="overview_grid_row_spacing">42dp</dimen>
+
<dimen name="recents_page_spacing">16dp</dimen>
<dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
@@ -59,10 +69,6 @@
<dimen name="task_card_menu_option_vertical_padding">8dp</dimen>
<dimen name="task_card_menu_shadow_height">3dp</dimen>
<dimen name="task_card_menu_horizontal_padding">0dp</dimen>
- <dimen name="portrait_task_card_horz_space_big_overview">132dp</dimen>
- <dimen name="portrait_modal_task_card_horz_space">60dp</dimen>
- <dimen name="landscape_task_card_horz_space">200dp</dimen>
- <dimen name="multi_window_task_card_horz_space">100dp</dimen>
<!-- Copied from framework resource:
docked_stack_divider_thickness - 2 * docked_stack_divider_insets -->
<dimen name="multi_window_task_divider_size">10dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 6eb1498..4f706cf 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -328,6 +328,10 @@
@Override
public void onDragLayerHierarchyChanged() {
onLauncherStateOrFocusChanged();
+
+ if (mTaskbarController != null) {
+ mTaskbarController.onLauncherDragLayerHierarchyChanged();
+ }
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
index 52b3195..744339b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
@@ -19,6 +19,8 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_REPLACE_TASKBAR_WITH_HOTSEAT;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
@@ -40,6 +42,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.R;
@@ -144,22 +147,13 @@
ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key,
ActivityOptions.makeBasic());
} else if (tag instanceof FolderInfo) {
- FolderIcon folderIcon = (FolderIcon) view;
- Folder folder = folderIcon.getFolder();
-
- setTaskbarWindowFullscreen(true);
-
- mTaskbarContainerView.post(() -> {
- folder.animateOpen();
-
- folder.iterateOverItems((itemInfo, itemView) -> {
- itemView.setOnClickListener(getItemOnClickListener());
- itemView.setOnLongClickListener(getItemOnLongClickListener());
- // To play haptic when dragging, like other Taskbar items do.
- itemView.setHapticFeedbackEnabled(true);
- return false;
- });
- });
+ if (mLauncher.hasBeenResumed()) {
+ FolderInfo folderInfo = (FolderInfo) tag;
+ onClickedOnFolderFromHome(folderInfo);
+ } else {
+ FolderIcon folderIcon = (FolderIcon) view;
+ onClickedOnFolderInApp(folderIcon);
+ }
} else {
ItemClickHandler.INSTANCE.onClick(view);
}
@@ -169,6 +163,34 @@
};
}
+ // Open the real folder in Launcher.
+ private void onClickedOnFolderFromHome(FolderInfo folderInfo) {
+ alignRealHotseatWithTaskbar();
+
+ FolderIcon folderIcon = (FolderIcon) mLauncher.getHotseat()
+ .getFirstItemMatch((info, v) -> info == folderInfo);
+ folderIcon.post(folderIcon::performClick);
+ }
+
+ // Open the Taskbar folder, and handle clicks on folder items.
+ private void onClickedOnFolderInApp(FolderIcon folderIcon) {
+ Folder folder = folderIcon.getFolder();
+
+ setTaskbarWindowFullscreen(true);
+
+ mTaskbarContainerView.post(() -> {
+ folder.animateOpen();
+
+ folder.iterateOverItems((itemInfo, itemView) -> {
+ itemView.setOnClickListener(getItemOnClickListener());
+ itemView.setOnLongClickListener(getItemOnLongClickListener());
+ // To play haptic when dragging, like other Taskbar items do.
+ itemView.setHapticFeedbackEnabled(true);
+ return false;
+ });
+ });
+ }
+
@Override
public View.OnLongClickListener getItemOnLongClickListener() {
return view -> {
@@ -307,6 +329,7 @@
mAnimator = createAnimToLauncher(null, duration);
} else {
mAnimator = createAnimToApp(duration);
+ replaceTaskbarWithHotseatOrViceVersa();
}
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
@@ -356,6 +379,7 @@
@Override
public void onAnimationStart(Animator animation) {
mTaskbarView.updateHotseatItemsVisibility();
+ setReplaceTaskbarWithHotseat(false);
}
});
return anim.buildAnim();
@@ -452,6 +476,35 @@
mTaskbarView.getHeight() - hotseatBounds.bottom);
}
+ /**
+ * A view was added or removed from DragLayer, check if we need to hide our hotseat copy and
+ * show the real one instead.
+ */
+ public void onLauncherDragLayerHierarchyChanged() {
+ replaceTaskbarWithHotseatOrViceVersa();
+ }
+
+ private void replaceTaskbarWithHotseatOrViceVersa() {
+ boolean replaceTaskbarWithHotseat = AbstractFloatingView.getTopOpenViewWithType(mLauncher,
+ TYPE_ALL & TYPE_REPLACE_TASKBAR_WITH_HOTSEAT) != null;
+ if (!mLauncher.hasBeenResumed()) {
+ replaceTaskbarWithHotseat = false;
+ }
+ setReplaceTaskbarWithHotseat(replaceTaskbarWithHotseat);
+ }
+
+ private void setReplaceTaskbarWithHotseat(boolean replaceTaskbarWithHotseat) {
+ Hotseat hotseat = mLauncher.getHotseat();
+ if (replaceTaskbarWithHotseat) {
+ alignRealHotseatWithTaskbar();
+ hotseat.getReplaceTaskbarAlpha().setValue(1f);
+ mTaskbarView.setHotseatViewsHidden(true);
+ } else {
+ hotseat.getReplaceTaskbarAlpha().setValue(0f);
+ mTaskbarView.setHotseatViewsHidden(false);
+ }
+ }
+
private float getTaskbarScaleOnHome() {
return 1f / mTaskbarContainerView.getTaskbarActivityContext().getTaskbarIconScale();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index a729e77..1d762e9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.taskbar;
+import android.animation.LayoutTransition;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
@@ -63,6 +64,7 @@
private TaskbarController.TaskbarViewCallbacks mControllerCallbacks;
// Initialized in init().
+ private LayoutTransition mLayoutTransition;
private int mHotseatStartIndex;
private int mHotseatEndIndex;
private View mHotseatRecentsDivider;
@@ -76,6 +78,7 @@
private boolean mIsDraggingItem;
// Only non-null when the corresponding Folder is open.
private @Nullable FolderIcon mLeaveBehindFolderIcon;
+ private boolean mIsHotseatHidden;
public TaskbarView(@NonNull Context context) {
this(context, null);
@@ -107,6 +110,9 @@
}
protected void init(int numHotseatIcons, int numRecentIcons) {
+ mLayoutTransition = new LayoutTransition();
+ setLayoutTransitionsEnabled(true);
+
mHotseatStartIndex = 0;
mHotseatEndIndex = mHotseatStartIndex + numHotseatIcons - 1;
updateHotseatItems(new ItemInfo[numHotseatIcons]);
@@ -119,6 +125,10 @@
updateRecentTasks(new Task[numRecentIcons]);
}
+ private void setLayoutTransitionsEnabled(boolean enabled) {
+ setLayoutTransition(enabled ? mLayoutTransition : null);
+ }
+
protected void cleanup() {
removeAllViews();
}
@@ -206,9 +216,19 @@
}
}
+ /**
+ * Hides or shows the hotseat items immediately (without layout transitions).
+ */
+ protected void setHotseatViewsHidden(boolean hidden) {
+ mIsHotseatHidden = hidden;
+ setLayoutTransitionsEnabled(false);
+ updateHotseatItemsVisibility();
+ setLayoutTransitionsEnabled(true);
+ }
+
private void updateHotseatItemVisibility(View hotseatView) {
if (hotseatView.getTag() != null) {
- hotseatView.setVisibility(VISIBLE);
+ hotseatView.setVisibility(mIsHotseatHidden ? INVISIBLE : VISIBLE);
} else {
int oldVisibility = hotseatView.getVisibility();
int newVisibility = mControllerCallbacks.getEmptyHotseatViewVisibility();
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index ce14197..7c1d9fa 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -33,6 +33,7 @@
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Build;
+import android.view.Gravity;
import android.view.MotionEvent;
import androidx.annotation.Nullable;
@@ -53,6 +54,7 @@
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.SplitScreenBounds;
import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -197,33 +199,23 @@
*/
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
PagedOrientationHandler orientedState) {
- calculateTaskSize(context, dp, getExtraSpace(context, dp, orientedState), outRect);
- }
-
- protected abstract float getExtraSpace(Context context, DeviceProfile dp,
- PagedOrientationHandler orientedState);
-
- private void calculateTaskSize(Context context, DeviceProfile dp, float extraVerticalSpace,
- Rect outRect) {
Resources res = context.getResources();
- final int paddingResId;
- if (dp.isMultiWindowMode) {
- paddingResId = R.dimen.multi_window_task_card_horz_space;
- } else if (dp.isVerticalBarLayout()) {
- paddingResId = R.dimen.landscape_task_card_horz_space;
- } else {
- paddingResId = R.dimen.portrait_task_card_horz_space_big_overview;
- }
- float paddingHorz = res.getDimension(paddingResId);
- float paddingVert = 0;
+ int taskMargin = res.getDimensionPixelSize(R.dimen.overview_task_margin);
+ int taskIconAndMargin = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size)
+ + res.getDimensionPixelSize(R.dimen.task_icon_top_margin);
+ int proactiveRowAndMargin = res.getDimensionPixelSize(R.dimen.overview_proactive_row_height)
+ + res.getDimensionPixelSize(R.dimen.overview_proactive_row_bottom_margin);
- calculateTaskSizeInternal(context, dp, extraVerticalSpace, paddingHorz, paddingVert,
- res.getDimension(R.dimen.task_thumbnail_top_margin), outRect);
+ calculateTaskSizeInternal(context, dp,
+ taskIconAndMargin + taskMargin,
+ proactiveRowAndMargin + getOverviewActionsHeight(context) + taskMargin,
+ res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
+ outRect);
}
private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
- float extraVerticalSpace, float paddingHorz, float paddingVert, float topIconMargin,
+ int claimedSpaceAbove, int claimedSpaceBelow, int minimumHorizontalPadding,
Rect outRect) {
float taskWidth, taskHeight;
Rect insets = dp.getInsets();
@@ -231,52 +223,64 @@
WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
taskWidth = bounds.availableSize.x;
taskHeight = bounds.availableSize.y;
- } else {
+ } else if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
taskWidth = dp.availableWidthPx;
taskHeight = dp.availableHeightPx;
+ } else {
+ taskWidth = dp.widthPx;
+ taskHeight = dp.heightPx;
}
- // Note this should be same as dp.availableWidthPx and dp.availableHeightPx unless
- // we override the insets ourselves.
- int launcherVisibleWidth = dp.widthPx - insets.left - insets.right;
- int launcherVisibleHeight = dp.heightPx - insets.top - insets.bottom;
+ Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
+ potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);
+ potentialTaskRect.inset(
+ minimumHorizontalPadding,
+ claimedSpaceAbove,
+ minimumHorizontalPadding,
+ claimedSpaceBelow);
- float availableHeight = launcherVisibleHeight
- - topIconMargin - extraVerticalSpace - paddingVert;
- float availableWidth = launcherVisibleWidth - paddingHorz;
+ float scale = Math.min(
+ potentialTaskRect.width() / taskWidth,
+ potentialTaskRect.height() / taskHeight);
+ int outWidth = Math.round(scale * taskWidth);
+ int outHeight = Math.round(scale * taskHeight);
- float scale = Math.min(availableWidth / taskWidth, availableHeight / taskHeight);
- float outWidth = scale * taskWidth;
- float outHeight = scale * taskHeight;
+ Gravity.apply(Gravity.CENTER, outWidth, outHeight, potentialTaskRect, outRect);
+ }
- // Center in the visible space
- float x = insets.left + (launcherVisibleWidth - outWidth) / 2;
- float y = insets.top + Math.max(topIconMargin,
- (launcherVisibleHeight - extraVerticalSpace - outHeight) / 2);
- outRect.set(Math.round(x), Math.round(y),
- Math.round(x) + Math.round(outWidth), Math.round(y) + Math.round(outHeight));
+ /**
+ * Calculates the overview grid size for the provided device configuration.
+ */
+ public final void calculateGridSize(Context context, DeviceProfile dp, Rect outRect) {
+ Resources res = context.getResources();
+ int topMargin = res.getDimensionPixelSize(R.dimen.overview_grid_top_margin);
+ int bottomMargin = res.getDimensionPixelSize(R.dimen.overview_grid_bottom_margin);
+ int sideMargin = res.getDimensionPixelSize(R.dimen.overview_grid_side_margin);
+
+ Rect insets = dp.getInsets();
+ outRect.set(0, 0, dp.widthPx, dp.heightPx);
+ outRect.inset(Math.max(insets.left, sideMargin), Math.max(insets.top, topMargin),
+ Math.max(insets.right, sideMargin), Math.max(insets.bottom, bottomMargin));
}
/**
* Calculates the modal taskView size for the provided device configuration
*/
public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect) {
- float paddingHorz = context.getResources().getDimension(dp.isMultiWindowMode
- ? R.dimen.multi_window_task_card_horz_space
- : dp.isVerticalBarLayout()
- ? R.dimen.landscape_task_card_horz_space
- : R.dimen.portrait_modal_task_card_horz_space);
- float extraVerticalSpace = getOverviewActionsHeight(context);
- float paddingVert = 0;
- float topIconMargin = 0;
- calculateTaskSizeInternal(context, dp, extraVerticalSpace, paddingHorz, paddingVert,
- topIconMargin, outRect);
+ Resources res = context.getResources();
+ calculateTaskSizeInternal(
+ context, dp,
+ res.getDimensionPixelSize(R.dimen.overview_task_margin),
+ getOverviewActionsHeight(context)
+ + res.getDimensionPixelSize(R.dimen.overview_task_margin),
+ res.getDimensionPixelSize(R.dimen.overview_task_margin),
+ outRect);
}
- /** Gets the space that the overview actions will take, including margins. */
- public final float getOverviewActionsHeight(Context context) {
+ /** Gets the space that the overview actions will take, including bottom margin. */
+ public final int getOverviewActionsHeight(Context context) {
Resources res = context.getResources();
- float actionsBottomMargin = 0;
+ int actionsBottomMargin = 0;
if (getMode(context) == Mode.THREE_BUTTONS) {
actionsBottomMargin = res.getDimensionPixelSize(
R.dimen.overview_actions_bottom_margin_three_button);
@@ -284,9 +288,8 @@
actionsBottomMargin = res.getDimensionPixelSize(
R.dimen.overview_actions_bottom_margin_gesture);
}
- float overviewActionsHeight = actionsBottomMargin
+ return actionsBottomMargin
+ res.getDimensionPixelSize(R.dimen.overview_actions_height);
- return overviewActionsHeight;
}
/**
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 96e4f38..db290d6 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -26,7 +26,6 @@
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.ActivityInitListener;
@@ -155,10 +154,4 @@
}
activity.<RecentsView>getOverviewPanel().startHome();
}
-
- @Override
- protected float getExtraSpace(Context context, DeviceProfile dp,
- PagedOrientationHandler orientationHandler) {
- return context.getResources().getDimensionPixelSize(R.dimen.overview_actions_height);
- }
}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 3f3e5ad..7efbfb8 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -19,13 +19,10 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.quickstep.SysUINavigationMode.getMode;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Rect;
-import android.util.Log;
import android.view.MotionEvent;
import androidx.annotation.Nullable;
@@ -36,13 +33,11 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherInitListener;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.taskbar.TaskbarController;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.SysUINavigationMode.Mode;
@@ -263,27 +258,6 @@
}
@Override
- protected float getExtraSpace(Context context, DeviceProfile dp,
- PagedOrientationHandler orientationHandler) {
- Resources res = context.getResources();
- //TODO: this needs to account for the swipe gesture height and accessibility
- // UI when shown.
- float actionsBottomMargin = 0;
- if (!dp.isVerticalBarLayout()) {
- if (getMode(context) == Mode.THREE_BUTTONS) {
- actionsBottomMargin = res.getDimensionPixelSize(
- R.dimen.overview_actions_bottom_margin_three_button);
- } else {
- actionsBottomMargin = res.getDimensionPixelSize(
- R.dimen.overview_actions_bottom_margin_gesture);
- }
- }
- float actionsHeight = actionsBottomMargin
- + res.getDimensionPixelSize(R.dimen.overview_actions_height);
- return actionsHeight;
- }
-
- @Override
void onOverviewServiceBound() {
final BaseQuickstepLauncher activity = getCreatedActivity();
if (activity == null) return;
diff --git a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
index d022085..0f2d778 100644
--- a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
+++ b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
@@ -99,7 +99,14 @@
.putExtra(Intent.EXTRA_STREAM, uri)
.putExtra(Intent.EXTRA_SHORTCUT_ID, shortcutInfo.getId())
.setClipData(clipdata);
- context.startActivity(intent);
+
+ if (context.getUserId() != appTarget.getUser().getIdentifier()) {
+ intent.prepareToLeaveUser(context.getUserId());
+ intent.fixUris(context.getUserId());
+ context.startActivityAsUser(intent, appTarget.getUser());
+ } else {
+ context.startActivity(intent);
+ }
}
/**
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 215f05a..188efad 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -23,9 +23,9 @@
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
-import static com.android.launcher3.util.SettingsCache.ROTATION_SETTING_URI;
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.SettingsCache.ROTATION_SETTING_URI;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -47,11 +47,12 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.views.TaskView;
import java.lang.annotation.Retention;
import java.util.function.IntConsumer;
@@ -367,8 +368,12 @@
*/
public float getFullScreenScaleAndPivot(Rect taskView, DeviceProfile dp, PointF outPivot) {
Rect insets = dp.getInsets();
- float fullWidth = dp.widthPx - insets.left - insets.right;
- float fullHeight = dp.heightPx - insets.top - insets.bottom;
+ float fullWidth = dp.widthPx;
+ float fullHeight = dp.heightPx;
+ if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
+ fullWidth -= insets.left + insets.right;
+ fullHeight -= insets.top + insets.bottom;
+ }
if (dp.isMultiWindowMode) {
WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(mContext);
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 9537247..df1229b 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -79,6 +79,7 @@
private final boolean mIsRecentsRtl;
private final Rect mTaskRect = new Rect();
+ private final Rect mGridRect = new Rect();
private boolean mDrawsBelowRecents;
private final PointF mPivot = new PointF();
private DeviceProfile mDp;
@@ -124,7 +125,7 @@
Resources resources = context.getResources();
mIsRecentsRtl = mOrientationState.getOrientationHandler().getRecentsRtlSetting(resources);
mTaskThumbnailPadding = (int) resources.getDimension(R.dimen.task_thumbnail_top_margin);
- mRowSpacing = (int) resources.getDimension(R.dimen.recents_row_spacing);
+ mRowSpacing = (int) resources.getDimension(R.dimen.overview_grid_row_spacing);
}
/**
@@ -266,6 +267,7 @@
mOrientationStateId = mOrientationState.getStateId();
getFullScreenScale();
+ mSizeStrategy.calculateGridSize(mContext, mDp, mGridRect);
mThumbnailData.rotation = mOrientationState.getDisplayRotation();
mPositionHelper.updateThumbnailMatrix(
@@ -304,24 +306,34 @@
mMatrix.postTranslate(insets.left, insets.top);
mMatrix.postScale(scale, scale);
+ // Apply TaskView matrix: gridProgress related properties
float interpolatedGridProgress = ACCEL_DEACCEL.getInterpolation(gridProgress.value);
-
- // Apply TaskView matrix: gridProgress
final int boxLength = (int) Math.max(taskWidth, taskHeight);
- float availableHeight =
- mTaskThumbnailPadding + taskHeight + mSizeStrategy.getOverviewActionsHeight(
- mContext);
+ float availableHeight = mGridRect.height();
float rowHeight = (availableHeight - mRowSpacing) / 2;
float gridScale = rowHeight / (boxLength + mTaskThumbnailPadding);
scale = Utilities.mapRange(interpolatedGridProgress, 1f, gridScale);
mMatrix.postScale(scale, scale, mIsRecentsRtl ? 0 : taskWidth, 0);
- float taskWidthDiff = taskWidth * (1 - gridScale);
- float taskWidthOffset = mIsRecentsRtl ? taskWidthDiff : -taskWidthDiff;
- mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
- Utilities.mapRange(interpolatedGridProgress, 0, taskWidthOffset));
mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
Utilities.mapRange(interpolatedGridProgress, 0, gridTranslationSecondary.value));
+ // Apply TaskView matrix: task rect and grid rect difference
+ float scaledWidth = taskWidth * gridScale;
+ float taskGridHorizontalDiff;
+ if (mIsRecentsRtl) {
+ float taskRight = mTaskRect.left + scaledWidth;
+ taskGridHorizontalDiff = mGridRect.right - taskRight;
+ } else {
+ float taskLeft = mTaskRect.right - scaledWidth;
+ taskGridHorizontalDiff = mGridRect.left - taskLeft;
+ }
+ float taskGridVerticalDiff =
+ mGridRect.top + mTaskThumbnailPadding * gridScale - mTaskRect.top;
+ mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
+ Utilities.mapRange(interpolatedGridProgress, 0, taskGridHorizontalDiff));
+ mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
+ Utilities.mapRange(interpolatedGridProgress, 0, taskGridVerticalDiff));
+
// Apply TaskView matrix: translate, scroll
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index d4548df..9a903dc 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -264,6 +264,7 @@
protected final TransformParams mLiveTileParams = new TransformParams();
protected final TaskViewSimulator mLiveTileTaskViewSimulator;
protected final Rect mLastComputedTaskSize = new Rect();
+ protected final Rect mLastComputedGridSize = new Rect();
// How much a task that is directly offscreen will be pushed out due to RecentsView scale/pivot.
protected Float mLastComputedTaskPushOutDistance = null;
protected boolean mEnableDrawingLiveTile = false;
@@ -471,7 +472,7 @@
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
mTaskTopMargin = getResources()
.getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
- mRowSpacing = (int) getResources().getDimension(R.dimen.recents_row_spacing);
+ mRowSpacing = getResources().getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
mSquaredTouchSlop = squaredTouchSlop(context);
mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
@@ -1012,6 +1013,10 @@
setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
dp.widthPx - mInsets.right - mTempRect.right,
dp.heightPx - mInsets.bottom - mTempRect.bottom);
+
+ mSizeStrategy.calculateGridSize(mActivity, mActivity.getDeviceProfile(),
+ mLastComputedGridSize);
+
// Force TaskView to update size from thumbnail
updateTaskSize();
}
@@ -1521,22 +1526,10 @@
}
final int boxLength = Math.max(mTaskWidth, mTaskHeight);
-
- float availableHeight =
- mTaskTopMargin + mTaskHeight + mSizeStrategy.getOverviewActionsHeight(mContext);
+ float availableHeight = mLastComputedGridSize.height();
float rowHeight = (availableHeight - mRowSpacing) / 2;
float gridScale = rowHeight / (boxLength + mTaskTopMargin);
- TaskView firstTask = getTaskViewAt(0);
- float firstTaskWidthOffset;
- if (mIsRtl) {
- // Move the first task to the right edge.
- firstTaskWidthOffset = mTaskWidth - firstTask.getLayoutParams().width * gridScale;
- } else {
- // Move the first task to the left edge.
- firstTaskWidthOffset = -firstTask.getLayoutParams().width * (1 - gridScale);
- }
-
int topRowWidth = 0;
int bottomRowWidth = 0;
float topAccumulatedTranslationX = 0;
@@ -1546,13 +1539,22 @@
for (int i = 0; i < taskCount; i++) {
TaskView taskView = getTaskViewAt(i);
taskView.setGridScale(gridScale);
+ gridTranslations[i] = 0;
- float taskWidthDiff = mTaskWidth - taskView.getLayoutParams().width * gridScale;
- float taskWidthOffset = mIsRtl ? taskWidthDiff : -taskWidthDiff;
- // Visually we want to move all task by firstTaskWidthOffset, but calculate page scroll
- // according to right edge (or left in nonRtl) of TaskView.
- gridTranslations[i] = firstTaskWidthOffset - taskWidthOffset;
- taskView.setGridOffsetTranslationX(taskWidthOffset);
+ float scaledWidth = taskView.getLayoutParams().width * gridScale;
+ float taskGridHorizontalDiff;
+ if (mIsRtl) {
+ float taskRight = mLastComputedTaskSize.left + scaledWidth;
+ taskGridHorizontalDiff = mLastComputedGridSize.right - taskRight;
+ } else {
+ float taskLeft = mLastComputedTaskSize.right - scaledWidth;
+ taskGridHorizontalDiff = mLastComputedGridSize.left - taskLeft;
+ }
+ gridTranslations[i] -= taskGridHorizontalDiff;
+ taskView.setGridOffsetTranslationX(taskGridHorizontalDiff);
+
+ float taskGridVerticalDiff = mLastComputedGridSize.top + mTaskTopMargin * gridScale
+ - mLastComputedTaskSize.top;
// Off-set gap due to task scaling.
float widthDiff = taskView.getLayoutParams().width * (1 - gridScale);
@@ -1567,7 +1569,7 @@
topRowWidth += taskView.getLayoutParams().width * gridScale + mPageSpacing;
topSet.add(i);
- taskView.setGridTranslationY(0);
+ taskView.setGridTranslationY(taskGridVerticalDiff);
// Move horizontally into empty space.
float widthOffset = 0;
@@ -1578,15 +1580,14 @@
float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
gridTranslations[i] += gridTranslationX;
- topAccumulatedTranslationX += gridTranslationX + gridScaleTranslationX;
- bottomAccumulatedTranslationX += gridScaleTranslationX;
+ topAccumulatedTranslationX += gridTranslationX;
} else {
gridTranslations[i] += bottomAccumulatedTranslationX;
bottomRowWidth += taskView.getLayoutParams().width * gridScale + mPageSpacing;
// Move into bottom row.
float heightOffset = (boxLength + mTaskTopMargin) * gridScale + mRowSpacing;
- taskView.setGridTranslationY(heightOffset);
+ taskView.setGridTranslationY(heightOffset + taskGridVerticalDiff);
// Move horizontally into empty space.
float widthOffset = 0;
@@ -1597,9 +1598,10 @@
float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
gridTranslations[i] += gridTranslationX;
- topAccumulatedTranslationX += gridScaleTranslationX;
- bottomAccumulatedTranslationX += gridTranslationX + gridScaleTranslationX;
+ bottomAccumulatedTranslationX += gridTranslationX;
}
+ topAccumulatedTranslationX += gridScaleTranslationX;
+ bottomAccumulatedTranslationX += gridScaleTranslationX;
}
// Use the accumulated translation of the longer row.
@@ -1632,8 +1634,9 @@
mIsRtl ? -shortTotalCompensation : shortTotalCompensation;
}
- float clearAllTotalTranslationX = firstTaskWidthOffset + clearAllAccumulatedTranslation
- + clearAllShorterRowCompensation + clearAllShortTotalCompensation;
+ float clearAllTotalTranslationX =
+ clearAllAccumulatedTranslation + clearAllShorterRowCompensation
+ + clearAllShortTotalCompensation;
// We need to maintain first task's grid translation at 0, now shift translation of all
// the TaskViews to achieve that.
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 4c21745..36a5f03 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -212,13 +212,6 @@
return mDimAlpha;
}
- public Rect getInsets(Rect fallback) {
- if (mThumbnailData != null) {
- return mThumbnailData.insets;
- }
- return fallback;
- }
-
/**
* Get the scaled insets that are being used to draw the task view. This is a subsection of
* the full snapshot.
@@ -230,6 +223,10 @@
return Insets.NONE;
}
+ if (!TaskView.CLIP_STATUS_AND_NAV_BARS) {
+ return Insets.NONE;
+ }
+
RectF bitmapRect = new RectF(
0, 0,
mThumbnailData.thumbnail.getWidth(), mThumbnailData.thumbnail.getHeight());
@@ -459,7 +456,6 @@
// Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
private final RectF mClippedInsets = new RectF();
private final Matrix mMatrix = new Matrix();
- private float mClipBottom = -1;
private boolean mIsOrientationChanged;
public Matrix getMatrix() {
@@ -476,7 +472,8 @@
int thumbnailRotation = thumbnailData.rotation;
int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
- RectF thumbnailClipHint = new RectF(thumbnailData.insets);
+ RectF thumbnailClipHint = TaskView.CLIP_STATUS_AND_NAV_BARS
+ ? new RectF(thumbnailData.insets) : new RectF();
float scale = thumbnailData.scale;
final float thumbnailScale;
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 605eb3f..eace0f8 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -121,6 +121,12 @@
*/
public static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
+ /**
+ * Should the TaskView display clip off the status and navigation bars in recents. When this
+ * is false the overview shows the whole screen scaled down instead.
+ */
+ public static final boolean CLIP_STATUS_AND_NAV_BARS = false;
+
private static final float EDGE_SCALE_DOWN_FACTOR_CAROUSEL = 0.03f;
private static final float EDGE_SCALE_DOWN_FACTOR_GRID = 0.00f;
@@ -620,12 +626,11 @@
int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
int taskIconMargin = (int) getResources().getDimension(R.dimen.task_icon_top_margin);
int taskIconHeight = (int) getResources().getDimension(R.dimen.task_thumbnail_icon_size);
- int iconTopMargin = taskIconMargin - taskIconHeight + thumbnailPadding;
LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
switch (orientationHandler.getRotation()) {
case ROTATION_90:
iconParams.gravity = (isRtl ? START : END) | CENTER_VERTICAL;
- iconParams.rightMargin = -thumbnailPadding;
+ iconParams.rightMargin = -taskIconHeight - taskIconMargin / 2;
iconParams.leftMargin = 0;
iconParams.topMargin = snapshotParams.topMargin / 2;
break;
@@ -633,11 +638,11 @@
iconParams.gravity = BOTTOM | CENTER_HORIZONTAL;
iconParams.bottomMargin = -thumbnailPadding;
iconParams.leftMargin = iconParams.rightMargin = 0;
- iconParams.topMargin = iconTopMargin;
+ iconParams.topMargin = taskIconMargin;
break;
case ROTATION_270:
iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
- iconParams.leftMargin = -thumbnailPadding;
+ iconParams.leftMargin = -taskIconHeight - taskIconMargin / 2;
iconParams.rightMargin = 0;
iconParams.topMargin = snapshotParams.topMargin / 2;
break;
@@ -645,7 +650,7 @@
default:
iconParams.gravity = TOP | CENTER_HORIZONTAL;
iconParams.leftMargin = iconParams.rightMargin = 0;
- iconParams.topMargin = iconTopMargin;
+ iconParams.topMargin = taskIconMargin;
break;
}
mIconView.setLayoutParams(iconParams);
@@ -1191,7 +1196,8 @@
int expectedWidth;
int expectedHeight;
- float thumbnailRatio = mTask != null ? mTask.getVisibleThumbnailRatio() : 0f;
+ float thumbnailRatio = mTask != null ? mTask.getVisibleThumbnailRatio(
+ TaskView.CLIP_STATUS_AND_NAV_BARS) : 0f;
if (isRunningTask() || thumbnailRatio == 0f) {
expectedWidth = taskWidth;
expectedHeight = taskHeight + thumbnailPadding;
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 95cdbdd..e263c7a 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -98,6 +98,9 @@
public static final int TYPE_HIDE_BACK_BUTTON = TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
| TYPE_SNACKBAR | TYPE_WIDGET_RESIZE_FRAME | TYPE_LISTENER;
+ // When these types of floating views are open, hide the taskbar hotseat and show the real one.
+ public static final int TYPE_REPLACE_TASKBAR_WITH_HOTSEAT = TYPE_FOLDER | TYPE_ACTION_POPUP;
+
public static final int TYPE_ACCESSIBLE = TYPE_ALL & ~TYPE_DISCOVERY_BOUNCE & ~TYPE_LISTENER
& ~TYPE_ALL_APPS_EDU;
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 2440854..fb7a99f 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -708,10 +708,11 @@
mInsets.top + availableHeightPx);
} else {
// Folders should only appear below the drop target bar and above the hotseat
+ int hotseatTop = isTaskbarPresent ? taskbarSize : hotseatBarSizePx;
return new Rect(mInsets.left + edgeMarginPx,
mInsets.top + dropTargetBarSizePx + edgeMarginPx,
mInsets.left + availableWidthPx - edgeMarginPx,
- mInsets.top + availableHeightPx - hotseatBarSizePx
+ mInsets.top + availableHeightPx - hotseatTop
- workspacePageIndicatorHeight - edgeMarginPx);
}
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index b2112ad..e5b75c1 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -29,6 +29,7 @@
import androidx.annotation.Nullable;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.MultiValueAlpha;
import java.util.function.Consumer;
@@ -37,6 +38,10 @@
*/
public class Hotseat extends CellLayout implements Insettable {
+ private static final int ALPHA_INDEX_STATE = 0;
+ private static final int ALPHA_INDEX_REPLACE_TASKBAR = 1;
+ private static final int NUM_ALPHA_CHANNELS = 2;
+
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHasVerticalHotseat;
private Workspace mWorkspace;
@@ -44,6 +49,8 @@
@Nullable
private Consumer<Boolean> mOnVisibilityAggregatedCallback;
+ private final MultiValueAlpha mMultiValueAlpha;
+
public Hotseat(Context context) {
this(context, null);
}
@@ -54,6 +61,8 @@
public Hotseat(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ mMultiValueAlpha = new MultiValueAlpha(this, NUM_ALPHA_CHANNELS, MultiValueAlpha.Mode.MAX);
+ mMultiValueAlpha.setUpdateVisibility(true);
}
/**
@@ -174,4 +183,12 @@
public View getFirstItemMatch(Workspace.ItemOperator itemOperator) {
return mWorkspace.getFirstMatch(new CellLayout[] { this }, itemOperator);
}
+
+ public MultiValueAlpha.AlphaProperty getStateAlpha() {
+ return mMultiValueAlpha.getProperty(ALPHA_INDEX_STATE);
+ }
+
+ public MultiValueAlpha.AlphaProperty getReplaceTaskbarAlpha() {
+ return mMultiValueAlpha.getProperty(ALPHA_INDEX_REPLACE_TASKBAR);
+ }
}
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 660eeab..d6d2f73 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -55,6 +55,7 @@
import com.android.launcher3.graphics.WorkspaceDragScrim;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.util.DynamicResource;
+import com.android.launcher3.util.MultiValueAlpha;
import com.android.systemui.plugins.ResourceProvider;
/**
@@ -143,8 +144,8 @@
}
float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
- propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha,
- config.getInterpolator(ANIM_HOTSEAT_FADE, fadeInterpolator));
+ propertySetter.setFloat(hotseat.getStateAlpha(), MultiValueAlpha.VALUE,
+ hotseatIconsAlpha, config.getInterpolator(ANIM_HOTSEAT_FADE, fadeInterpolator));
float workspacePageIndicatorAlpha = (elements & WORKSPACE_PAGE_INDICATOR) != 0 ? 1 : 0;
propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
workspacePageIndicatorAlpha, fadeInterpolator);
diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
index 330ec68..e268f56 100644
--- a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.allapps.search;
+import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -37,6 +38,11 @@
}
@Override
+ public void onSliceStatusUpdate(Uri sliceUri) {
+
+ }
+
+ @Override
public boolean isSearchView(int viewType) {
return false;
}
diff --git a/src/com/android/launcher3/allapps/search/LiveSearchManager.java b/src/com/android/launcher3/allapps/search/LiveSearchManager.java
index 76099a6..adb882a 100644
--- a/src/com/android/launcher3/allapps/search/LiveSearchManager.java
+++ b/src/com/android/launcher3/allapps/search/LiveSearchManager.java
@@ -42,6 +42,7 @@
import androidx.slice.SliceViewManager;
import androidx.slice.SliceViewManager.SliceCallback;
+import com.android.launcher3.Alarm;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.statemanager.StateManager.StateListener;
@@ -52,6 +53,7 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.function.Consumer;
/**
* Manages Lifecycle for Live search results
@@ -60,6 +62,7 @@
private static final String TAG = "LiveSearchManager";
+ private static final long SLICE_TIMEOUT_MS = 50;
public static final int SEARCH_APPWIDGET_HOST_ID = 2048;
private final Launcher mLauncher;
@@ -144,16 +147,50 @@
/**
* Adds a new observer for the provided uri and returns a callback to cancel this observer
*/
- public SafeCloseable addObserver(Uri uri, Observer<Slice> listener) {
+ public SafeCloseable addObserver(Uri uri, Observer<Slice> listener,
+ Consumer<Uri> timeoutConsumer) {
SliceLifeCycle slc = mUriSliceMap.get(uri);
if (slc == null) {
slc = new SliceLifeCycle(uri, mLauncher);
mUriSliceMap.put(uri, slc);
}
- slc.addListener(listener);
+ if (slc.mLastValue != null) {
+ listener.onChanged(slc.mLastValue);
+ }
+
+ // Use a listener wrapper to handle error timeout.
+ Observer<Slice> listenerWrapper = new Observer<Slice>() {
+ final Alarm mErrorTimeout = new Alarm();
+ {
+ mErrorTimeout.setOnAlarmListener(alarm -> {
+ alarm.cancelAlarm();
+ timeoutConsumer.accept(uri);
+ });
+ mErrorTimeout.setAlarm(SLICE_TIMEOUT_MS);
+ }
+
+ @Override
+ public void onChanged(Slice slice) {
+ if (slice == null) {
+ return;
+ }
+
+ if (mErrorTimeout.alarmPending()) {
+ mErrorTimeout.cancelAlarm();
+ }
+
+ if (mUriSliceMap.get(uri) != null) {
+ mUriSliceMap.get(uri).mLastValue = slice;
+ }
+
+ listener.onChanged(slice);
+ }
+ };
+
+ slc.addListener(listenerWrapper);
final SliceLifeCycle sliceLifeCycle = slc;
- return () -> sliceLifeCycle.removeListener(listener);
+ return () -> sliceLifeCycle.removeListener(listenerWrapper);
}
static class SearchWidgetHost extends AppWidgetHost {
@@ -184,6 +221,8 @@
private boolean mDestroyed = false;
private boolean mWasListening = false;
+ Slice mLastValue;
+
SliceLifeCycle(Uri uri, Launcher launcher) {
mUri = uri;
mLauncher = launcher;
diff --git a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
index fdacd3d..0864090 100644
--- a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
@@ -16,6 +16,7 @@
package com.android.launcher3.allapps.search;
+import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -40,6 +41,11 @@
public abstract void onBindView(AllAppsGridAdapter.ViewHolder holder, int position);
/**
+ * Called from LiveSearchManager to notify slice status updates.
+ */
+ public abstract void onSliceStatusUpdate(Uri sliceUri);
+
+ /**
* Returns whether or not viewType can be handled by searchProvider
*/
public abstract boolean isSearchView(int viewType);
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index feb528c..ee6ea99 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -40,7 +40,6 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.R;
-import com.android.launcher3.ResourceUtils;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PropertyResetListener;
@@ -177,7 +176,7 @@
Math.round((totalOffsetX + initialSize)),
Math.round((paddingOffsetY + initialSize)));
Rect endRect = new Rect(0, 0, lp.width, lp.height);
- float finalRadius = ResourceUtils.pxFromDp(2, mContext.getResources().getDisplayMetrics());
+ float finalRadius = mFolderBackground.getCornerRadius();
// Create the animators.
AnimatorSet a = new AnimatorSet();
diff --git a/src/com/android/launcher3/util/MultiValueAlpha.java b/src/com/android/launcher3/util/MultiValueAlpha.java
index 5be9529..c79b1f6 100644
--- a/src/com/android/launcher3/util/MultiValueAlpha.java
+++ b/src/com/android/launcher3/util/MultiValueAlpha.java
@@ -42,16 +42,49 @@
}
};
+ /**
+ * Determines how each alpha should factor into the final alpha.
+ */
+ public enum Mode {
+ BLEND(1f) {
+ @Override
+ public float calculateNewAlpha(float currentAlpha, float otherAlpha) {
+ return currentAlpha * otherAlpha;
+ }
+ },
+
+ MAX(0f) {
+ @Override
+ public float calculateNewAlpha(float currentAlpha, float otherAlpha) {
+ return Math.max(currentAlpha, otherAlpha);
+ }
+ };
+
+ Mode(float startAlpha) {
+ mStartAlpha = startAlpha;
+ }
+
+ protected final float mStartAlpha;
+ protected abstract float calculateNewAlpha(float currentAlpha, float otherAlpha);
+ }
+
private final View mView;
private final AlphaProperty[] mMyProperties;
+ private final Mode mMode;
private int mValidMask;
// Whether we should change from INVISIBLE to VISIBLE and vice versa at low alpha values.
private boolean mUpdateVisibility;
public MultiValueAlpha(View view, int size) {
+ this(view, size, Mode.BLEND);
+ }
+
+ public MultiValueAlpha(View view, int size, Mode mode) {
mView = view;
mMyProperties = new AlphaProperty[size];
+ mMode = mode;
+ mView.setAlpha(mMode.mStartAlpha);
mValidMask = 0;
for (int i = 0; i < size; i++) {
@@ -79,9 +112,9 @@
private final int mMyMask;
- private float mValue = 1;
+ private float mValue = mMode.mStartAlpha;
// Factor of all other alpha channels, only valid if mMyMask is present in mValidMask.
- private float mOthers = 1;
+ private float mOthers = mMode.mStartAlpha;
AlphaProperty(int myMask) {
mMyMask = myMask;
@@ -94,10 +127,10 @@
if ((mValidMask & mMyMask) == 0) {
// Our cache value is not correct, recompute it.
- mOthers = 1;
+ mOthers = mMode.mStartAlpha;
for (AlphaProperty prop : mMyProperties) {
if (prop != this) {
- mOthers *= prop.mValue;
+ mOthers = mMode.calculateNewAlpha(mOthers, prop.mValue);
}
}
}
@@ -107,7 +140,7 @@
mValidMask = mMyMask;
mValue = value;
- mView.setAlpha(mOthers * mValue);
+ mView.setAlpha(mMode.calculateNewAlpha(mOthers, mValue));
if (mUpdateVisibility) {
AlphaUpdateListener.updateVisibility(mView);
}
diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java
index a6c7c03..8f4381b 100644
--- a/tests/src/com/android/launcher3/ui/WorkTabTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java
@@ -18,7 +18,6 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
-import static com.android.launcher3.tapl.LauncherInstrumentation.LONG_WAIT_TIME_MS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -37,6 +36,7 @@
import com.android.launcher3.allapps.AllAppsPagedView;
import com.android.launcher3.allapps.WorkModeSwitch;
import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.views.WorkEduView;
@@ -147,7 +147,7 @@
return true;
}
return false;
- }, LONG_WAIT_TIME_MS);
+ }, LauncherInstrumentation.WAIT_TIME_MS);
executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
WorkEduView workEduView = getEduView();
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index f279a82..a3f37d2 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -155,8 +155,7 @@
private static final String OVERVIEW_RES_ID = "overview_panel";
private static final String WIDGETS_RES_ID = "primary_widgets_list_view";
private static final String CONTEXT_MENU_RES_ID = "deep_shortcuts_container";
- public static final int WAIT_TIME_MS = 10000;
- public static final int LONG_WAIT_TIME_MS = 60000;
+ public static final int WAIT_TIME_MS = 60000;
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
private static final String ANDROID_PACKAGE = "android";
@@ -656,7 +655,7 @@
try {
final AccessibilityEvent event =
mInstrumentation.getUiAutomation().executeAndWaitForEvent(
- command, eventFilter, LONG_WAIT_TIME_MS);
+ command, eventFilter, WAIT_TIME_MS);
assertNotNull("executeAndWaitForEvent returned null (this can't happen)", event);
final Parcelable parcelableData = event.getParcelableData();
event.recycle();