Merge "Fix wrong widget appearing in widget picker for tablet" into tm-qpr-dev
diff --git a/OWNERS b/OWNERS
index 560b562..962d63a 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,31 +4,36 @@
# People who can approve changes for submission
#
-alexchau@google.com
-andraskloczl@google.com
-patmanning@google.com
adamcohen@google.com
-hyunyoungs@google.com
-mrcasey@google.com
-sunnygoyal@google.com
+alexchau@google.com
+andonian@google.com
awickham@google.com
-twickham@google.com
-winsonc@google.com
-zakcohen@google.com
-santie@google.com
-vadimt@google.com
-jonmiranda@google.com
-pinyaoting@google.com
-gwasserman@google.com
-jamesoleary@google.com
-joshtrask@google.com
-mrenouf@google.com
-mkephart@google.com
-hwwang@google.com
-tracyzhou@google.com
-peanutbutter@google.com
-xuqiu@google.com
+brdayauon@google.com
brianji@google.com
+captaincole@google.com
+charlander@google.com
+fbaron@google.com
+ganjam@google.com
+hwwang@google.com
+hyunyoungs@google.com
+jagrutdesai@google.com
+jeremysim@google.com
+jiuyu@google.com
+jonmiranda@google.com
+kylim@google.com
+patmanning@google.com
+peanutbutter@google.com
+pinyaoting@google.com
+randypfohl@google.com
+saumyaprakash@google.com
+sihua@google.com
+sunnygoyal@google.com
+tracyzhou@google.com
+twickham@google.com
+vadimt@google.com
+victortulias@google.com
+winsonc@google.com
+xuqiu@google.com
per-file FeatureFlags.java, globs = set noparent
-per-file FeatureFlags.java = sunnygoyal@google.com, winsonc@google.com, zakcohen@google.com, mrcasey@google.com, adamcohen@google.com, hyunyoungs@google.com
+per-file FeatureFlags.java = sunnygoyal@google.com, winsonc@google.com, adamcohen@google.com, hyunyoungs@google.com
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index bd11c1e..1642fd4 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -17,11 +17,14 @@
file, they need to be loaded at runtime. -->
<com.android.quickstep.views.TaskView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:defaultFocusHighlightEnabled="false"
- android:focusable="true">
+ android:focusable="true"
+ launcher:borderColor="?androidprv:attr/colorAccentSecondaryVariant">
<com.android.quickstep.views.TaskThumbnailView
android:id="@+id/snapshot"
diff --git a/quickstep/res/layout/task_grouped.xml b/quickstep/res/layout/task_grouped.xml
index ec03c69..a8d5b50 100644
--- a/quickstep/res/layout/task_grouped.xml
+++ b/quickstep/res/layout/task_grouped.xml
@@ -22,11 +22,14 @@
<com.android.quickstep.views.GroupedTaskView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:defaultFocusHighlightEnabled="false"
- android:focusable="true">
+ android:focusable="true"
+ launcher:borderColor="?androidprv:attr/colorAccentSecondaryVariant">
<com.android.quickstep.views.TaskThumbnailView
android:id="@+id/snapshot"
diff --git a/quickstep/res/values/attrs.xml b/quickstep/res/values/attrs.xml
index 336fb57..f1d4dab 100644
--- a/quickstep/res/values/attrs.xml
+++ b/quickstep/res/values/attrs.xml
@@ -19,4 +19,13 @@
<attr name="android:textSize"/>
<attr name="android:fontFamily"/>
</declare-styleable>
+
+ <!--
+ TaskView specific attributes. These attributes are used to customize a TaskView view in
+ XML files.
+ -->
+ <declare-styleable name="TaskView">
+ <!-- Border color for a keyboard quick switch task views -->
+ <attr name="borderColor" format="color" />
+ </declare-styleable>
</resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 3846a9c..fb04cc0 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -328,4 +328,7 @@
<!-- Note: keep this value in sync with the WindowManager/Shell dimens.xml -->
<!-- starting_surface_exit_animation_window_shift_length -->
<dimen name="starting_surface_exit_animation_window_shift_length">20dp</dimen>
+
+ <!-- Keyboard Quick Switch -->
+ <dimen name="keyboard_quick_switch_border_width">4dp</dimen>
</resources>
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 335482c..0b6e5d3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -29,6 +29,7 @@
import android.os.RemoteException;
import android.util.Log;
import android.view.TaskTransitionSpec;
+import android.view.View;
import android.view.WindowManagerGlobal;
import androidx.annotation.NonNull;
@@ -49,6 +50,7 @@
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.quickstep.RecentsAnimationCallbacks;
+import com.android.quickstep.util.GroupTask;
import com.android.quickstep.views.RecentsView;
import java.io.PrintWriter;
@@ -380,6 +382,17 @@
}
@Override
+ public RecentsView getRecentsView() {
+ return mLauncher.getOverviewPanel();
+ }
+
+ @Override
+ public void launchSplitTasks(View taskView, GroupTask groupTask) {
+ super.launchSplitTasks(taskView, groupTask);
+ mLauncher.launchSplitTasks(taskView, groupTask);
+ }
+
+ @Override
public void dumpLogs(String prefix, PrintWriter pw) {
super.dumpLogs(prefix, pw);
@@ -399,9 +412,4 @@
mTaskbarLauncherStateController.dumpLogs(prefix + "\t", pw);
}
-
- @Override
- public RecentsView getRecentsView() {
- return mLauncher.getOverviewPanel();
- }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 74e7375..0f25ba1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -36,6 +38,7 @@
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
+import com.android.systemui.shared.system.QuickStepContract;
import java.io.PrintWriter;
@@ -78,6 +81,10 @@
private float mStartProgressForNextRevealAnim;
private boolean mWasLastRevealAnimReversed;
+ // States that affect whether region sampling is enabled or not
+ private boolean mIsStashed;
+ private boolean mTaskbarHidden;
+
public StashedHandleViewController(TaskbarActivityContext activity,
StashedHandleView stashedHandleView) {
mActivity = activity;
@@ -218,7 +225,8 @@
/** Called when taskbar is stashed or unstashed. */
public void onIsStashedChanged(boolean isStashed) {
- mRegionSamplingHelper.setWindowVisible(isStashed);
+ mIsStashed = isStashed;
+ updateRegionSamplingWindowVisibility();
if (isStashed) {
mStashedHandleView.updateSampledRegion(mStashedHandleBounds);
mRegionSamplingHelper.start(mStashedHandleView.getSampledRegion());
@@ -247,6 +255,15 @@
homeDisabled ? 0 : 1);
}
+ public void updateStateForSysuiFlags(int systemUiStateFlags) {
+ mTaskbarHidden = (systemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0;
+ updateRegionSamplingWindowVisibility();
+ }
+
+ private void updateRegionSamplingWindowVisibility() {
+ mRegionSamplingHelper.setWindowVisible(mIsStashed && !mTaskbarHidden);
+ }
+
public boolean isStashedHandleVisible() {
return mStashedHandleView.getVisibility() == View.VISIBLE;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index c6d8fce..c0c14a3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -247,6 +247,12 @@
// Initialize controllers after all are constructed.
mControllers.init(sharedState);
updateSysuiStateFlags(sharedState.sysuiStateFlags, true /* fromInit */);
+ disableNavBarElements(sharedState.disableNavBarDisplayId, sharedState.disableNavBarState1,
+ sharedState.disableNavBarState2, false /* animate */);
+ onSystemBarAttributesChanged(sharedState.systemBarAttrsDisplayId,
+ sharedState.systemBarAttrsBehavior);
+ onNavButtonsDarkIntensityChanged(sharedState.navButtonsDarkIntensity);
+
if (!mAddedWindow) {
mWindowManager.addView(mDragLayer, mWindowLayoutParams);
@@ -564,6 +570,7 @@
|| isNavBarKidsModeActive());
mControllers.stashedHandleViewController.setIsHomeButtonDisabled(
mControllers.navbarButtonsViewController.isHomeDisabled());
+ mControllers.stashedHandleViewController.updateStateForSysuiFlags(systemUiStateFlags);
mControllers.taskbarKeyguardController.updateStateForSysuiFlags(systemUiStateFlags);
mControllers.taskbarStashController.updateStateForSysuiFlags(
systemUiStateFlags, fromInit || !isUserSetupComplete());
@@ -1061,6 +1068,12 @@
mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
}
+ void notifyUpdateLayoutParams() {
+ if (mDragLayer.isAttachedToWindow()) {
+ mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ }
+ }
+
public void showPopupMenuForIcon(BubbleTextView btv) {
setTaskbarWindowFullscreen(true);
btv.post(() -> mControllers.taskbarPopupController.showForIcon(btv));
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 9f24565..571d443 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -18,16 +18,21 @@
import android.graphics.Insets
import android.graphics.Region
import android.view.InsetsFrameProvider
+import android.view.InsetsFrameProvider.SOURCE_DISPLAY
+import android.view.InsetsFrameProvider.SOURCE_FRAME
import android.view.InsetsState
import android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES
import android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT
import android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR
+import android.view.InsetsState.ITYPE_LEFT_GESTURES
+import android.view.InsetsState.ITYPE_RIGHT_GESTURES
import android.view.ViewTreeObserver
import android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME
import android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION
import android.view.WindowManager
import android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD
import android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION
+import com.android.internal.policy.GestureNavigationSettingsObserver
import com.android.launcher3.AbstractFloatingView
import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_OVERLAY_PROXY
import com.android.launcher3.DeviceProfile
@@ -45,6 +50,9 @@
private val deviceProfileChangeListener = { _: DeviceProfile ->
onTaskbarWindowHeightOrInsetsChanged()
}
+ private val gestureNavSettingsObserver =
+ GestureNavigationSettingsObserver(context.mainThreadHandler, context,
+ this::onTaskbarWindowHeightOrInsetsChanged)
// Initialized in init.
private lateinit var controllers: TaskbarControllers
@@ -59,7 +67,16 @@
intArrayOf(
ITYPE_EXTRA_NAVIGATION_BAR,
ITYPE_BOTTOM_TAPPABLE_ELEMENT,
- ITYPE_BOTTOM_MANDATORY_GESTURES
+ ITYPE_BOTTOM_MANDATORY_GESTURES,
+ ITYPE_LEFT_GESTURES,
+ ITYPE_RIGHT_GESTURES,
+ ),
+ intArrayOf(
+ SOURCE_FRAME,
+ SOURCE_FRAME,
+ SOURCE_FRAME,
+ SOURCE_DISPLAY,
+ SOURCE_DISPLAY
)
)
@@ -67,10 +84,12 @@
windowLayoutParams.insetsRoundedCornerFrame = true
context.addOnDeviceProfileChangeListener(deviceProfileChangeListener)
+ gestureNavSettingsObserver.registerForCurrentUser()
}
fun onDestroy() {
context.removeOnDeviceProfileChangeListener(deviceProfileChangeListener)
+ gestureNavSettingsObserver.unregister()
}
fun onTaskbarWindowHeightOrInsetsChanged() {
@@ -91,6 +110,22 @@
provider.insetsSize = getInsetsByNavMode(contentHeight)
} else if (provider.type == ITYPE_BOTTOM_TAPPABLE_ELEMENT) {
provider.insetsSize = getInsetsByNavMode(tappableHeight)
+ } else if (provider.type == ITYPE_LEFT_GESTURES) {
+ provider.insetsSize =
+ Insets.of(
+ gestureNavSettingsObserver.getLeftSensitivity(context.resources),
+ 0,
+ 0,
+ 0
+ )
+ } else if (provider.type == ITYPE_RIGHT_GESTURES) {
+ provider.insetsSize =
+ Insets.of(
+ 0,
+ 0,
+ gestureNavSettingsObserver.getRightSensitivity(context.resources),
+ 0
+ )
}
}
@@ -116,6 +151,7 @@
provider.insetsSizeOverrides = insetsSizeOverride
}
}
+ context.notifyUpdateLayoutParams()
}
/**
@@ -140,10 +176,12 @@
* @param params The window layout params.
* @param providesInsetsTypes The inset types we would like this layout params to provide.
*/
- fun setProvidesInsetsTypes(params: WindowManager.LayoutParams, providesInsetsTypes: IntArray) {
+ fun setProvidesInsetsTypes(params: WindowManager.LayoutParams, providesInsetsTypes: IntArray,
+ providesInsetsSources: IntArray) {
params.providedInsets = arrayOfNulls<InsetsFrameProvider>(providesInsetsTypes.size)
for (i in providesInsetsTypes.indices) {
- params.providedInsets[i] = InsetsFrameProvider(providesInsetsTypes[i])
+ params.providedInsets[i] = InsetsFrameProvider(providesInsetsTypes[i],
+ providesInsetsSources[i], null, null)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index a58906f..4110822 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -362,18 +362,24 @@
}
public void disableNavBarElements(int displayId, int state1, int state2, boolean animate) {
+ mSharedState.disableNavBarDisplayId = displayId;
+ mSharedState.disableNavBarState1 = state1;
+ mSharedState.disableNavBarState2 = state2;
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.disableNavBarElements(displayId, state1, state2, animate);
}
}
public void onSystemBarAttributesChanged(int displayId, int behavior) {
+ mSharedState.systemBarAttrsDisplayId = displayId;
+ mSharedState.systemBarAttrsBehavior = behavior;
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.onSystemBarAttributesChanged(displayId, behavior);
}
}
public void onNavButtonsDarkIntensityChanged(float darkIntensity) {
+ mSharedState.navButtonsDarkIntensity = darkIntensity;
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.onNavButtonsDarkIntensityChanged(darkIntensity);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
index 87b3789..026eff7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
@@ -20,8 +20,21 @@
*/
public class TaskbarSharedState {
+ // TaskbarManager#onSystemUiFlagsChanged
public int sysuiStateFlags;
+ // TaskbarManager#disableNavBarElements()
+ public int disableNavBarDisplayId;
+ public int disableNavBarState1;
+ public int disableNavBarState2;
+
+ // TaskbarManager#onSystemBarAttributesChanged()
+ public int systemBarAttrsDisplayId;
+ public int systemBarAttrsBehavior;
+
+ // TaskbarManager#onNavButtonsDarkIntensityChanged()
+ public float navButtonsDarkIntensity;
+
public boolean setupUIVisible = false;
public boolean allAppsVisible = false;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index bfdf156..a388388 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -29,6 +29,7 @@
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.quickstep.util.GroupTask;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
@@ -228,4 +229,11 @@
}
);
}
+
+ /**
+ * Launches the focused task in splitscreen.
+ *
+ * No-op if the view is not yet open.
+ */
+ public void launchSplitTasks(View taskview, GroupTask groupTask) { }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
index d91b650..ec64128 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -27,17 +27,45 @@
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
/** Root drag layer for the Taskbar overlay window. */
public class TaskbarOverlayDragLayer extends
BaseDragLayer<TaskbarOverlayContext> implements
ViewTreeObserver.OnComputeInternalInsetsListener {
+ private final List<OnClickListener> mOnClickListeners = new CopyOnWriteArrayList<>();
+ private final TouchController mClickListenerTouchController = new TouchController() {
+ @Override
+ public boolean onControllerTouchEvent(MotionEvent ev) {
+ if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
+ for (OnClickListener listener : mOnClickListeners) {
+ listener.onClick(TaskbarOverlayDragLayer.this);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ for (int i = 0; i < getChildCount(); i++) {
+ if (isEventOverView(getChildAt(i), ev)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ };
+
TaskbarOverlayDragLayer(Context context) {
super(context, null, 1);
setClipChildren(false);
@@ -58,7 +86,10 @@
@Override
public void recreateControllers() {
- mControllers = new TouchController[]{mActivity.getDragController()};
+ mControllers = mOnClickListeners.isEmpty()
+ ? new TouchController[]{mActivity.getDragController()}
+ : new TouchController[] {
+ mActivity.getDragController(), mClickListenerTouchController};
}
@Override
@@ -99,6 +130,51 @@
}
/**
+ * Adds the given callback to clicks to this drag layer.
+ * <p>
+ * Clicks are only accepted on this drag layer if they fall within this drag layer's bounds and
+ * outside the bounds of all child views.
+ * <p>
+ * If the click falls within the bounds of a child view, then this callback does not run and
+ * that child can optionally handle it.
+ */
+ private void addOnClickListener(@NonNull OnClickListener listener) {
+ boolean wasEmpty = mOnClickListeners.isEmpty();
+ mOnClickListeners.add(listener);
+ if (wasEmpty) {
+ recreateControllers();
+ }
+ }
+
+ /**
+ * Removes the given on click callback.
+ * <p>
+ * No-op if the callback was never added.
+ */
+ private void removeOnClickListener(@NonNull OnClickListener listener) {
+ boolean wasEmpty = mOnClickListeners.isEmpty();
+ mOnClickListeners.remove(listener);
+ if (!wasEmpty && mOnClickListeners.isEmpty()) {
+ recreateControllers();
+ }
+ }
+
+ /**
+ * Queues the given callback on the next click on this drag layer.
+ * <p>
+ * Once run, this callback is immediately removed.
+ */
+ public void runOnClickOnce(@NonNull OnClickListener listener) {
+ addOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ listener.onClick(v);
+ removeOnClickListener(this);
+ }
+ });
+ }
+
+ /**
* Taskbar automatically stashes when opening all apps, but we don't report the insets as
* changing to avoid moving the underlying app. But internally, the apps view should still
* layout according to the stashed insets rather than the unstashed insets. So this method
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index fd986e6..80ce369 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -50,6 +50,7 @@
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO;
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
@@ -143,6 +144,7 @@
import com.android.launcher3.util.PendingRequestArgs;
import com.android.launcher3.util.PendingSplitSelectInfo;
import com.android.launcher3.util.RunnableList;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
import com.android.launcher3.util.TouchController;
@@ -152,6 +154,7 @@
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.TouchInteractionService.TISBinder;
+import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.LauncherUnfoldAnimationController;
import com.android.quickstep.util.ProxyScreenStatusProvider;
import com.android.quickstep.util.QuickstepOnboardingPrefs;
@@ -1206,6 +1209,32 @@
getDeviceProfile().toSmallString());
}
+ /**
+ * Launches the given {@link GroupTask} in splitscreen.
+ *
+ * If the second split task is missing, launches the first task normally.
+ */
+ public void launchSplitTasks(View taskView, GroupTask groupTask) {
+ if (groupTask.task2 == null) {
+ UI_HELPER_EXECUTOR.execute(() ->
+ ActivityManagerWrapper.getInstance().startActivityFromRecents(
+ groupTask.task1.key,
+ getActivityLaunchOptions(taskView, null).options));
+ return;
+ }
+ mSplitSelectStateController.launchTasks(
+ groupTask.task1.key.id,
+ groupTask.task2.key.id,
+ SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT,
+ /* callback= */ success -> {},
+ /* freezeTaskList= */ true,
+ groupTask.mSplitBounds == null
+ ? DEFAULT_SPLIT_RATIO
+ : groupTask.mSplitBounds.appsStackedVertically
+ ? groupTask.mSplitBounds.topTaskPercent
+ : groupTask.mSplitBounds.leftTaskPercent);
+ }
+
private static final class LauncherTaskViewController extends
TaskViewTouchController<Launcher> {
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 5a09e02..b5240fd 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -24,8 +24,10 @@
import android.os.Build;
import android.os.SystemClock;
import android.os.Trace;
+import android.view.View;
import androidx.annotation.BinderThread;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -48,7 +50,7 @@
public class OverviewCommandHelper {
public static final int TYPE_SHOW = 1;
- public static final int TYPE_SHOW_NEXT_FOCUS = 2;
+ public static final int TYPE_KEYBOARD_INPUT = 2;
public static final int TYPE_HIDE = 3;
public static final int TYPE_TOGGLE = 4;
public static final int TYPE_HOME = 5;
@@ -66,6 +68,13 @@
private final TaskAnimationManager mTaskAnimationManager;
private final ArrayList<CommandInfo> mPendingCommands = new ArrayList<>();
+ /**
+ * Index of the TaskView that should be focused when launching Overview. Persisted so that we
+ * do not lose the focus across multiple calls of
+ * {@link OverviewCommandHelper#executeCommand(CommandInfo)} for the same command
+ */
+ private int mTaskFocusIndexOverride = -1;
+
public OverviewCommandHelper(TouchInteractionService service,
OverviewComponentObserver observer,
TaskAnimationManager taskAnimationManager) {
@@ -179,6 +188,7 @@
// already visible
return true;
case TYPE_HIDE: {
+ mTaskFocusIndexOverride = -1;
int currentPage = recents.getNextPage();
TaskView tv = (currentPage >= 0 && currentPage < recents.getTaskViewCount())
? (TaskView) recents.getPageAt(currentPage)
@@ -194,15 +204,9 @@
}
final Runnable completeCallback = () -> {
- if (cmd.type == TYPE_SHOW_NEXT_FOCUS) {
- RecentsView rv = activityInterface.getVisibleRecentsView();
- // When the overview is launched via alt tab (cmd type is TYPE_SHOW_NEXT_FOCUS),
- // the touch mode somehow is not change to false by the Android framework.
- // The subsequent tab to go through tasks in overview can only be dispatched to
- // focuses views, while focus can only be requested in
- // {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
- // here we launch overview from home.
- rv.getViewRootImpl().touchModeChanged(false);
+ RecentsView rv = activityInterface.getVisibleRecentsView();
+ if (rv != null && (cmd.type == TYPE_KEYBOARD_INPUT || cmd.type == TYPE_HIDE)) {
+ updateRecentsViewFocus(rv);
}
scheduleNextTask(cmd);
};
@@ -280,40 +284,55 @@
cmd.removeListener(handler);
Trace.endAsyncSection(TRANSITION_NAME, 0);
- if (cmd.type == TYPE_SHOW_NEXT_FOCUS) {
- RecentsView rv =
- mOverviewComponentObserver.getActivityInterface().getVisibleRecentsView();
- if (rv != null) {
- // When the overview is launched via alt tab (cmd type is TYPE_SHOW_NEXT_FOCUS),
- // the touch mode somehow is not change to false by the Android framework.
- // The subsequent tab to go through tasks in overview can only be dispatched to
- // focuses views, while focus can only be requested in
- // {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
- // here we launch overview with live tile.
- rv.getViewRootImpl().touchModeChanged(false);
- // Ensure that recents view has focus so that it receives the followup key inputs
- TaskView taskView = rv.getNextTaskView();
- if (taskView == null) {
- taskView = rv.getTaskViewAt(0);
- if (taskView != null) {
- taskView.requestFocus();
- } else {
- rv.requestFocus();
- }
- } else {
- taskView.requestFocus();
- }
- }
+ RecentsView rv =
+ mOverviewComponentObserver.getActivityInterface().getVisibleRecentsView();
+ if (rv != null && (cmd.type == TYPE_KEYBOARD_INPUT || cmd.type == TYPE_HIDE)) {
+ updateRecentsViewFocus(rv);
}
scheduleNextTask(cmd);
}
+ private void updateRecentsViewFocus(@NonNull RecentsView rv) {
+ // When the overview is launched via alt tab (cmd type is TYPE_KEYBOARD_INPUT),
+ // the touch mode somehow is not change to false by the Android framework.
+ // The subsequent tab to go through tasks in overview can only be dispatched to
+ // focuses views, while focus can only be requested in
+ // {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
+ // here we launch overview with live tile.
+ rv.getViewRootImpl().touchModeChanged(false);
+ // Ensure that recents view has focus so that it receives the followup key inputs
+ TaskView taskView = rv.getTaskViewAt(mTaskFocusIndexOverride);
+ if (taskView != null) {
+ requestFocus(taskView);
+ return;
+ }
+ taskView = rv.getNextTaskView();
+ if (taskView != null) {
+ requestFocus(taskView);
+ return;
+ }
+ taskView = rv.getTaskViewAt(0);
+ if (taskView != null) {
+ requestFocus(taskView);
+ return;
+ }
+ requestFocus(rv);
+ }
+
+ private void requestFocus(@NonNull View view) {
+ view.post(() -> {
+ view.requestFocus();
+ view.requestAccessibilityFocus();
+ });
+ }
+
public void dump(PrintWriter pw) {
pw.println("OverviewCommandHelper:");
pw.println(" mPendingCommands=" + mPendingCommands.size());
if (!mPendingCommands.isEmpty()) {
pw.println(" pendingCommandType=" + mPendingCommands.get(0).type);
}
+ pw.println(" mTaskFocusIndexOverride=" + mTaskFocusIndexOverride);
}
private static class CommandInfo {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 287b468..1b8a93c 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -205,7 +205,7 @@
public void onOverviewShown(boolean triggeredFromAltTab) {
if (triggeredFromAltTab) {
TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_SHOW_NEXT_FOCUS);
+ mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_KEYBOARD_INPUT);
} else {
mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_SHOW);
}
diff --git a/quickstep/src/com/android/quickstep/util/BorderAnimator.java b/quickstep/src/com/android/quickstep/util/BorderAnimator.java
new file mode 100644
index 0000000..532edb2
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/BorderAnimator.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import android.animation.Animator;
+import android.annotation.ColorInt;
+import android.annotation.Nullable;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.view.animation.Interpolator;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Px;
+
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedFloat;
+import com.android.launcher3.anim.AnimatorListeners;
+import com.android.launcher3.anim.Interpolators;
+
+/**
+ * Utility class for drawing a rounded-rect border around a view.
+ * <p>
+ * To use this class:
+ * 1. Create an instance in the target view.
+ * 2. Override the target view's {@link android.view.View#draw(Canvas)} method and call
+ * {@link BorderAnimator#drawBorder(Canvas)} after {@code super.draw(canvas)}.
+ * 3. Call {@link BorderAnimator#buildAnimator(boolean)} and start the animation where appropriate.
+ */
+public final class BorderAnimator {
+
+ public static final int DEFAULT_BORDER_COLOR = 0xffffffff;
+
+ private static final long DEFAULT_APPEARANCE_ANIMATION_DURATION_MS = 300;
+ private static final long DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS = 133;
+ private static final Interpolator DEFAULT_INTERPOLATOR = Interpolators.EMPHASIZED_DECELERATE;
+
+ @NonNull private final AnimatedFloat mBorderAnimationProgress = new AnimatedFloat(
+ this::updateOutline);
+ @NonNull private final Rect mBorderBounds = new Rect();
+ @NonNull private final BorderBoundsBuilder mBorderBoundsBuilder;
+ @Px private final int mBorderWidthPx;
+ @Px private final int mBorderRadiusPx;
+ @NonNull private final Runnable mInvalidateViewCallback;
+ private final long mAppearanceDurationMs;
+ private final long mDisappearanceDurationMs;
+ @NonNull private final Interpolator mInterpolator;
+ @NonNull private final Paint mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ private int mAlignmentAdjustment;
+
+ @Nullable private Animator mRunningBorderAnimation;
+
+ public BorderAnimator(
+ @NonNull BorderBoundsBuilder borderBoundsBuilder,
+ int borderWidthPx,
+ int borderRadiusPx,
+ @ColorInt int borderColor,
+ @NonNull Runnable invalidateViewCallback) {
+ this(borderBoundsBuilder,
+ borderWidthPx,
+ borderRadiusPx,
+ borderColor,
+ invalidateViewCallback,
+ DEFAULT_APPEARANCE_ANIMATION_DURATION_MS,
+ DEFAULT_DISAPPEARANCE_ANIMATION_DURATION_MS,
+ DEFAULT_INTERPOLATOR);
+ }
+
+ public BorderAnimator(
+ @NonNull BorderBoundsBuilder borderBoundsBuilder,
+ int borderWidthPx,
+ int borderRadiusPx,
+ @ColorInt int borderColor,
+ @NonNull Runnable invalidateViewCallback,
+ long appearanceDurationMs,
+ long disappearanceDurationMs,
+ @NonNull Interpolator interpolator) {
+ mBorderBoundsBuilder = borderBoundsBuilder;
+ mBorderWidthPx = borderWidthPx;
+ mBorderRadiusPx = borderRadiusPx;
+ mInvalidateViewCallback = invalidateViewCallback;
+ mAppearanceDurationMs = appearanceDurationMs;
+ mDisappearanceDurationMs = disappearanceDurationMs;
+ mInterpolator = interpolator;
+
+ mBorderPaint.setColor(borderColor);
+ mBorderPaint.setStyle(Paint.Style.STROKE);
+ mBorderPaint.setAlpha(0);
+ }
+
+ private void updateOutline() {
+ float interpolatedProgress = mInterpolator.getInterpolation(
+ mBorderAnimationProgress.value);
+ mAlignmentAdjustment = (int) Utilities.mapBoundToRange(
+ mBorderAnimationProgress.value,
+ /* lowerBound= */ 0f,
+ /* upperBound= */ 1f,
+ /* toMin= */ 0f,
+ /* toMax= */ (float) (mBorderWidthPx / 2f),
+ mInterpolator);
+
+ mBorderPaint.setAlpha(Math.round(255 * interpolatedProgress));
+ mBorderPaint.setStrokeWidth(Math.round(mBorderWidthPx * interpolatedProgress));
+ mInvalidateViewCallback.run();
+ }
+
+ /**
+ * Draws the border on the given canvas.
+ * <p>
+ * Call this method in the target view's {@link android.view.View#draw(Canvas)} method after
+ * calling super.
+ */
+ public void drawBorder(Canvas canvas) {
+ canvas.drawRoundRect(
+ /* left= */ mBorderBounds.left + mAlignmentAdjustment,
+ /* top= */ mBorderBounds.top + mAlignmentAdjustment,
+ /* right= */ mBorderBounds.right - mAlignmentAdjustment,
+ /* bottom= */ mBorderBounds.bottom - mAlignmentAdjustment,
+ /* rx= */ mBorderRadiusPx - mAlignmentAdjustment,
+ /* ry= */ mBorderRadiusPx - mAlignmentAdjustment,
+ /* paint= */ mBorderPaint);
+ }
+
+ /**
+ * Builds the border appearance/disappearance animation.
+ */
+ public Animator buildAnimator(boolean isAppearing) {
+ mBorderBoundsBuilder.updateBorderBounds(mBorderBounds);
+ mRunningBorderAnimation = mBorderAnimationProgress.animateToValue(isAppearing ? 1f : 0f);
+ mRunningBorderAnimation.setDuration(
+ isAppearing ? mAppearanceDurationMs : mDisappearanceDurationMs);
+
+ mRunningBorderAnimation.addListener(
+ AnimatorListeners.forEndCallback(() -> mRunningBorderAnimation = null));
+
+ return mRunningBorderAnimation;
+ }
+
+ /**
+ * Callback to update the border bounds when building this animation.
+ */
+ public interface BorderBoundsBuilder {
+
+ /**
+ * Sets the given rect to the most up-to-date bounds.
+ */
+ void updateBorderBounds(Rect rect);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 5cf79ea..e9498fd 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -5,6 +5,7 @@
import android.content.Context;
import android.graphics.PointF;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@@ -72,6 +73,23 @@
}
@Override
+ protected void updateBorderBounds(Rect bounds) {
+ if (mSplitBoundsConfig == null) {
+ super.updateBorderBounds(bounds);
+ return;
+ }
+ bounds.set(
+ Math.min(mSnapshotView.getLeft() + Math.round(mSnapshotView.getTranslationX()),
+ mSnapshotView2.getLeft() + Math.round(mSnapshotView2.getTranslationX())),
+ Math.min(mSnapshotView.getTop() + Math.round(mSnapshotView.getTranslationY()),
+ mSnapshotView2.getTop() + Math.round(mSnapshotView2.getTranslationY())),
+ Math.max(mSnapshotView.getRight() + Math.round(mSnapshotView.getTranslationX()),
+ mSnapshotView2.getRight() + Math.round(mSnapshotView2.getTranslationX())),
+ Math.max(mSnapshotView.getBottom() + Math.round(mSnapshotView.getTranslationY()),
+ mSnapshotView2.getBottom() + Math.round(mSnapshotView2.getTranslationY())));
+ }
+
+ @Override
protected void onFinishInflate() {
super.onFinishInflate();
mSnapshotView2 = findViewById(R.id.bottomright_snapshot);
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index d3c7778..0e2f020 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -31,6 +31,7 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition;
+import static com.android.quickstep.util.BorderAnimator.DEFAULT_BORDER_COLOR;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -42,6 +43,7 @@
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -94,6 +96,7 @@
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.TaskViewUtils;
+import com.android.quickstep.util.BorderAnimator;
import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitSelectStateController;
@@ -405,6 +408,8 @@
private boolean mIsClickableAsLiveTile = true;
+ @Nullable private final BorderAnimator mBorderAnimator;
+
public TaskView(Context context) {
this(context, null);
}
@@ -414,12 +419,46 @@
}
public TaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public TaskView(
+ Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
mActivity = StatefulActivity.fromContext(context);
setOnClickListener(this::onClick);
mCurrentFullscreenParams = new FullscreenDrawParams(context);
mDigitalWellBeingToast = new DigitalWellBeingToast(mActivity, this);
+
+ setWillNotDraw(!FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get());
+
+ mBorderAnimator = !FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get()
+ ? null
+ : new BorderAnimator(
+ /* borderBoundsBuilder= */ this::updateBorderBounds,
+ /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
+ R.dimen.keyboard_quick_switch_border_width),
+ /* borderRadiusPx= */ (int) mCurrentFullscreenParams.mCornerRadius,
+ /* borderColor= */ attrs == null
+ ? DEFAULT_BORDER_COLOR
+ : context.getTheme()
+ .obtainStyledAttributes(
+ attrs,
+ R.styleable.TaskView,
+ defStyleAttr,
+ defStyleRes)
+ .getColor(
+ R.styleable.TaskView_borderColor,
+ DEFAULT_BORDER_COLOR),
+ /* invalidateViewCallback= */ TaskView.this::invalidate);
+ }
+
+ protected void updateBorderBounds(Rect bounds) {
+ bounds.set(mSnapshotView.getLeft() + Math.round(mSnapshotView.getTranslationX()),
+ mSnapshotView.getTop() + Math.round(mSnapshotView.getTranslationY()),
+ mSnapshotView.getRight() + Math.round(mSnapshotView.getTranslationX()),
+ mSnapshotView.getBottom() + Math.round(mSnapshotView.getTranslationY()));
}
public void setTaskViewId(int id) {
@@ -463,6 +502,22 @@
mIconTouchDelegate = new TransformingTouchDelegate(mIconView);
}
+ @Override
+ protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ if (mBorderAnimator != null) {
+ mBorderAnimator.buildAnimator(gainFocus).start();
+ }
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+ if (mBorderAnimator != null) {
+ mBorderAnimator.drawBorder(canvas);
+ }
+ }
+
/**
* Whether the taskview should take the touch event from parent. Events passed to children
* that might require special handling.
diff --git a/res/drawable/bg_widgets_content.xml b/res/drawable/bg_widgets_content.xml
new file mode 100644
index 0000000..8060430
--- /dev/null
+++ b/res/drawable/bg_widgets_content.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <!--
+ L -> large radius
+ s -> small radius
+ 0 -> no radiuls
+ -->
+
+ <!-- MIDDLE : 0 0 s s -->
+ <item android:state_middle="true">
+ <shape android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="0dp"
+ android:topRightRadius="0dp"
+ android:bottomLeftRadius="@dimen/widget_list_content_corner_radius"
+ android:bottomRightRadius="@dimen/widget_list_content_corner_radius" />
+ </shape>
+ </item>
+
+ <!-- LAST : 0 0 L L -->
+ <item android:state_last="true">
+ <shape android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="0dp"
+ android:topRightRadius="0dp"
+ android:bottomLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:bottomRightRadius="@dimen/widget_list_top_bottom_corner_radius" />
+ </shape>
+ </item>
+</selector>
diff --git a/res/drawable/bg_widgets_header.xml b/res/drawable/bg_widgets_header.xml
new file mode 100644
index 0000000..a89aad4
--- /dev/null
+++ b/res/drawable/bg_widgets_header.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+ android:insetTop="@dimen/widget_list_entry_spacing" >
+ <ripple
+ android:color="?android:attr/colorControlHighlight"
+ android:paddingTop="@dimen/widget_list_header_view_vertical_padding"
+ android:paddingBottom="@dimen/widget_list_header_view_vertical_padding" >
+ <item android:id="@android:id/mask"
+ android:drawable="@drawable/bg_widgets_header_states" />
+ <item android:drawable="@drawable/bg_widgets_header_states" />
+ </ripple>
+</inset>
\ No newline at end of file
diff --git a/res/drawable/bg_widgets_header_states.xml b/res/drawable/bg_widgets_header_states.xml
new file mode 100644
index 0000000..f45a7ab
--- /dev/null
+++ b/res/drawable/bg_widgets_header_states.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <!--
+ L -> large radius
+ s -> small radius
+ 0 -> no radiuls
+ -->
+
+ <!-- SINGLE : L L L L -->
+ <item android:state_single="true">
+ <shape android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:topRightRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:bottomLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:bottomRightRadius="@dimen/widget_list_top_bottom_corner_radius" />
+ </shape>
+ </item>
+
+ <!-- FIRST_EXPANDED : L L 0 0 -->
+ <item android:state_first="true" android:state_expanded="true">
+ <shape android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:topRightRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:bottomLeftRadius="0dp"
+ android:bottomRightRadius="0dp" />
+ </shape>
+ </item>
+
+ <!-- FIRST : L L s s -->
+ <item android:state_first="true" >
+ <shape android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:topRightRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:bottomLeftRadius="@dimen/widget_list_content_corner_radius"
+ android:bottomRightRadius="@dimen/widget_list_content_corner_radius" />
+ </shape>
+ </item>
+
+ <!-- MIDDLE_EXPANDED : s s 0 0 -->
+ <item android:state_middle="true" android:state_expanded="true">
+ <shape android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="@dimen/widget_list_content_corner_radius"
+ android:topRightRadius="@dimen/widget_list_content_corner_radius"
+ android:bottomLeftRadius="0dp"
+ android:bottomRightRadius="0dp" />
+ </shape>
+ </item>
+
+ <!-- MIDDLE : s s s s -->
+ <item android:state_middle="true">
+ <shape android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="@dimen/widget_list_content_corner_radius"
+ android:topRightRadius="@dimen/widget_list_content_corner_radius"
+ android:bottomLeftRadius="@dimen/widget_list_content_corner_radius"
+ android:bottomRightRadius="@dimen/widget_list_content_corner_radius" />
+ </shape>
+ </item>
+
+ <!-- LAST : s s L L -->
+ <item android:state_last="true">
+ <shape android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="@dimen/widget_list_content_corner_radius"
+ android:topRightRadius="@dimen/widget_list_content_corner_radius"
+ android:bottomLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
+ android:bottomRightRadius="@dimen/widget_list_top_bottom_corner_radius" />
+ </shape>
+ </item>
+</selector>
diff --git a/res/drawable/widgets_tray_expand_button.xml b/res/drawable/widgets_tray_expand_button.xml
index 8316e0f..f2e142e 100644
--- a/res/drawable/widgets_tray_expand_button.xml
+++ b/res/drawable/widgets_tray_expand_button.xml
@@ -14,8 +14,8 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true"
+ <item android:state_expanded="true"
android:drawable="@drawable/ic_expand_less" />
- <item android:state_checked="false"
+ <item android:state_expanded="false"
android:drawable="@drawable/ic_expand_more" />
</selector>
diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml
index 35bea27..6d26ce3 100644
--- a/res/layout/widgets_list_row_header.xml
+++ b/res/layout/widgets_list_row_header.xml
@@ -23,7 +23,8 @@
android:importantForAccessibility="yes"
android:focusable="true"
launcher:appIconSize="48dp"
- android:descendantFocusability="afterDescendants">
+ android:descendantFocusability="afterDescendants"
+ android:background="@drawable/bg_widgets_header" >
<ImageView
android:id="@+id/app_icon"
@@ -65,8 +66,11 @@
<!-- This checkbox is not clickable. The outermost LinearLayout is responsible to handle all
click event and update the checkbox state. -->
- <CheckBox
+ <ImageView
+ android:duplicateParentState="true"
android:id="@+id/toggle"
+ android:alpha=".6"
+ android:src="@drawable/widgets_tray_expand_button"
android:layout_marginHorizontal="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -74,7 +78,6 @@
android:layout_alignParentEnd="true"
android:enabled="false"
android:clickable="false"
- android:importantForAccessibility="no"
- android:button="@drawable/widgets_tray_expand_button"/>
+ android:importantForAccessibility="no" />
</com.android.launcher3.widget.picker.WidgetsListHeader>
\ No newline at end of file
diff --git a/res/layout/widgets_table_container.xml b/res/layout/widgets_table_container.xml
index ab96b1343..4a32672 100644
--- a/res/layout/widgets_table_container.xml
+++ b/res/layout/widgets_table_container.xml
@@ -16,5 +16,6 @@
<com.android.launcher3.widget.picker.WidgetsListTableView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widgets_table"
+ android:background="@drawable/bg_widgets_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index af9ed95..7b0033d 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -356,6 +356,9 @@
"SECONDARY_DRAG_N_DROP_TO_PIN", false,
"Enable dragging and dropping to pin apps within secondary display");
+ public static final BooleanFlag ENABLE_ICON_IN_TEXT_HEADER = getDebugFlag(
+ "ENABLE_ICON_IN_TEXT_HEADER", false, "Show icon in textheader");
+
public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag(
"SHOW_DOT_PAGINATION", false, "Enable showing dot pagination in workspace");
@@ -408,6 +411,10 @@
"Enables receiving unfold animation events from sysui instead of calculating "
+ "them in launcher process using hinge sensor values.");
+ public static final BooleanFlag ENABLE_KEYBOARD_QUICK_SWITCH = getDebugFlag(
+ "ENABLE_KEYBOARD_QUICK_SWITCH", false,
+ "Enables keyboard quick switching");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 7c7cdf4..2ce400e 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -274,8 +274,6 @@
mSuggestedWidgetsHeader = (WidgetsListHeader) layoutInflater.inflate(
R.layout.widgets_list_row_header, mSuggestedWidgetsContainer, false);
mSuggestedWidgetsHeader.setExpanded(true);
- mSuggestedWidgetsHeader.setBackground(
- new WidgetsListDrawableFactory(getContext()).createHeaderBackgroundDrawable());
PackageItemInfo packageItemInfo = new PackageItemInfo(
/* packageName= */ SUGGESTIONS_PACKAGE_NAME,
@@ -311,9 +309,8 @@
? mContent.findViewById(R.id.title)
: mSearchScrollView.findViewById(R.id.title);
mRightPane = mIsTwoPane ? mContent.findViewById(R.id.right_pane) : null;
- mWidgetsListTableViewHolderBinder = new WidgetsListTableViewHolderBinder(
- layoutInflater, this, this,
- new WidgetsListDrawableFactory(getContext()));
+ mWidgetsListTableViewHolderBinder =
+ new WidgetsListTableViewHolderBinder(layoutInflater, this, this);
onRecommendedWidgetsBound();
onWidgetsBound();
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index 549ac42..b5ff719 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -108,19 +108,15 @@
mHeaderChangeListener = headerChangeListener;
mContext = context;
mDiffReporter = new WidgetsDiffReporter(iconCache, this);
- WidgetsListDrawableFactory listDrawableFactory = new WidgetsListDrawableFactory(context);
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_LIST,
new WidgetsListTableViewHolderBinder(
- layoutInflater, iconClickListener, iconLongClickListener,
- listDrawableFactory));
+ layoutInflater, iconClickListener, iconLongClickListener));
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_HEADER,
new WidgetsListHeaderViewHolderBinder(
- layoutInflater,
- /* onHeaderClickListener= */ this,
- listDrawableFactory));
+ layoutInflater, /* onHeaderClickListener= */ this));
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_SPACE,
new WidgetsSpaceViewHolderBinder(emptySpaceHeightProvider));
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java b/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java
deleted file mode 100644
index 984a274..0000000
--- a/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.widget.picker;
-
-import static com.android.launcher3.widget.picker.WidgetsListDrawableState.FIRST;
-import static com.android.launcher3.widget.picker.WidgetsListDrawableState.FIRST_EXPANDED;
-import static com.android.launcher3.widget.picker.WidgetsListDrawableState.LAST;
-import static com.android.launcher3.widget.picker.WidgetsListDrawableState.MIDDLE;
-import static com.android.launcher3.widget.picker.WidgetsListDrawableState.MIDDLE_EXPANDED;
-import static com.android.launcher3.widget.picker.WidgetsListDrawableState.SINGLE;
-
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.InsetDrawable;
-import android.graphics.drawable.RippleDrawable;
-import android.graphics.drawable.StateListDrawable;
-
-import com.android.launcher3.R;
-import com.android.launcher3.util.Themes;
-
-/** Factory for creating drawables to use as background for list elements. */
-final class WidgetsListDrawableFactory {
-
- private final float mTopBottomCornerRadius;
- private final float mMiddleCornerRadius;
- private final ColorStateList mSurfaceColor;
- private final ColorStateList mRippleColor;
- private final int mVerticalPadding;
- private final int mHeaderMargin;
-
- WidgetsListDrawableFactory(Context context) {
- Resources res = context.getResources();
- mTopBottomCornerRadius = res.getDimension(R.dimen.widget_list_top_bottom_corner_radius);
- mMiddleCornerRadius = res.getDimension(R.dimen.widget_list_content_corner_radius);
- mSurfaceColor = context.getColorStateList(R.color.surface);
- mRippleColor = ColorStateList.valueOf(
- Themes.getAttrColor(context, android.R.attr.colorControlHighlight));
- mVerticalPadding =
- res.getDimensionPixelSize(R.dimen.widget_list_header_view_vertical_padding);
- mHeaderMargin = res.getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
- }
-
- /**
- * Creates a drawable for widget header list items. This drawable supports all positions
- * in {@link WidgetsListDrawableState}.
- */
- Drawable createHeaderBackgroundDrawable() {
- StateListDrawable stateList = new StateListDrawable();
- stateList.addState(
- SINGLE.mStateSet,
- createRoundedRectDrawable(mTopBottomCornerRadius, mTopBottomCornerRadius));
- stateList.addState(
- FIRST_EXPANDED.mStateSet,
- createRoundedRectDrawable(mTopBottomCornerRadius, 0));
- stateList.addState(
- FIRST.mStateSet,
- createRoundedRectDrawable(mTopBottomCornerRadius, mMiddleCornerRadius));
- stateList.addState(
- MIDDLE_EXPANDED.mStateSet,
- createRoundedRectDrawable(mMiddleCornerRadius, 0));
- stateList.addState(
- MIDDLE.mStateSet,
- createRoundedRectDrawable(mMiddleCornerRadius, mMiddleCornerRadius));
- stateList.addState(
- LAST.mStateSet,
- createRoundedRectDrawable(mMiddleCornerRadius, mTopBottomCornerRadius));
- RippleDrawable ripple =
- new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList);
- ripple.setPadding(0, mVerticalPadding, 0, mVerticalPadding);
- return new InsetDrawable(ripple, 0, mHeaderMargin, 0, 0);
- }
-
- /**
- * Creates a drawable for widget content list items. This state list supports the middle and
- * last states.
- */
- Drawable createContentBackgroundDrawable() {
- StateListDrawable stateList = new StateListDrawable();
- stateList.addState(
- MIDDLE.mStateSet,
- createRoundedRectDrawable(0, mMiddleCornerRadius));
- stateList.addState(
- LAST.mStateSet,
- createRoundedRectDrawable(0, mTopBottomCornerRadius));
- return new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList);
- }
-
- /** Creates a rounded-rect drawable with the specified radii. */
- private Drawable createRoundedRectDrawable(float topRadius, float bottomRadius) {
- GradientDrawable backgroundMask = new GradientDrawable();
- backgroundMask.setColor(mSurfaceColor);
- backgroundMask.setShape(GradientDrawable.RECTANGLE);
- backgroundMask.setCornerRadii(
- new float[]{
- topRadius,
- topRadius,
- topRadius,
- topRadius,
- bottomRadius,
- bottomRadius,
- bottomRadius,
- bottomRadius
- });
- return backgroundMask;
- }
-}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
index a6ef89f..547f39e 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
@@ -28,7 +28,6 @@
import android.util.TypedValue;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -67,7 +66,6 @@
private TextView mTitle;
private TextView mSubtitle;
private GradientDrawable mBackground;
- private CheckBox mExpandToggle;
private boolean mEnableIconUpdateAnimation = false;
private boolean mIsExpanded = false;
@@ -101,9 +99,8 @@
mAppIcon = findViewById(R.id.app_icon);
mTitle = findViewById(R.id.app_title);
mSubtitle = findViewById(R.id.app_subtitle);
- mExpandToggle = findViewById(R.id.toggle);
if (mIsTwoPane) {
- mExpandToggle.setVisibility(GONE);
+ findViewById(R.id.toggle).setVisibility(GONE);
}
setAccessibilityDelegate(new AccessibilityDelegate() {
@@ -153,7 +150,6 @@
@UiThread
public void setExpanded(boolean isExpanded) {
this.mIsExpanded = isExpanded;
- mExpandToggle.setChecked(isExpanded);
if (mIsTwoPane) {
if (Utilities.isDarkTheme(getContext())) {
if (mIsExpanded) {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
index c6a7285..27a2b1c 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
@@ -32,22 +32,17 @@
ViewHolderBinder<WidgetsListHeaderEntry, WidgetsListHeaderHolder> {
private final LayoutInflater mLayoutInflater;
private final OnHeaderClickListener mOnHeaderClickListener;
- private final WidgetsListDrawableFactory mListDrawableFactory;
public WidgetsListHeaderViewHolderBinder(LayoutInflater layoutInflater,
- OnHeaderClickListener onHeaderClickListener,
- WidgetsListDrawableFactory listDrawableFactory) {
+ OnHeaderClickListener onHeaderClickListener) {
mLayoutInflater = layoutInflater;
mOnHeaderClickListener = onHeaderClickListener;
- mListDrawableFactory = listDrawableFactory;
}
@Override
public WidgetsListHeaderHolder newViewHolder(ViewGroup parent) {
- WidgetsListHeader header = (WidgetsListHeader) mLayoutInflater.inflate(
- R.layout.widgets_list_row_header, parent, false);
- header.setBackground(mListDrawableFactory.createHeaderBackgroundDrawable());
- return new WidgetsListHeaderHolder(header);
+ return new WidgetsListHeaderHolder((WidgetsListHeader) mLayoutInflater.inflate(
+ R.layout.widgets_list_row_header, parent, false));
}
@Override
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
index 8500b9a..4c1f7a9 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
@@ -51,17 +51,14 @@
private final LayoutInflater mLayoutInflater;
private final OnClickListener mIconClickListener;
private final OnLongClickListener mIconLongClickListener;
- private final WidgetsListDrawableFactory mListDrawableFactory;
public WidgetsListTableViewHolderBinder(
LayoutInflater layoutInflater,
OnClickListener iconClickListener,
- OnLongClickListener iconLongClickListener,
- WidgetsListDrawableFactory listDrawableFactory) {
+ OnLongClickListener iconLongClickListener) {
mLayoutInflater = layoutInflater;
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
- mListDrawableFactory = listDrawableFactory;
}
@Override
@@ -70,12 +67,8 @@
Log.v(TAG, "\nonCreateViewHolder");
}
- WidgetsRowViewHolder viewHolder =
- new WidgetsRowViewHolder(mLayoutInflater.inflate(
+ return new WidgetsRowViewHolder(mLayoutInflater.inflate(
R.layout.widgets_table_container, parent, false));
- viewHolder.tableContainer.setBackgroundDrawable(
- mListDrawableFactory.createContentBackgroundDrawable());
- return viewHolder;
}
@Override
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
index f53d15b..612a4c6 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
@@ -90,8 +90,7 @@
}).when(mIconCache).getTitleNoCache(any());
mViewHolderBinder = new WidgetsListHeaderViewHolderBinder(
LayoutInflater.from(mContext),
- mOnHeaderClickListener,
- new WidgetsListDrawableFactory(mContext));
+ mOnHeaderClickListener);
}
@Test
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
index 7ec4d20..9dc46f1 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
@@ -96,8 +96,7 @@
mViewHolderBinder = new WidgetsListTableViewHolderBinder(
LayoutInflater.from(mContext),
mOnIconClickListener,
- mOnLongClickListener,
- new WidgetsListDrawableFactory(mContext));
+ mOnLongClickListener);
}
@Test