From 0adad2440854d0f8dd70fa39016671d44fca5f65 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Tue, 22 Nov 2022 17:14:44 -0800 Subject: [PATCH 1/7] Adds header protection on tablet all apps panel. Removes background and manually draws it while drawing scrim. Then draws header protection on top as needed. Currently this only applies to all apps from Launcher, as Taskbar doesn't seem to use the same scrim flow. So taskbar adds the same static background that was previously used. Demo videos: https://drive.google.com/drive/folders/11PyFsrLV6-QhU_E-zD3s5bfzZK2nOU87?resourcekey=0-E41uw5TP9xuqTifLAs71yw&usp=sharing Test: Manually on phone and tablet with dark/light mode, floating search bar on/off, work profile present/absent, taskbar/home entry Bug: 240670050 Change-Id: I81dcc956d9dbbc7552c8a227a49741bcf71eed71 --- .../allapps/TaskbarAllAppsContainerView.java | 9 ++ .../all_apps_bottom_sheet_background.xml | 3 +- .../allapps/ActivityAllAppsContainerView.java | 4 + .../allapps/BaseAllAppsContainerView.java | 94 +++++++++++++++---- 4 files changed, 90 insertions(+), 20 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java index f8d9d11d39..70405d94cb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java @@ -19,6 +19,8 @@ import android.content.Context; import android.util.AttributeSet; import android.view.WindowInsets; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.R; import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; @@ -44,4 +46,11 @@ public class TaskbarAllAppsContainerView extends protected boolean isSearchSupported() { return false; } + + @Override + protected void updateBackground(DeviceProfile deviceProfile) { + super.updateBackground(deviceProfile); + // TODO(b/240670050): Remove this and add header protection for the taskbar entrypoint. + mBottomSheetBackground.setBackgroundResource(R.drawable.bg_rounded_corner_bottom_sheet); + } } diff --git a/res/layout/all_apps_bottom_sheet_background.xml b/res/layout/all_apps_bottom_sheet_background.xml index 3e47690197..b0157c9c3e 100644 --- a/res/layout/all_apps_bottom_sheet_background.xml +++ b/res/layout/all_apps_bottom_sheet_background.xml @@ -16,8 +16,7 @@ + android:layout_height="match_parent"> 0 && tabsHeight != 0) { - if (DEBUG_HEADER_PROTECTION) { - mHeaderPaint.setColor(Color.BLUE); - mHeaderPaint.setAlpha(255); - } else { - mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha)); - } - canvas.drawRect(0, bottom, canvas.getWidth(), bottom + tabsHeight, mHeaderPaint); + } + int tabsHeight = headerView.getPeripheralProtectionHeight(); + if (mTabsProtectionAlpha > 0 && tabsHeight != 0) { + if (DEBUG_HEADER_PROTECTION) { + mHeaderPaint.setColor(Color.BLUE); + mHeaderPaint.setAlpha(255); + } else { + mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha)); } + int left = 0; + int right = canvas.getWidth(); + if (isTablet) { + left = mBottomSheetBackground.getLeft(); + right = mBottomSheetBackground.getRight(); + } + canvas.drawRect(left, bottom, right, bottom + tabsHeight, mHeaderPaint); } } From 7234034ceea1a1fcc0477b45f099a9afc7151002 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 6 Dec 2022 16:39:38 -0800 Subject: [PATCH 2/7] Enable transient taskbar flag on by default. Bug: 261859222 Test: manual Change-Id: I46ed930aba743f76da3b6fe94629fdb0f585ee55 --- src/com/android/launcher3/config/FeatureFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index f9883e379c..1b0b000e10 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -343,7 +343,7 @@ public final class FeatureFlags { + " nav mode and when transient taskbar is enabled."); public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag( - "ENABLE_TRANSIENT_TASKBAR", false, "Enables transient taskbar."); + "ENABLE_TRANSIENT_TASKBAR", true, "Enables transient taskbar."); public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag( "SECONDARY_DRAG_N_DROP_TO_PIN", false, From b962950ae9a4b0c4577e571e726538df91b851b3 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Thu, 8 Dec 2022 16:19:21 +0000 Subject: [PATCH 3/7] Add logging to investigate updateOverviewTargets state. Test: Manual (logcat) Bug: 258022658 Change-Id: I50640124f1e8fd5ae4aaf6240c044ded108849b5 --- .../android/quickstep/OverviewComponentObserver.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java index 8e07376b14..83f2a0a114 100644 --- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java +++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java @@ -34,6 +34,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.util.Log; import android.util.SparseIntArray; import androidx.annotation.NonNull; @@ -54,6 +55,8 @@ import java.util.function.Consumer; * and provide callers the relevant classes. */ public final class OverviewComponentObserver { + private static final String TAG = "OverviewComponentObserver"; + private final BroadcastReceiver mUserPreferenceChangeReceiver = new SimpleBroadcastReceiver(this::updateOverviewTargets); private final BroadcastReceiver mOtherHomeAppUpdateReceiver = @@ -146,7 +149,12 @@ public final class OverviewComponentObserver { } } - if (!mDeviceState.isHomeDisabled() && (defaultHome == null || mIsDefaultHome)) { + // TODO(b/258022658): Remove temporary logging. + Log.i(TAG, "updateOverviewTargets: mIsHomeDisabled=" + mIsHomeDisabled + + ", isDefaultHomeNull=" + (defaultHome == null) + + ", mIsDefaultHome=" + mIsDefaultHome); + + if (!mIsHomeDisabled && (defaultHome == null || mIsDefaultHome)) { // User default home is same as out home app. Use Overview integrated in Launcher. mActivityInterface = LauncherActivityInterface.INSTANCE; mIsHomeAndOverviewSame = true; From 3f82a06c7fc440fe62262e3c1c53450a4371900b Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Thu, 8 Dec 2022 14:53:46 -0800 Subject: [PATCH 4/7] Remove delightful page indicator Due to design changes, we are no longer going to use the changes guarded under the flag SHOW_DELIIGHTFUL_PAGINATION, so we remove the flag and the code that was guarded by that flag Bug: 261904707 Test: verify flag SHOW_DELIGHTFUL_PAGINATION no longer exists and that the regular pagination works without issues after removing all this code Change-Id: I244b88b98df0357aa99a325a11988e8248a03206 --- src/com/android/launcher3/Launcher.java | 4 +- .../launcher3/config/FeatureFlags.java | 4 - .../pageindicators/PageIndicatorDots.java | 176 ++---------------- 3 files changed, 21 insertions(+), 163 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 1a6c68dd6a..18ed0fca9a 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -43,7 +43,6 @@ import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions; import static com.android.launcher3.anim.Interpolators.EMPHASIZED; -import static com.android.launcher3.config.FeatureFlags.SHOW_DELIGHTFUL_PAGINATION; import static com.android.launcher3.config.FeatureFlags.SHOW_DOT_PAGINATION; import static com.android.launcher3.logging.StatsLogManager.EventEnum; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND; @@ -1280,8 +1279,7 @@ public class Launcher extends StatefulActivity @Override public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { - if ((SHOW_DOT_PAGINATION.get() || SHOW_DELIGHTFUL_PAGINATION.get()) - && WorkspacePageIndicator.class.getName().equals(name)) { + if ((SHOW_DOT_PAGINATION.get()) && WorkspacePageIndicator.class.getName().equals(name)) { return LayoutInflater.from(context).inflate(R.layout.page_indicator_dots, (ViewGroup) parent, false); } diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 5cab817b43..c7e23de009 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -307,10 +307,6 @@ public final class FeatureFlags { "SCROLL_TOP_TO_RESET", false, "Bring up IME and focus on " + "input when scroll to top if 'Always show keyboard' is enabled or in prefix state"); - public static final BooleanFlag SHOW_DELIGHTFUL_PAGINATION = getDebugFlag( - "SHOW_DELIGHTFUL_PAGINATION", false, - "Enable showing the new 'delightful pagination' which is a brand" - + " new animation for folder pagination and workspace pagination"); public static final BooleanFlag POPUP_MATERIAL_U = new DeviceFlag( "POPUP_MATERIAL_U", false, "Switch popup UX to use material U"); diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java index e9b660626b..c324ce3cf5 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java @@ -16,7 +16,6 @@ package com.android.launcher3.pageindicators; -import static com.android.launcher3.config.FeatureFlags.SHOW_DELIGHTFUL_PAGINATION; import static com.android.launcher3.config.FeatureFlags.SHOW_DOT_PAGINATION; import android.animation.Animator; @@ -32,7 +31,6 @@ import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Rect; import android.graphics.RectF; -import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; @@ -48,7 +46,6 @@ import androidx.annotation.Nullable; import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.anim.Interpolators; import com.android.launcher3.util.Themes; /** @@ -70,7 +67,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private static final int PAGE_INDICATOR_ALPHA = 255; private static final int DOT_ALPHA = 128; private static final int DOT_GAP_FACTOR = 3; - private static final float DOT_GAP_FACTOR_FLOAT = 3.8f; private static final int VISIBLE_ALPHA = 1; private static final int INVISIBLE_ALPHA = 0; private Paint mPaginationPaint; @@ -78,8 +74,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator // This value approximately overshoots to 1.5 times the original size. private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f; - private static final float INDICATOR_ROTATION = 180f; - private static final RectF sTempRect = new RectF(); private static final FloatProperty CURRENT_POSITION = @@ -112,11 +106,8 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator }; private final Handler mDelayedPaginationFadeHandler = new Handler(Looper.getMainLooper()); - private final Drawable mPageIndicatorDrawable; private final float mDotRadius; private final float mCircleGap; - private final float mPageIndicatorSize; - private final float mPageIndicatorRadius; private final boolean mIsRtl; private int mNumPages; @@ -159,31 +150,14 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator mPaginationPaint.setStyle(Style.FILL); mPaginationPaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor)); mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2; - - if (SHOW_DELIGHTFUL_PAGINATION.get()) { - mPageIndicatorSize = getResources().getDimension( - R.dimen.page_indicator_size); - mPageIndicatorRadius = mPageIndicatorSize / 2; - mPageIndicatorDrawable = context.getDrawable(R.drawable.page_indicator); - mPageIndicatorDrawable.setBounds(0, 0, (int) mPageIndicatorSize, - (int) mPageIndicatorSize); - mCircleGap = DOT_GAP_FACTOR_FLOAT * mDotRadius; - - } else { - mPageIndicatorSize = 0; - mPageIndicatorRadius = 0; - mPageIndicatorDrawable = null; - mCircleGap = DOT_GAP_FACTOR * mDotRadius; - } - if (!SHOW_DELIGHTFUL_PAGINATION.get()) { - setOutlineProvider(new MyOutlineProver()); - } + mCircleGap = DOT_GAP_FACTOR * mDotRadius; + setOutlineProvider(new MyOutlineProver()); mIsRtl = Utilities.isRtl(getResources()); } @Override public void setScroll(int currentScroll, int totalScroll) { - if (SHOW_DELIGHTFUL_PAGINATION.get() || SHOW_DOT_PAGINATION.get()) { + if (SHOW_DOT_PAGINATION.get()) { animatePaginationToAlpha(VISIBLE_ALPHA); } @@ -197,16 +171,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator } mTotalScroll = totalScroll; - if (SHOW_DELIGHTFUL_PAGINATION.get()) { - mCurrentScroll = currentScroll; - invalidate(); - - if (mShouldAutoHide - && (getScrollPerPage() == 0 || mCurrentScroll % getScrollPerPage() == 0)) { - hideAfterDelay(); - } - return; - } int scrollPerPage = totalScroll / (mNumPages - 1); int pageToLeft = currentScroll / scrollPerPage; @@ -404,122 +368,45 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator } for (int i = 0; i < mEntryAnimationRadiusFactors.length; i++) { mPaginationPaint.setAlpha(i == mActivePage ? PAGE_INDICATOR_ALPHA : DOT_ALPHA); - if (SHOW_DELIGHTFUL_PAGINATION.get()) { - if (i != mActivePage) { - canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i], - mPaginationPaint); - } else { - drawPageIndicator(canvas, mEntryAnimationRadiusFactors[i]); - } - } else { - canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i], - mPaginationPaint); - } + canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i], + mPaginationPaint); x += circleGap; } } else { // Here we draw the dots mPaginationPaint.setAlpha(DOT_ALPHA); for (int i = 0; i < mNumPages; i++) { - if (SHOW_DELIGHTFUL_PAGINATION.get()) { - canvas.drawCircle(x, y, getRadius(x), mPaginationPaint); - } else { - canvas.drawCircle(x, y, mDotRadius, mPaginationPaint); - } + canvas.drawCircle(x, y, mDotRadius, mPaginationPaint); x += circleGap; } // Here we draw the current page indicator mPaginationPaint.setAlpha(PAGE_INDICATOR_ALPHA); - if (SHOW_DELIGHTFUL_PAGINATION.get()) { - drawPageIndicator(canvas, 1); - } else { - canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint); - } + canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint); } } - /** - * Draws the page indicator, denoting the currently selected page - * - * @param canvas is used to draw the page indicator and to rotate it as we scroll - * @param scale is used to set the scale of our canvas - */ - private void drawPageIndicator(Canvas canvas, float scale) { - RectF currRect = getActiveRect(); - - // saves the canvas so we can later restore it to its original scale - canvas.save(); - - // Moves the canvas to start at the top left corner of the page indicator - canvas.translate(currRect.left, currRect.top); - - // Scales the canvas in place to animate the indicator on entry - canvas.scale(scale, scale, mPageIndicatorRadius, mPageIndicatorRadius); - - int scrollPerPage = getScrollPerPage(); - // This IF is to avoid division by 0 - if (scrollPerPage != 0) { - int delta = mCurrentScroll % scrollPerPage; - canvas.rotate((INDICATOR_ROTATION * delta) / scrollPerPage, - mPageIndicatorRadius, mPageIndicatorRadius); - } - - mPageIndicatorDrawable.draw(canvas); - canvas.restore(); - } - - /** - * Returns the radius of the circle based on how close the page indicator is to it - * - * @param dotPositionX is the position the dot is located at in the x-axis - */ - private float getRadius(float dotPositionX) { - - float startXIndicator = - ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2) - getOffset(); - float indicatorPosition = startXIndicator + getIndicatorScrollDistance() - + mPageIndicatorRadius; - - // If the indicator gets close enough to a dot then we change the radius - // of the dot based on how close the indicator is to it. - float dotDistance = Math.abs(indicatorPosition - dotPositionX); - if (dotDistance <= mCircleGap) { - return Utilities.mapToRange(dotDistance, 0, mCircleGap, 0f, mDotRadius, - Interpolators.LINEAR); - } - return mDotRadius; - } - private RectF getActiveRect() { float startCircle = (int) mCurrentPosition; float delta = mCurrentPosition - startCircle; float diameter = 2 * mDotRadius; float startX; - if (SHOW_DELIGHTFUL_PAGINATION.get()) { - startX = ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2) - getOffset(); - sTempRect.top = (getHeight() - mPageIndicatorSize) * 0.5f; - sTempRect.bottom = (getHeight() + mPageIndicatorSize) * 0.5f; - sTempRect.left = startX + getIndicatorScrollDistance(); - sTempRect.right = sTempRect.left + mPageIndicatorSize; + startX = ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2); + sTempRect.top = (getHeight() * 0.5f) - mDotRadius; + sTempRect.bottom = (getHeight() * 0.5f) + mDotRadius; + sTempRect.left = startX + (startCircle * mCircleGap); + sTempRect.right = sTempRect.left + diameter; + + if (delta < SHIFT_PER_ANIMATION) { + // dot is capturing the right circle. + sTempRect.right += delta * mCircleGap * 2; } else { - startX = ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2); - sTempRect.top = (getHeight() * 0.5f) - mDotRadius; - sTempRect.bottom = (getHeight() * 0.5f) + mDotRadius; - sTempRect.left = startX + (startCircle * mCircleGap); - sTempRect.right = sTempRect.left + diameter; + // Dot is leaving the left circle. + sTempRect.right += mCircleGap; - if (delta < SHIFT_PER_ANIMATION) { - // dot is capturing the right circle. - sTempRect.right += delta * mCircleGap * 2; - } else { - // Dot is leaving the left circle. - sTempRect.right += mCircleGap; - - delta -= SHIFT_PER_ANIMATION; - sTempRect.left += delta * mCircleGap * 2; - } + delta -= SHIFT_PER_ANIMATION; + sTempRect.left += delta * mCircleGap * 2; } if (mIsRtl) { @@ -531,29 +418,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator return sTempRect; } - /** - * The offset between the radius of the dot and the midpoint of the indicator so that - * the indicator is centered in with the indicator circles - */ - private float getOffset() { - return mPageIndicatorRadius - mDotRadius; - } - - /** - * Returns an int that is the amount we need to scroll per page - */ - private int getScrollPerPage() { - return mNumPages > 1 ? mTotalScroll / (mNumPages - 1) : 0; - } - - /** - * The current scroll adjusted for the distance the indicator needs to travel on the screen - */ - private float getIndicatorScrollDistance() { - int scrollPerPage = getScrollPerPage(); - return scrollPerPage != 0 ? ((float) mCurrentScroll / scrollPerPage) * mCircleGap : 0; - } - private class MyOutlineProver extends ViewOutlineProvider { @Override From a6a67e347dbd5e8e1f9b5808f897f657643bdae6 Mon Sep 17 00:00:00 2001 From: Fengjiang Li Date: Tue, 6 Dec 2022 21:53:25 -0800 Subject: [PATCH 5/7] Support mouse right click on HomeScreen to show the customization menu Bug: b/250089861 Fix: b/250089861 Test: Manual Testing Video: https://b.corp.google.com/action/issues/250089861/attachments/40243664?download=true Change-Id: Ia23e302bf8f3e18fafd6ccd079740c8005ae7860 --- .../launcher3/CheckLongPressHelper.java | 15 +---- .../touch/WorkspaceTouchListener.java | 10 +++ src/com/android/launcher3/util/TouchUtil.java | 37 ++++++++++ .../android/launcher3/util/TouchUtilTest.kt | 67 +++++++++++++++++++ 4 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 src/com/android/launcher3/util/TouchUtil.java create mode 100644 tests/src/com/android/launcher3/util/TouchUtilTest.kt diff --git a/src/com/android/launcher3/CheckLongPressHelper.java b/src/com/android/launcher3/CheckLongPressHelper.java index ec29b297a9..3e4e96bec0 100644 --- a/src/com/android/launcher3/CheckLongPressHelper.java +++ b/src/com/android/launcher3/CheckLongPressHelper.java @@ -17,11 +17,12 @@ package com.android.launcher3; import android.os.Handler; -import android.view.InputDevice; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; +import com.android.launcher3.util.TouchUtil; + /** * Utility class to handle tripper long press or right click on a view with custom timeout and * stylus event @@ -64,7 +65,7 @@ public class CheckLongPressHelper { cancelLongPress(); // Mouse right click should immediately trigger a long press - if (isMouseRightClickDownOrMove(ev)) { + if (TouchUtil.isMouseRightClickDownOrMove(ev)) { mIsInMouseRightClick = true; triggerLongPress(); final Handler handler = mView.getHandler(); @@ -176,14 +177,4 @@ public class CheckLongPressHelper { return event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS && event.isButtonPressed(MotionEvent.BUTTON_SECONDARY); } - - /** - * Detect ACTION_DOWN or ACTION_MOVE from mouse right button. Note that we cannot detect - * ACTION_UP from mouse's right button because, in that case, - * {@link MotionEvent#getButtonState()} returns 0 for any mouse button (right, middle, right). - */ - private static boolean isMouseRightClickDownOrMove(MotionEvent event) { - return event.isFromSource(InputDevice.SOURCE_MOUSE) - && ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0); - } } diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java index 6cb021bc42..96ae4a32fd 100644 --- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java +++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java @@ -44,6 +44,7 @@ import com.android.launcher3.dragndrop.DragLayer; import com.android.launcher3.logger.LauncherAtom; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; +import com.android.launcher3.util.TouchUtil; /** * Helper class to handle touch on empty space in workspace and show options popup on long press @@ -105,6 +106,11 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe if (handleLongPress) { mLongPressState = STATE_REQUESTED; mTouchDownPoint.set(ev.getX(), ev.getY()); + // Mouse right button's ACTION_DOWN should immediately show menu + if (TouchUtil.isMouseRightClickDownOrMove(ev)) { + maybeShowMenu(); + return true; + } } mWorkspace.onTouchEvent(ev); @@ -185,6 +191,10 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe @Override public void onLongPress(MotionEvent event) { + maybeShowMenu(); + } + + private void maybeShowMenu() { if (mLongPressState == STATE_REQUESTED) { TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Workspace.longPress"); if (canHandleLongPress()) { diff --git a/src/com/android/launcher3/util/TouchUtil.java b/src/com/android/launcher3/util/TouchUtil.java new file mode 100644 index 0000000000..b18a2ef485 --- /dev/null +++ b/src/com/android/launcher3/util/TouchUtil.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 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.util; + +import android.view.InputDevice; +import android.view.MotionEvent; + +import androidx.annotation.NonNull; + +/** Util class for touch event. */ +public final class TouchUtil { + + private TouchUtil() {} + + /** + * Detect ACTION_DOWN or ACTION_MOVE from mouse right button. Note that we cannot detect + * ACTION_UP from mouse's right button because, in that case, + * {@link MotionEvent#getButtonState()} returns 0 for any mouse button (right, middle, right). + */ + public static boolean isMouseRightClickDownOrMove(@NonNull MotionEvent event) { + return event.isFromSource(InputDevice.SOURCE_MOUSE) + && ((event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0); + } +} diff --git a/tests/src/com/android/launcher3/util/TouchUtilTest.kt b/tests/src/com/android/launcher3/util/TouchUtilTest.kt new file mode 100644 index 0000000000..d6c6e91e49 --- /dev/null +++ b/tests/src/com/android/launcher3/util/TouchUtilTest.kt @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2022 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.util + +import android.view.InputDevice +import android.view.MotionEvent +import androidx.test.filters.SmallTest +import com.google.common.truth.Truth.assertThat +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Test +import org.junit.runner.RunWith + +/** Unit tests for [TouchUtil] */ +@SmallTest +@RunWith(AndroidJUnit4::class) +class TouchUtilTest { + + @Test + fun isMouseRightClickDownOrMove_onMouseRightButton_returnsTrue() { + val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0) + ev.source = InputDevice.SOURCE_MOUSE + ev.buttonState = MotionEvent.BUTTON_SECONDARY + + assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isTrue() + } + + @Test + fun isMouseRightClickDownOrMove_onMouseLeftButton_returnsFalse() { + val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0) + ev.source = InputDevice.SOURCE_MOUSE + ev.buttonState = MotionEvent.BUTTON_PRIMARY + + assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse() + } + + @Test + fun isMouseRightClickDownOrMove_onMouseTertiaryButton_returnsFalse() { + val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0) + ev.source = InputDevice.SOURCE_MOUSE + ev.buttonState = MotionEvent.BUTTON_TERTIARY + + assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse() + } + + @Test + fun isMouseRightClickDownOrMove_onDpadRightButton_returnsFalse() { + val ev = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 1.0f, 0.0f, 0) + ev.source = InputDevice.SOURCE_DPAD + ev.buttonState = MotionEvent.BUTTON_SECONDARY + + assertThat(TouchUtil.isMouseRightClickDownOrMove(ev)).isFalse() + } +} From 85ccf120f2424717fd893e6f64e56f57f9f63087 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Thu, 8 Dec 2022 21:00:45 +0000 Subject: [PATCH 6/7] Better support transient and persistent taskbar in taskbar's overlays. - Transient taskbar nav threshold now works in overlays. - Delay closing overlay to transient app-window threshold if necessary. - Persistent taskbar no longer stashes for EDU overlay. - EDU overlay provides enough bottom padding for transient and persistent taskbar. Test: Manual Bug: 217261955 Change-Id: I2ae5612ef70a6d09e22f83f8117cdbf2a0a053b8 Fix: 260769010 --- quickstep/res/layout/taskbar_edu.xml | 2 +- .../taskbar/TaskbarActivityContext.java | 10 +++++ .../taskbar/TaskbarEduController.java | 29 +++++++------ .../taskbar/TaskbarStashController.java | 7 +-- .../taskbar/TaskbarUIController.java | 5 ++- .../allapps/TaskbarAllAppsViewController.java | 19 +++++--- .../TaskbarStashInputConsumer.java | 43 +++++++++++++------ 7 files changed, 76 insertions(+), 39 deletions(-) diff --git a/quickstep/res/layout/taskbar_edu.xml b/quickstep/res/layout/taskbar_edu.xml index 10444f1d96..d7daea31cd 100644 --- a/quickstep/res/layout/taskbar_edu.xml +++ b/quickstep/res/layout/taskbar_edu.xml @@ -46,7 +46,7 @@ android:id="@+id/edu_start_button" android:layout_width="wrap_content" android:layout_height="36dp" - android:layout_marginBottom="92dp" + android:layout_marginBottom="18dp" android:layout_marginTop="32dp" app:layout_constraintTop_toBottomOf="@id/content" app:layout_constraintBottom_toBottomOf="parent" diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 01ec5f34ad..83b8d83044 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -877,6 +877,16 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false); } + /** Called when we want to hide the overlay window when user performs swipe up gesture. */ + public void onSwipeToHideOverlay() { + mControllers.taskbarOverlayController.hideWindow(); + } + + /** Returns {@code true} if taskbar is stashed. */ + public boolean isTaskbarStashed() { + return mControllers.taskbarStashController.isStashed(); + } + /** * Called to start the taskbar translation spring to its settled translation (0). */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java index 2cb05ff684..d3f1b2f51e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java @@ -15,11 +15,11 @@ */ package com.android.launcher3.taskbar; -import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_EDU; -import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; - import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import com.android.launcher3.taskbar.overlay.TaskbarOverlayController; @@ -62,20 +62,21 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC : R.layout.taskbar_edu_pages_persistent, mPagedView, true); + + // Provide enough room for taskbar. + View startButton = mTaskbarEduView.findViewById(R.id.edu_start_button); + ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) startButton.getLayoutParams(); + DeviceProfile dp = overlayContext.getDeviceProfile(); + layoutParams.bottomMargin += DisplayController.isTransientTaskbar(overlayContext) + ? dp.taskbarSize + dp.transientTaskbarMargin + : dp.taskbarSize; + mTaskbarEduView.init(new TaskbarEduCallbacks()); mControllers.navbarButtonsViewController.setSlideInViewVisible(true); - TaskbarStashController stashController = mControllers.taskbarStashController; - stashController.updateStateForFlag(FLAG_STASHED_IN_APP_EDU, true); - stashController.applyState(overlayController.getOpenDuration()); - - mTaskbarEduView.setOnCloseBeginListener(() -> { - mControllers.navbarButtonsViewController.setSlideInViewVisible(false); - // Post in case view is closing due to gesture navigation. If a gesture is in progress, - // wait to unstash until after the gesture is finished. - MAIN_EXECUTOR.post(() -> stashController.resetFlagIfNoGestureInProgress( - FLAG_STASHED_IN_APP_EDU)); - }); + mTaskbarEduView.setOnCloseBeginListener( + () -> mControllers.navbarButtonsViewController.setSlideInViewVisible(false)); mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null); mTaskbarEduView.show(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 3d98f6edc6..74be20882c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -82,7 +82,6 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba public static final int FLAG_IN_SETUP = 1 << 8; // In the Setup Wizard public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 9; // phone screen gesture nav, stashed public static final int FLAG_STASHED_IN_APP_AUTO = 1 << 10; // Autohide (transient taskbar). - public static final int FLAG_STASHED_IN_APP_EDU = 1 << 11; // EDU is visible. // If any of these flags are enabled, isInApp should return true. private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP; @@ -91,7 +90,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL | FLAG_STASHED_IN_SYSUI_STATE | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_TASKBAR_ALL_APPS - | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO | FLAG_STASHED_IN_APP_EDU; + | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO; private static final int FLAGS_STASHED_IN_APP_IGNORING_IME = FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME; @@ -101,8 +100,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // Currently any flag that causes us to stash in an app is included, except for IME or All Apps // since those cover the underlying app anyway and thus the app shouldn't change insets. private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP - & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS - & ~FLAG_STASHED_IN_APP_EDU; + & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS; /** * How long to stash/unstash when manually invoked via long press. @@ -728,7 +726,6 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // Only update the following flags when system gesture is not in progress. boolean shouldStashForIme = shouldStashForIme(); updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false); - updateStateForFlag(FLAG_STASHED_IN_APP_EDU, false); if (hasAnyFlag(FLAG_STASHED_IN_APP_IME) != shouldStashForIme) { updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme); applyState(TASKBAR_STASH_DURATION_FOR_IME, getTaskbarStashStartDelayForIme()); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index a059295bfc..b3b53c2732 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -25,6 +25,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; +import com.android.launcher3.util.DisplayController; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; @@ -84,7 +85,9 @@ public class TaskbarUIController { * Manually closes the overlay window. */ public void hideOverlayWindow() { - mControllers.taskbarOverlayController.hideWindow(); + if (!DisplayController.isTransientTaskbar(mControllers.taskbarActivityContext)) { + mControllers.taskbarOverlayController.hideWindow(); + } } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java index 41654866bd..721f81656a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java @@ -16,6 +16,7 @@ package com.android.launcher3.taskbar.allapps; import static com.android.launcher3.LauncherState.ALL_APPS; +import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_AUTO; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_TASKBAR_ALL_APPS; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT; @@ -28,6 +29,7 @@ import com.android.launcher3.taskbar.TaskbarControllers; import com.android.launcher3.taskbar.TaskbarStashController; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import com.android.launcher3.taskbar.overlay.TaskbarOverlayController; +import com.android.launcher3.util.DisplayController; /** * Handles the {@link TaskbarAllAppsContainerView} behavior and synchronizes its transitions with @@ -88,18 +90,25 @@ final class TaskbarAllAppsViewController { } private void setUpTaskbarStashing() { - mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, true); + mTaskbarStashController.updateStateForFlag( + DisplayController.isTransientTaskbar(mContext) + ? FLAG_STASHED_IN_APP_AUTO + : FLAG_STASHED_IN_TASKBAR_ALL_APPS, + true); mTaskbarStashController.applyState( ALL_APPS.getTransitionDuration(mContext, true /* isToState */)); + mNavbarButtonsViewController.setSlideInViewVisible(true); mSlideInView.setOnCloseBeginListener(() -> { mNavbarButtonsViewController.setSlideInViewVisible(false); AbstractFloatingView.closeOpenContainer( mContext, AbstractFloatingView.TYPE_ACTION_POPUP); - // Post in case view is closing due to gesture navigation. If a gesture is in progress, - // wait to unstash until after the gesture is finished. - MAIN_EXECUTOR.post(() -> mTaskbarStashController.resetFlagIfNoGestureInProgress( - FLAG_STASHED_IN_TASKBAR_ALL_APPS)); + if (!DisplayController.isTransientTaskbar(mContext)) { + // Post in case view is closing due to gesture navigation. If a gesture is in + // progress, wait to unstash until after the gesture is finished. + MAIN_EXECUTOR.post(() -> mTaskbarStashController.resetFlagIfNoGestureInProgress( + FLAG_STASHED_IN_TASKBAR_ALL_APPS)); + } }); } diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java index 3a094905bf..c8326c4189 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java @@ -53,8 +53,11 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { private final float mUnstashArea; private final float mScreenWidth; - private final int mTaskbarThresholdY; - private boolean mHasPassedTaskbarThreshold; + private final int mTaskbarNavThresholdY; + private final int mTaskbarAppWindowThresholdY; + private final boolean mTaskbarAlreadyOpen; + private boolean mHasPassedTaskbarNavThreshold; + private boolean mHasPassedTaskbarAppWindowThreshold; private final PointF mDownPos = new PointF(); private final PointF mLastPos = new PointF(); @@ -73,11 +76,18 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { Resources res = context.getResources(); mUnstashArea = res.getDimensionPixelSize(R.dimen.taskbar_unstash_input_area); - int taskbarThreshold = res.getDimensionPixelSize(ENABLE_TASKBAR_REVISED_THRESHOLDS.get() + int taskbarNavThreshold = res.getDimensionPixelSize(ENABLE_TASKBAR_REVISED_THRESHOLDS.get() ? R.dimen.taskbar_nav_threshold_v2 : R.dimen.taskbar_nav_threshold); + int taskbarAppWindowThreshold = res.getDimensionPixelSize( + ENABLE_TASKBAR_REVISED_THRESHOLDS.get() + ? R.dimen.taskbar_app_window_threshold_v2 + : R.dimen.taskbar_app_window_threshold); int screenHeight = taskbarActivityContext.getDeviceProfile().heightPx; - mTaskbarThresholdY = screenHeight - taskbarThreshold; + mTaskbarNavThresholdY = screenHeight - taskbarNavThreshold; + mTaskbarAppWindowThresholdY = screenHeight - taskbarAppWindowThreshold; + mTaskbarAlreadyOpen = mTaskbarActivityContext != null + && !mTaskbarActivityContext.isTaskbarStashed(); mIsTransientTaskbar = DisplayController.isTransientTaskbar(context); @@ -113,7 +123,8 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { mDownPos.set(ev.getX(), ev.getY()); mLastPos.set(mDownPos); - mHasPassedTaskbarThreshold = false; + mHasPassedTaskbarNavThreshold = false; + mHasPassedTaskbarAppWindowThreshold = false; mTaskbarActivityContext.setAutohideSuspendFlag( FLAG_AUTOHIDE_SUSPEND_TOUCHING, true); if (isInArea(x)) { @@ -156,18 +167,23 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { if (mIsTransientTaskbar) { float dY = mLastPos.y - mDownPos.y; - boolean passedTaskbarThreshold = dY < 0 - && mLastPos.y < mTaskbarThresholdY; - - if (!mHasPassedTaskbarThreshold - && passedTaskbarThreshold) { - mHasPassedTaskbarThreshold = true; + boolean passedTaskbarNavThreshold = dY < 0 + && mLastPos.y < mTaskbarNavThresholdY; + boolean passedTaskbarAppWindowThreshold = dY < 0 + && mLastPos.y < mTaskbarAppWindowThresholdY; + if (!mHasPassedTaskbarNavThreshold && passedTaskbarNavThreshold) { + mHasPassedTaskbarNavThreshold = true; mTaskbarActivityContext.onSwipeToUnstashTaskbar(); } + if (mTaskbarAlreadyOpen || (!mHasPassedTaskbarAppWindowThreshold + && passedTaskbarAppWindowThreshold)) { + mHasPassedTaskbarAppWindowThreshold = true; + mTaskbarActivityContext.onSwipeToHideOverlay(); + } if (dY < 0) { - dY = -OverScroll.dampedScroll(-dY, mTaskbarThresholdY); + dY = -OverScroll.dampedScroll(-dY, mTaskbarNavThresholdY); if (mTransitionCallback != null) { mTransitionCallback.onActionMove(dY); } @@ -185,7 +201,8 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { if (mTransitionCallback != null) { mTransitionCallback.onActionEnd(); } - mHasPassedTaskbarThreshold = false; + mHasPassedTaskbarNavThreshold = false; + mHasPassedTaskbarAppWindowThreshold = false; break; } } From 09c9cb54815747d5bdbf0cffae3265637f1ce5f0 Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Fri, 9 Dec 2022 14:42:51 -0800 Subject: [PATCH 7/7] Ignore all launcher3 flaky test so that they come back online Dashboards in: https://sites.google.com/corp/a/google.com/gnl/testing#h.p_ID_32 Bug: 256832045 Test: dashboard should not show flaky tests Change-Id: I3e4bbf14c87e23b42a010a3cad046bb4852bd641 --- tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java index 1f5590e843..0fccf7960b 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java @@ -33,6 +33,7 @@ import com.android.launcher3.ui.TestViewHelpers; import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -85,6 +86,7 @@ public class AddWidgetTest extends AbstractLauncherUiTest { * A custom shortcut is a 1x1 widget that launches a specific intent when user tap on it. * Custom shortcuts are replaced by deep shortcuts after api 25. */ + @Ignore @Test @PortraitLandscape public void testDragCustomShortcut() throws Throwable {