From 1a4670eeffc165c823a7bbc0a772b086a111888d Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Tue, 16 Mar 2021 19:30:04 +0000 Subject: [PATCH 01/17] Only clear widgets list upon all widgets & shortcuts update Test: Install BBC News. Then, quickly go to all widgets tray. BBC News widgets is added to the all widgets tray without removing other widgets. Bug: 182897740 Change-Id: I17b50f5128e24c346354b8fb7817a318a94efb62 --- .../com/android/launcher3/model/WidgetsModel.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java index 3ea47660b0..f82f2cc47a 100644 --- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java +++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java @@ -132,7 +132,7 @@ public class WidgetsModel { widgetsAndShortcuts.add(new WidgetItem(info, app.getIconCache(), pm)); updatedItems.add(info); } - setWidgetsAndShortcuts(widgetsAndShortcuts, app); + setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser); } catch (Exception e) { if (!FeatureFlags.IS_STUDIO_BUILD && Utilities.isBinderSizeError(e)) { // the returned value may be incomplete and will not be refreshed until the next @@ -149,7 +149,7 @@ public class WidgetsModel { } private synchronized void setWidgetsAndShortcuts(ArrayList rawWidgetsShortcuts, - LauncherAppState app) { + LauncherAppState app, @Nullable PackageUserKey packageUser) { if (DEBUG) { Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size()); } @@ -158,8 +158,12 @@ public class WidgetsModel { // {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList} HashMap tmpPackageItemInfos = new HashMap<>(); - // clear the lists. - mWidgetsList.clear(); + // Clear the lists only if this is an update on all widgets and shortcuts. If packageUser + // isn't null, only updates the shortcuts and widgets for the app represented in + // packageUser. + if (packageUser == null) { + mWidgetsList.clear(); + } // add and update. mWidgetsList.putAll(rawWidgetsShortcuts.stream() .filter(new WidgetValidityCheck(app)) From 333a110840be0c6a1aacca107b703ce3e4496e02 Mon Sep 17 00:00:00 2001 From: Samuel Fufa Date: Tue, 16 Mar 2021 18:43:03 -0500 Subject: [PATCH 02/17] Move SearchWidgetInfoContainer to NexusLauncher Bug: 182361605 Test: Manual Change-Id: I082c0ecdebca4b8c41d5d6283aacff555fa7ae63 --- .../search/SearchWidgetInfoContainer.java | 73 ------------------- 1 file changed, 73 deletions(-) delete mode 100644 src/com/android/launcher3/allapps/search/SearchWidgetInfoContainer.java diff --git a/src/com/android/launcher3/allapps/search/SearchWidgetInfoContainer.java b/src/com/android/launcher3/allapps/search/SearchWidgetInfoContainer.java deleted file mode 100644 index 8e5f8cb9c0..0000000000 --- a/src/com/android/launcher3/allapps/search/SearchWidgetInfoContainer.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2020 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.allapps.search; - -import android.appwidget.AppWidgetHostView; -import android.appwidget.AppWidgetProviderInfo; -import android.content.Context; -import android.widget.RemoteViews; - -import java.util.ArrayList; -import java.util.List; - -/** - * A placeholder {@link AppWidgetHostView} used for managing widget search results - */ -public class SearchWidgetInfoContainer extends AppWidgetHostView { - private int mAppWidgetId; - private AppWidgetProviderInfo mProviderInfo; - private RemoteViews mViews; - private List mListeners = new ArrayList<>(); - - public SearchWidgetInfoContainer(Context context) { - super(context); - } - - @Override - public void setAppWidget(int appWidgetId, AppWidgetProviderInfo info) { - mAppWidgetId = appWidgetId; - mProviderInfo = info; - for (AppWidgetHostView listener : mListeners) { - listener.setAppWidget(mAppWidgetId, mProviderInfo); - } - } - - @Override - public void updateAppWidget(RemoteViews remoteViews) { - mViews = remoteViews; - for (AppWidgetHostView listener : mListeners) { - listener.updateAppWidget(remoteViews); - } - } - - /** - * Create a live {@link AppWidgetHostView} from placeholder - */ - public void attachWidget(AppWidgetHostView hv) { - hv.setTag(getTag()); - hv.setAppWidget(mAppWidgetId, mProviderInfo); - hv.updateAppWidget(mViews); - mListeners.add(hv); - } - - /** - * stops AppWidgetHostView from getting updates - */ - public void detachWidget(AppWidgetHostView hostView) { - mListeners.remove(hostView); - } - -} From a608d81359c0c161765cc8f2b26be79a1e8c7912 Mon Sep 17 00:00:00 2001 From: "[1;3C" Date: Fri, 22 Jan 2021 13:34:46 -0800 Subject: [PATCH 03/17] Add rotation support to launch animations This only adds support for launch animations. Recents requires some auxiliar work. Adds a rotation parameter to the animation targets that only gets used by shell transitions. If this is non-zero, launcher will transform it's coordinates relative to that provide rotation. Bug: 179308296 Test: Launch and exit apps with different orientation from default (portrait). Change-Id: I7b52cbd37432bcd43e7155bcb07b30cc65c43186 --- .../launcher3/QuickstepTransitionManager.java | 111 +++++++++++++----- src/com/android/launcher3/Utilities.java | 31 +++++ 2 files changed, 114 insertions(+), 28 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 343b87e735..5dcec685ff 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -314,9 +314,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // before our internal listeners. mLauncher.getStateManager().setCurrentAnimation(anim); - Rect windowTargetBounds = getWindowTargetBounds(appTargets); + final int rotationChange = getRotationChange(appTargets); + // Note: the targetBounds are relative to the launcher + Rect windowTargetBounds = getWindowTargetBounds(appTargets, rotationChange); anim.play(getOpeningWindowAnimators(v, appTargets, wallpaperTargets, windowTargetBounds, - areAllTargetsTranslucent(appTargets))); + areAllTargetsTranslucent(appTargets), rotationChange)); if (launcherClosing) { Pair launcherContentAnimator = getLauncherContentAnimator(true /* isAppOpening */, @@ -345,19 +347,29 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * In multiwindow mode, we need to get the final size of the opening app window target to help * figure out where the floating view should animate to. */ - private Rect getWindowTargetBounds(RemoteAnimationTargetCompat[] appTargets) { - Rect bounds = new Rect(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx); - if (mLauncher.isInMultiWindowMode()) { - for (RemoteAnimationTargetCompat target : appTargets) { - if (target.mode == MODE_OPENING) { - bounds.set(target.screenSpaceBounds); - if (target.localBounds != null) { - bounds.set(target.localBounds); - } else { - bounds.offsetTo(target.position.x, target.position.y); - } - return bounds; - } + private Rect getWindowTargetBounds(@NonNull RemoteAnimationTargetCompat[] appTargets, + int rotationChange) { + RemoteAnimationTargetCompat target = null; + for (RemoteAnimationTargetCompat t : appTargets) { + if (t.mode != MODE_OPENING) continue; + target = t; + break; + } + if (target == null) return new Rect(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx); + final Rect bounds = new Rect(target.screenSpaceBounds); + if (target.localBounds != null) { + bounds.set(target.localBounds); + } else { + bounds.offsetTo(target.position.x, target.position.y); + } + if (rotationChange != 0) { + if ((rotationChange % 2) == 1) { + // undoing rotation, so our "original" parent size is actually flipped + Utilities.rotateBounds(bounds, mDeviceProfile.heightPx, mDeviceProfile.widthPx, + 4 - rotationChange); + } else { + Utilities.rotateBounds(bounds, mDeviceProfile.widthPx, mDeviceProfile.heightPx, + 4 - rotationChange); } } return bounds; @@ -510,7 +522,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private Animator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets, - Rect windowTargetBounds, boolean appTargetsAreTranslucent) { + Rect windowTargetBounds, boolean appTargetsAreTranslucent, int rotationChange) { RectF launcherIconBounds = new RectF(); FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v, !appTargetsAreTranslucent, launcherIconBounds, true /* isOpening */); @@ -610,6 +622,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener final int windowCropWidth = crop.width(); final int windowCropHeight = crop.height(); + if (rotationChange != 0) { + Utilities.rotateBounds(crop, mDeviceProfile.widthPx, + mDeviceProfile.heightPx, rotationChange); + } // Scale the size of the icon to match the size of the window crop. float scaleX = iconWidth / windowCropWidth; @@ -649,7 +665,20 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener if (target.mode == MODE_OPENING) { matrix.setScale(scale, scale); - matrix.postTranslate(windowTransX0, windowTransY0); + if (rotationChange == 1) { + matrix.postTranslate(windowTransY0, + mDeviceProfile.widthPx - (windowTransX0 + scaledCropWidth)); + } else if (rotationChange == 2) { + matrix.postTranslate( + mDeviceProfile.widthPx - (windowTransX0 + scaledCropWidth), + mDeviceProfile.heightPx - (windowTransY0 + scaledCropHeight)); + } else if (rotationChange == 3) { + matrix.postTranslate( + mDeviceProfile.heightPx - (windowTransY0 + scaledCropHeight), + windowTransX0); + } else { + matrix.postTranslate(windowTransX0, windowTransY0); + } floatingView.update(floatingIconBounds, mIconAlpha.value, percent, 0f, mWindowRadius.value * scale, true /* isOpening */); @@ -658,17 +687,25 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener .withAlpha(1f - mIconAlpha.value) .withCornerRadius(mWindowRadius.value) .withShadowRadius(mShadowRadius.value); - } else { + } else if (target.mode == MODE_CLOSING) { if (target.localBounds != null) { final Rect localBounds = target.localBounds; tmpPos.set(target.localBounds.left, target.localBounds.top); } else { tmpPos.set(target.position.x, target.position.y); } - - matrix.setTranslate(tmpPos.x, tmpPos.y); final Rect crop = new Rect(target.screenSpaceBounds); crop.offsetTo(0, 0); + + if ((rotationChange % 2) == 1) { + int tmp = crop.right; + crop.right = crop.bottom; + crop.bottom = tmp; + tmp = tmpPos.x; + tmpPos.x = tmpPos.y; + tmpPos.y = tmp; + } + matrix.setTranslate(tmpPos.x, tmpPos.y); builder.withMatrix(matrix) .withWindowCrop(crop) .withAlpha(1f); @@ -825,14 +862,26 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener return unlockAnimator; } + private static int getRotationChange(RemoteAnimationTargetCompat[] appTargets) { + int rotationChange = 0; + for (RemoteAnimationTargetCompat target : appTargets) { + if (Math.abs(target.rotationChange) > Math.abs(rotationChange)) { + rotationChange = target.rotationChange; + } + } + return rotationChange; + } + /** * Animator that controls the transformations of the windows the targets that are closing. */ private Animator getClosingWindowAnimators(RemoteAnimationTargetCompat[] appTargets, RemoteAnimationTargetCompat[] wallpaperTargets) { + final int rotationChange = getRotationChange(appTargets); SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(mDragLayer); Matrix matrix = new Matrix(); Point tmpPos = new Point(); + Rect tmpRect = new Rect(); ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1); int duration = CLOSING_TRANSITION_DURATION_MS; float windowCornerRadius = mDeviceProfile.isMultiWindowMode @@ -859,26 +908,32 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener tmpPos.set(target.position.x, target.position.y); } + final Rect crop = new Rect(target.screenSpaceBounds); + crop.offsetTo(0, 0); if (target.mode == MODE_CLOSING) { + tmpRect.set(target.screenSpaceBounds); + if ((rotationChange % 2) != 0) { + final int right = crop.right; + crop.right = crop.bottom; + crop.bottom = right; + } matrix.setScale(mScale.value, mScale.value, - target.screenSpaceBounds.centerX(), - target.screenSpaceBounds.centerY()); + tmpRect.centerX(), + tmpRect.centerY()); matrix.postTranslate(0, mDy.value); matrix.postTranslate(tmpPos.x, tmpPos.y); builder.withMatrix(matrix) + .withWindowCrop(crop) .withAlpha(mAlpha.value) .withCornerRadius(windowCornerRadius) .withShadowRadius(mShadowRadius.value); - } else { + } else if (target.mode == MODE_OPENING) { matrix.setTranslate(tmpPos.x, tmpPos.y); builder.withMatrix(matrix) + .withWindowCrop(crop) .withAlpha(1f); } - final Rect crop = new Rect(target.screenSpaceBounds); - crop.offsetTo(0, 0); - params[i] = builder - .withWindowCrop(crop) - .build(); + params[i] = builder.build(); } surfaceApplier.scheduleApply(params); } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 94c6574c60..e57844d7df 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -700,6 +700,37 @@ public final class Utilities { return (Math.abs(first - second) / Math.abs((first + second) / 2.0f)) > bound; } + /** + * Rotates `inOutBounds` by `delta` 90-degree increments. Rotation is visually CCW. Parent + * sizes represent the "space" that will rotate carrying inOutBounds along with it to determine + * the final bounds. + */ + public static void rotateBounds(Rect inOutBounds, int parentWidth, int parentHeight, + int delta) { + int rdelta = ((delta % 4) + 4) % 4; + int origLeft = inOutBounds.left; + switch (rdelta) { + case 0: + return; + case 1: + inOutBounds.left = inOutBounds.top; + inOutBounds.top = parentWidth - inOutBounds.right; + inOutBounds.right = inOutBounds.bottom; + inOutBounds.bottom = parentWidth - origLeft; + return; + case 2: + inOutBounds.left = parentWidth - inOutBounds.right; + inOutBounds.right = parentWidth - origLeft; + return; + case 3: + inOutBounds.left = parentHeight - inOutBounds.bottom; + inOutBounds.bottom = inOutBounds.right; + inOutBounds.right = parentHeight - inOutBounds.top; + inOutBounds.top = origLeft; + return; + } + } + private static class FixedSizeEmptyDrawable extends ColorDrawable { private final int mSize; From c79316740b2be062efb8822f3b45b00876ba77d3 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Thu, 18 Mar 2021 11:08:49 -0400 Subject: [PATCH 04/17] Update deep shortcut to new ui. - Removed divider views, using margin to separate views - Removed elevations - Added a ViewGroup to hold all notification views, and applied an outline Bug: 175329686 Test: visual Change-Id: Iad70dcfdaeba6050c2b17c07f76bb7bfb728e544 --- res/drawable/middle_item_primary.xml | 20 ++++++ res/drawable/single_item_primary.xml | 20 ++++++ res/drawable/single_item_secondary.xml | 20 ++++++ res/layout/deep_shortcut.xml | 9 +-- res/layout/longpress_options_menu.xml | 1 - res/layout/notification_content.xml | 8 --- res/layout/notification_gutter.xml | 5 +- res/layout/popup_container.xml | 11 ++- res/layout/system_shortcut.xml | 9 +-- res/layout/system_shortcut_icons.xml | 2 +- res/layout/user_folder_icon_normalized.xml | 1 - res/values/dimens.xml | 20 +++--- .../notification/NotificationItemView.java | 46 +++++++----- .../android/launcher3/popup/ArrowPopup.java | 70 ++++++++++++++++++- .../popup/PopupContainerWithArrow.java | 40 +++-------- .../launcher3/shortcuts/DeepShortcutView.java | 6 -- .../launcher3/views/OptionsPopupView.java | 1 - 17 files changed, 188 insertions(+), 101 deletions(-) create mode 100644 res/drawable/middle_item_primary.xml create mode 100644 res/drawable/single_item_primary.xml create mode 100644 res/drawable/single_item_secondary.xml diff --git a/res/drawable/middle_item_primary.xml b/res/drawable/middle_item_primary.xml new file mode 100644 index 0000000000..c9757142da --- /dev/null +++ b/res/drawable/middle_item_primary.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/res/drawable/single_item_primary.xml b/res/drawable/single_item_primary.xml new file mode 100644 index 0000000000..1c0889bd23 --- /dev/null +++ b/res/drawable/single_item_primary.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/res/drawable/single_item_secondary.xml b/res/drawable/single_item_secondary.xml new file mode 100644 index 0000000000..4edc4813aa --- /dev/null +++ b/res/drawable/single_item_secondary.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml index 840a8b776d..d6b4a37dd4 100644 --- a/res/layout/deep_shortcut.xml +++ b/res/layout/deep_shortcut.xml @@ -19,6 +19,7 @@ xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="@dimen/bg_popup_item_width" android:layout_height="@dimen/bg_popup_item_height" + android:background="@drawable/middle_item_primary" android:theme="@style/PopupItem" > - - diff --git a/res/layout/longpress_options_menu.xml b/res/layout/longpress_options_menu.xml index 20bb5b81be..3898365b1c 100644 --- a/res/layout/longpress_options_menu.xml +++ b/res/layout/longpress_options_menu.xml @@ -18,7 +18,6 @@ android:id="@+id/deep_shortcuts_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="?attr/popupColorPrimary" android:clipToPadding="false" android:clipChildren="false" android:elevation="@dimen/deep_shortcuts_elevation" diff --git a/res/layout/notification_content.xml b/res/layout/notification_content.xml index d01be019eb..147aa30525 100644 --- a/res/layout/notification_content.xml +++ b/res/layout/notification_content.xml @@ -96,14 +96,6 @@ - - - \ No newline at end of file + android:layout_height="0dp" + android:layout_marginTop="@dimen/popup_margin" /> \ No newline at end of file diff --git a/res/layout/popup_container.xml b/res/layout/popup_container.xml index c73740771d..04822fd7a2 100644 --- a/res/layout/popup_container.xml +++ b/res/layout/popup_container.xml @@ -19,8 +19,15 @@ android:id="@+id/deep_shortcuts_container" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="?attr/popupColorPrimary" android:clipToPadding="false" android:clipChildren="false" android:elevation="@dimen/deep_shortcuts_elevation" - android:orientation="vertical" /> \ No newline at end of file + android:orientation="vertical"> + + \ No newline at end of file diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml index c620e2af57..68251e4d15 100644 --- a/res/layout/system_shortcut.xml +++ b/res/layout/system_shortcut.xml @@ -19,6 +19,7 @@ xmlns:launcher="http://schemas.android.com/apk/res-auto" android:layout_width="@dimen/bg_popup_item_width" android:layout_height="@dimen/bg_popup_item_height" + android:background="@drawable/middle_item_primary" android:theme="@style/PopupItem" > - - diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml index a340f4fc9d..f9922488fb 100644 --- a/res/layout/system_shortcut_icons.xml +++ b/res/layout/system_shortcut_icons.xml @@ -21,7 +21,7 @@ android:layout_height="@dimen/system_shortcut_header_height" android:orientation="horizontal" android:gravity="end|center_vertical" - android:background="?attr/popupColorSecondary" + android:background="@drawable/single_item_secondary" android:clipToPadding="true"> 2dp - 9dp - + 0dp 234dp 56dp 48dp 6dp 16dp - 36dp - 8dp + 32dp + 2dp + 100dp + 4dp + 12dp 16dp 10dp 16dp @@ -194,16 +196,14 @@ 10dp -1dp - 28dp + 26dp 2dp - 56dp - - 178dp + 52dp 24dp - + 16dp - 48dp + 56dp 48dp 12dp diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java index 0320aa3edd..d44d158010 100644 --- a/src/com/android/launcher3/notification/NotificationItemView.java +++ b/src/com/android/launcher3/notification/NotificationItemView.java @@ -21,10 +21,13 @@ import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL; import android.app.Notification; import android.content.Context; import android.graphics.Color; +import android.graphics.Outline; import android.graphics.Rect; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.ViewGroup.MarginLayoutParams; +import android.view.ViewOutlineProvider; import android.widget.TextView; import com.android.launcher3.R; @@ -43,7 +46,8 @@ public class NotificationItemView { private static final Rect sTempRect = new Rect(); private final Context mContext; - private final PopupContainerWithArrow mContainer; + private final PopupContainerWithArrow mPopupContainer; + private final ViewGroup mRootView; private final TextView mHeaderText; private final TextView mHeaderCount; @@ -53,7 +57,6 @@ public class NotificationItemView { private final View mIconView; private final View mHeader; - private final View mDivider; private View mGutter; @@ -61,8 +64,9 @@ public class NotificationItemView { private boolean mAnimatingNextIcon; private int mNotificationHeaderTextColor = Notification.COLOR_DEFAULT; - public NotificationItemView(PopupContainerWithArrow container) { - mContainer = container; + public NotificationItemView(PopupContainerWithArrow container, ViewGroup rootView) { + mPopupContainer = container; + mRootView = rootView; mContext = container.getContext(); mHeaderText = container.findViewById(R.id.notification_text); @@ -72,17 +76,25 @@ public class NotificationItemView { mIconView = container.findViewById(R.id.popup_item_icon); mHeader = container.findViewById(R.id.header); - mDivider = container.findViewById(R.id.divider); mSwipeDetector = new SingleAxisSwipeDetector(mContext, mMainView, HORIZONTAL); mSwipeDetector.setDetectableScrollConditions(SingleAxisSwipeDetector.DIRECTION_BOTH, false); mMainView.setSwipeDetector(mSwipeDetector); mFooter.setContainer(this); + + float radius = Themes.getDialogCornerRadius(mContext); + rootView.setClipToOutline(true); + rootView.setOutlineProvider(new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius); + } + }); } public void addGutter() { if (mGutter == null) { - mGutter = mContainer.inflateAndAdd(R.layout.notification_gutter, mContainer); + mGutter = mPopupContainer.inflateAndAdd(R.layout.notification_gutter, mRootView); } } @@ -94,9 +106,8 @@ public class NotificationItemView { } public void removeFooter() { - if (mContainer.indexOfChild(mFooter) >= 0) { - mContainer.removeView(mFooter); - mContainer.removeView(mDivider); + if (mRootView.indexOfChild(mFooter) >= 0) { + mRootView.removeView(mFooter); } } @@ -108,16 +119,15 @@ public class NotificationItemView { } public void removeAllViews() { - mContainer.removeView(mMainView); - mContainer.removeView(mHeader); + mRootView.removeView(mMainView); + mRootView.removeView(mHeader); - if (mContainer.indexOfChild(mFooter) >= 0) { - mContainer.removeView(mFooter); - mContainer.removeView(mDivider); + if (mRootView.indexOfChild(mFooter) >= 0) { + mRootView.removeView(mFooter); } if (mGutter != null) { - mContainer.removeView(mGutter); + mRootView.removeView(mGutter); } } @@ -136,11 +146,11 @@ public class NotificationItemView { public boolean onInterceptTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { - sTempRect.set(mMainView.getLeft(), mMainView.getTop(), - mMainView.getRight(), mMainView.getBottom()); + sTempRect.set(mRootView.getLeft(), mRootView.getTop(), + mRootView.getRight(), mRootView.getBottom()); mIgnoreTouch = !sTempRect.contains((int) ev.getX(), (int) ev.getY()); if (!mIgnoreTouch) { - mContainer.getParent().requestDisallowInterceptTouchEvent(true); + mPopupContainer.getParent().requestDisallowInterceptTouchEvent(true); } } if (mIgnoreTouch) { diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index 15915e5380..6aa98122cd 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -28,6 +28,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Outline; import android.graphics.Rect; +import android.graphics.drawable.GradientDrawable; import android.util.AttributeSet; import android.util.Pair; import android.view.Gravity; @@ -48,6 +49,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.RevealOutlineAnimation; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; @@ -75,6 +77,8 @@ public abstract class ArrowPopup extends Abstrac private final int mArrowPointRadius; private final View mArrow; + private final int mMargin; + protected boolean mIsLeftAligned; protected boolean mIsAboveIcon; private int mGravity; @@ -84,6 +88,9 @@ public abstract class ArrowPopup extends Abstrac private final Rect mStartRect = new Rect(); private final Rect mEndRect = new Rect(); + private final GradientDrawable mRoundedTop; + private final GradientDrawable mRoundedBottom; + private Runnable mOnCloseCallback = () -> { }; public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) { @@ -103,6 +110,7 @@ public abstract class ArrowPopup extends Abstrac // Initialize arrow view final Resources resources = getResources(); + mMargin = resources.getDimensionPixelSize(R.dimen.popup_margin); mArrowWidth = resources.getDimensionPixelSize(R.dimen.popup_arrow_width); mArrowHeight = resources.getDimensionPixelSize(R.dimen.popup_arrow_height); mArrow = new View(context); @@ -111,6 +119,17 @@ public abstract class ArrowPopup extends Abstrac mArrowOffsetHorizontal = resources.getDimensionPixelSize( R.dimen.popup_arrow_horizontal_center_offset) - (mArrowWidth / 2); mArrowPointRadius = resources.getDimensionPixelSize(R.dimen.popup_arrow_corner_radius); + + mRoundedTop = new GradientDrawable(); + mRoundedTop.setColor(Themes.getAttrColor(context, R.attr.popupColorPrimary)); + mRoundedTop.setCornerRadii(new float[] { mOutlineRadius, mOutlineRadius, mOutlineRadius, + mOutlineRadius, 0, 0, 0, 0}); + + mRoundedBottom = new GradientDrawable(); + mRoundedBottom.setColor(Themes.getAttrColor(context, R.attr.popupColorPrimary)); + mRoundedBottom.setCornerRadii(new float[] { 0, 0, 0, 0, mOutlineRadius, mOutlineRadius, + mOutlineRadius, mOutlineRadius}); + } public ArrowPopup(Context context, AttributeSet attrs) { @@ -153,6 +172,50 @@ public abstract class ArrowPopup extends Abstrac */ protected void onInflationComplete(boolean isReversed) { } + /** + * Set the margins and radius of backgrounds after views are properly ordered. + */ + protected void assignMarginsAndBackgrounds() { + int count = getChildCount(); + int totalVisibleShortcuts = 0; + for (int i = 0; i < count; i++) { + View view = getChildAt(i); + if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) { + totalVisibleShortcuts++; + } + } + + int numVisibleShortcut = 0; + View lastView = null; + for (int i = 0; i < count; i++) { + View view = getChildAt(i); + boolean isShortcut = view instanceof DeepShortcutView; + if (view.getVisibility() == VISIBLE) { + if (lastView != null) { + MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams(); + mlp.bottomMargin = mMargin; + } + lastView = view; + MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams(); + mlp.bottomMargin = 0; + + if (isShortcut) { + if (totalVisibleShortcuts == 1) { + view.setBackgroundResource(R.drawable.single_item_primary); + } else if (totalVisibleShortcuts > 1) { + if (numVisibleShortcut == 0) { + view.setBackground(mRoundedTop); + } else if (numVisibleShortcut == (totalVisibleShortcuts - 1)) { + view.setBackground(mRoundedBottom); + } + numVisibleShortcut++; + } + } + } + } + measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + } + /** * Shows the popup at the desired location, optionally reversing the children. * @param viewsToFlip number of views from the top to to flip in case of reverse order @@ -164,6 +227,8 @@ public abstract class ArrowPopup extends Abstrac reverseOrder(viewsToFlip); } onInflationComplete(reverseOrder); + assignMarginsAndBackgrounds(); + orientAboutObject(); if (shouldAddArrow()) { addArrow(); } @@ -176,6 +241,8 @@ public abstract class ArrowPopup extends Abstrac protected void show() { setupForDisplay(); onInflationComplete(false); + assignMarginsAndBackgrounds(); + orientAboutObject(); if (shouldAddArrow()) { addArrow(); } @@ -203,8 +270,6 @@ public abstract class ArrowPopup extends Abstrac for (int i = 0; i < count; i++) { addView(allViews.get(i)); } - - orientAboutObject(); } private int getArrowLeft() { @@ -408,6 +473,7 @@ public abstract class ArrowPopup extends Abstrac ? getResources().getInteger(R.integer.config_popupArrowOpenCloseDuration) : 0; } + private void animateOpen() { setVisibility(View.VISIBLE); diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index a1ba74703c..4087f49f8e 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -91,6 +91,7 @@ public class PopupContainerWithArrow extends Arr private BubbleTextView mOriginalIcon; private NotificationItemView mNotificationItemView; private int mNumNotifications; + private ViewGroup mNotificationContainer; private ViewGroup mSystemShortcutContainer; @@ -222,20 +223,6 @@ public class PopupContainerWithArrow extends Arr if (isReversed && mNotificationItemView != null) { mNotificationItemView.inverseGutterMargin(); } - - // Update dividers - int count = getChildCount(); - DeepShortcutView lastView = null; - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) { - if (lastView != null) { - lastView.setDividerVisibility(VISIBLE); - } - lastView = (DeepShortcutView) view; - lastView.setDividerVisibility(INVISIBLE); - } - } } @TargetApi(Build.VERSION_CODES.P) @@ -257,8 +244,12 @@ public class PopupContainerWithArrow extends Arr // Add views if (mNumNotifications > 0) { // Add notification entries - View.inflate(getContext(), R.layout.notification_content, this); - mNotificationItemView = new NotificationItemView(this); + if (mNotificationContainer == null) { + mNotificationContainer = findViewById(R.id.notification_container); + mNotificationContainer.setVisibility(VISIBLE); + } + View.inflate(getContext(), R.layout.notification_content, mNotificationContainer); + mNotificationItemView = new NotificationItemView(this, mNotificationContainer); if (mNumNotifications == 1) { mNotificationItemView.removeFooter(); } @@ -358,21 +349,6 @@ public class PopupContainerWithArrow extends Arr } } - private void updateDividers() { - int count = getChildCount(); - DeepShortcutView lastView = null; - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) { - if (lastView != null) { - lastView.setDividerVisibility(VISIBLE); - } - lastView = (DeepShortcutView) view; - lastView.setDividerVisibility(INVISIBLE); - } - } - } - private void initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) { View view = inflateAndAdd( resId, container, getInsertIndexForSystemShortcut(container, info)); @@ -592,7 +568,7 @@ public class PopupContainerWithArrow extends Arr mNotificationItemView.removeAllViews(); mNotificationItemView = null; updateHiddenShortcuts(); - updateDividers(); + assignMarginsAndBackgrounds(); } else { mNotificationItemView.trimNotifications( NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys())); diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java index e9b92e2f10..1c1418c325 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java @@ -41,7 +41,6 @@ public class DeepShortcutView extends FrameLayout { private BubbleTextView mBubbleText; private View mIconView; - private View mDivider; private WorkspaceItemInfo mInfo; private ShortcutInfo mDetail; @@ -63,11 +62,6 @@ public class DeepShortcutView extends FrameLayout { super.onFinishInflate(); mBubbleText = findViewById(R.id.bubble_text); mIconView = findViewById(R.id.icon); - mDivider = findViewById(R.id.divider); - } - - public void setDividerVisibility(int visibility) { - mDivider.setVisibility(visibility); } public BubbleTextView getBubbleText() { diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java index 1a114f3ce7..9a2db109ef 100644 --- a/src/com/android/launcher3/views/OptionsPopupView.java +++ b/src/com/android/launcher3/views/OptionsPopupView.java @@ -134,7 +134,6 @@ public class OptionsPopupView extends ArrowPopup (DeepShortcutView) popup.inflateAndAdd(R.layout.system_shortcut, popup); view.getIconView().setBackgroundResource(item.iconRes); view.getBubbleText().setText(item.labelRes); - view.setDividerVisibility(View.INVISIBLE); view.setOnClickListener(popup); view.setOnLongClickListener(popup); popup.mItemMap.put(view, item); From 7c67fafe4d2c355d3b3564bf84f8e1548281706d Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Thu, 18 Mar 2021 17:24:25 +0000 Subject: [PATCH 05/17] Respect clip hint when aligning cropped thumbnails. With clipping off, alignment will show letterbox borders. With clipping we will respect the clip hints. Test: manual Bug: 177402412 Change-Id: Ie9d2c95636f23c4f64635ac6d55eb59306c30223 --- .../quickstep/views/TaskThumbnailView.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index 17d075f6c8..2b54f95bdf 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -550,23 +550,26 @@ public class TaskThumbnailView extends View implements PluginListener Date: Tue, 2 Feb 2021 23:29:09 -0800 Subject: [PATCH 06/17] Update calls to go through the feature interface instead of sysui proxy Bug: 180074017 Test: atest PinnedStackTests Test: Verify Pip works w/ launcher (shelf offsets, autoenter, etc) Change-Id: I7de733f7267123218f6550963e44f6a893ad99b2 --- .../launcher3/QuickstepTransitionManager.java | 2 +- .../com/android/quickstep/SystemUiProxy.java | 258 ++++++++++-------- .../quickstep/TouchInteractionService.java | 24 +- .../android/quickstep/views/RecentsView.java | 23 +- 4 files changed, 178 insertions(+), 129 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 7404dee9d1..9ac2c72045 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -84,7 +84,6 @@ import com.android.quickstep.util.RemoteAnimationProvider; import com.android.quickstep.util.StaggeredWorkspaceAnim; import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.views.RecentsView; -import com.android.systemui.shared.recents.IStartingWindowListener; import com.android.systemui.shared.system.ActivityCompat; import com.android.systemui.shared.system.ActivityOptionsCompat; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; @@ -96,6 +95,7 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.RemoteTransitionCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import com.android.systemui.shared.system.WindowManagerWrapper; +import com.android.wm.shell.startingsurface.IStartingWindowListener; import java.util.LinkedHashMap; diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index a70cc4ccd2..cf71eaeeb8 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -35,12 +35,17 @@ import android.util.Log; import android.view.MotionEvent; import com.android.launcher3.util.MainThreadInitializedObject; -import com.android.systemui.shared.recents.IPinnedStackAnimationListener; -import com.android.systemui.shared.recents.ISplitScreenListener; -import com.android.systemui.shared.recents.IStartingWindowListener; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.RemoteTransitionCompat; +import com.android.wm.shell.onehanded.IOneHanded; +import com.android.wm.shell.pip.IPip; +import com.android.wm.shell.pip.IPipAnimationListener; +import com.android.wm.shell.splitscreen.ISplitScreen; +import com.android.wm.shell.splitscreen.ISplitScreenListener; +import com.android.wm.shell.startingsurface.IStartingWindow; +import com.android.wm.shell.startingsurface.IStartingWindowListener; +import com.android.wm.shell.transition.IShellTransitions; /** * Holds the reference to SystemUI. @@ -53,8 +58,13 @@ public class SystemUiProxy implements ISystemUiProxy, new MainThreadInitializedObject<>(SystemUiProxy::new); private ISystemUiProxy mSystemUiProxy; + private IPip mPip; + private ISplitScreen mSplitScreen; + private IOneHanded mOneHanded; + private IShellTransitions mShellTransitions; + private IStartingWindow mStartingWindow; private final DeathRecipient mSystemUiProxyDeathRecipient = () -> { - MAIN_EXECUTOR.execute(() -> setProxy(null)); + MAIN_EXECUTOR.execute(() -> clearProxy()); }; // Used to dedupe calls to SystemUI @@ -83,12 +93,23 @@ public class SystemUiProxy implements ISystemUiProxy, return null; } - public void setProxy(ISystemUiProxy proxy) { + public void setProxy(ISystemUiProxy proxy, IPip pip, ISplitScreen splitScreen, + IOneHanded oneHanded, IShellTransitions shellTransitions, + IStartingWindow startingWindow) { unlinkToDeath(); mSystemUiProxy = proxy; + mPip = pip; + mSplitScreen = splitScreen; + mOneHanded = oneHanded; + mShellTransitions = shellTransitions; + mStartingWindow = startingWindow; linkToDeath(); } + public void clearProxy() { + setProxy(null, null, null, null, null, null); + } + // TODO(141886704): Find a way to remove this public void setLastSystemUiStateFlags(int stateFlags) { mLastSystemUiStateFlags = stateFlags; @@ -267,21 +288,6 @@ public class SystemUiProxy implements ISystemUiProxy, } } - @Override - public void setShelfHeight(boolean visible, int shelfHeight) { - boolean changed = visible != mLastShelfVisible || shelfHeight != mLastShelfHeight; - if (mSystemUiProxy != null && changed) { - mLastShelfVisible = visible; - mLastShelfHeight = shelfHeight; - try { - mSystemUiProxy.setShelfHeight(visible, shelfHeight); - } catch (RemoteException e) { - Log.w(TAG, "Failed call setShelfHeight visible: " + visible - + " height: " + shelfHeight, e); - } - } - } - @Override public void handleImageAsScreenshot(Bitmap bitmap, Rect rect, Insets insets, int i) { if (mSystemUiProxy != null) { @@ -318,20 +324,6 @@ public class SystemUiProxy implements ISystemUiProxy, } } - /** - * Sets listener to get pinned stack animation callbacks. - */ - @Override - public void setPinnedStackAnimationListener(IPinnedStackAnimationListener listener) { - if (mSystemUiProxy != null) { - try { - mSystemUiProxy.setPinnedStackAnimationListener(listener); - } catch (RemoteException e) { - Log.w(TAG, "Failed call setPinnedStackAnimationListener", e); - } - } - } - @Override public void onQuickSwitchToNewTask(int rotation) { if (mSystemUiProxy != null) { @@ -356,28 +348,6 @@ public class SystemUiProxy implements ISystemUiProxy, } } - @Override - public void startOneHandedMode() { - if (mSystemUiProxy != null) { - try { - mSystemUiProxy.startOneHandedMode(); - } catch (RemoteException e) { - Log.w(TAG, "Failed call startOneHandedMode", e); - } - } - } - - @Override - public void stopOneHandedMode() { - if (mSystemUiProxy != null) { - try { - mSystemUiProxy.stopOneHandedMode(); - } catch (RemoteException e) { - Log.w(TAG, "Failed call stopOneHandedMode", e); - } - } - } - @Override public void expandNotificationPanel() { if (mSystemUiProxy != null) { @@ -389,12 +359,45 @@ public class SystemUiProxy implements ISystemUiProxy, } } - @Override + // + // Pip + // + + /** + * Sets the shelf height. + */ + public void setShelfHeight(boolean visible, int shelfHeight) { + boolean changed = visible != mLastShelfVisible || shelfHeight != mLastShelfHeight; + if (mPip != null && changed) { + mLastShelfVisible = visible; + mLastShelfHeight = shelfHeight; + try { + mPip.setShelfHeight(visible, shelfHeight); + } catch (RemoteException e) { + Log.w(TAG, "Failed call setShelfHeight visible: " + visible + + " height: " + shelfHeight, e); + } + } + } + + /** + * Sets listener to get pinned stack animation callbacks. + */ + public void setPinnedStackAnimationListener(IPipAnimationListener listener) { + if (mPip != null) { + try { + mPip.setPinnedStackAnimationListener(listener); + } catch (RemoteException e) { + Log.w(TAG, "Failed call setPinnedStackAnimationListener", e); + } + } + } + public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, PictureInPictureParams pictureInPictureParams, int launcherRotation, int shelfHeight) { - if (mSystemUiProxy != null) { + if (mPip != null) { try { - return mSystemUiProxy.startSwipePipToHome(componentName, activityInfo, + return mPip.startSwipePipToHome(componentName, activityInfo, pictureInPictureParams, launcherRotation, shelfHeight); } catch (RemoteException e) { Log.w(TAG, "Failed call startSwipePipToHome", e); @@ -403,111 +406,85 @@ public class SystemUiProxy implements ISystemUiProxy, return null; } - @Override public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds) { - if (mSystemUiProxy != null) { + if (mPip != null) { try { - mSystemUiProxy.stopSwipePipToHome(componentName, destinationBounds); + mPip.stopSwipePipToHome(componentName, destinationBounds); } catch (RemoteException e) { Log.w(TAG, "Failed call stopSwipePipToHome"); } } } - @Override - public void registerRemoteTransition(RemoteTransitionCompat remoteTransition) { - if (mSystemUiProxy != null) { - try { - mSystemUiProxy.registerRemoteTransition(remoteTransition); - } catch (RemoteException e) { - Log.w(TAG, "Failed call registerRemoteTransition"); - } - } - } + // + // Splitscreen + // - @Override - public void unregisterRemoteTransition(RemoteTransitionCompat remoteTransition) { - if (mSystemUiProxy != null) { - try { - mSystemUiProxy.unregisterRemoteTransition(remoteTransition); - } catch (RemoteException e) { - Log.w(TAG, "Failed call registerRemoteTransition"); - } - } - } - - @Override public void registerSplitScreenListener(ISplitScreenListener listener) { - if (mSystemUiProxy != null) { + if (mSplitScreen != null) { try { - mSystemUiProxy.registerSplitScreenListener(listener); + mSplitScreen.registerSplitScreenListener(listener); } catch (RemoteException e) { Log.w(TAG, "Failed call registerSplitScreenListener"); } } } - @Override public void unregisterSplitScreenListener(ISplitScreenListener listener) { - if (mSystemUiProxy != null) { + if (mSplitScreen != null) { try { - mSystemUiProxy.unregisterSplitScreenListener(listener); + mSplitScreen.unregisterSplitScreenListener(listener); } catch (RemoteException e) { Log.w(TAG, "Failed call unregisterSplitScreenListener"); } } } - @Override public void setSideStageVisibility(boolean visible) { - if (mSystemUiProxy != null) { + if (mSplitScreen != null) { try { - mSystemUiProxy.setSideStageVisibility(visible); + mSplitScreen.setSideStageVisibility(visible); } catch (RemoteException e) { Log.w(TAG, "Failed call setSideStageVisibility"); } } } - @Override public void exitSplitScreen() { - if (mSystemUiProxy != null) { + if (mSplitScreen != null) { try { - mSystemUiProxy.exitSplitScreen(); + mSplitScreen.exitSplitScreen(); } catch (RemoteException e) { Log.w(TAG, "Failed call exitSplitScreen"); } } } - @Override public void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) { - if (mSystemUiProxy != null) { + if (mSplitScreen != null) { try { - mSystemUiProxy.exitSplitScreenOnHide(exitSplitScreenOnHide); + mSplitScreen.exitSplitScreenOnHide(exitSplitScreenOnHide); } catch (RemoteException e) { Log.w(TAG, "Failed call exitSplitScreen"); } } } - @Override public void startTask(int taskId, int stage, int position, Bundle options) { - if (mSystemUiProxy != null) { + if (mSplitScreen != null) { try { - mSystemUiProxy.startTask(taskId, stage, position, options); + mSplitScreen.startTask(taskId, stage, position, options); } catch (RemoteException e) { Log.w(TAG, "Failed call startTask"); } } } - @Override public void startShortcut(String packageName, String shortcutId, int stage, int position, Bundle options, UserHandle user) { - if (mSystemUiProxy != null) { + if (mSplitScreen != null) { try { - mSystemUiProxy.startShortcut(packageName, shortcutId, stage, position, options, + mSplitScreen.startShortcut(packageName, shortcutId, stage, position, options, user); } catch (RemoteException e) { Log.w(TAG, "Failed call startShortcut"); @@ -515,38 +492,87 @@ public class SystemUiProxy implements ISystemUiProxy, } } - @Override - public void startIntent(PendingIntent intent, Intent fillInIntent, int stage, - int position, Bundle options) { - if (mSystemUiProxy != null) { + public void startIntent(PendingIntent intent, Intent fillInIntent, int stage, int position, + Bundle options) { + if (mSplitScreen != null) { try { - mSystemUiProxy.startIntent(intent, fillInIntent, stage, position, - options); + mSplitScreen.startIntent(intent, fillInIntent, stage, position, options); } catch (RemoteException e) { Log.w(TAG, "Failed call startIntent"); } } } - @Override public void removeFromSideStage(int taskId) { - if (mSystemUiProxy != null) { + if (mSplitScreen != null) { try { - mSystemUiProxy.removeFromSideStage(taskId); + mSplitScreen.removeFromSideStage(taskId); } catch (RemoteException e) { Log.w(TAG, "Failed call removeFromSideStage"); } } } + // + // One handed + // + + public void startOneHandedMode() { + if (mOneHanded != null) { + try { + mOneHanded.startOneHanded(); + } catch (RemoteException e) { + Log.w(TAG, "Failed call startOneHandedMode", e); + } + } + } + + public void stopOneHandedMode() { + if (mOneHanded != null) { + try { + mOneHanded.stopOneHanded(); + } catch (RemoteException e) { + Log.w(TAG, "Failed call stopOneHandedMode", e); + } + } + } + + // + // Remote transitions + // + + public void registerRemoteTransition(RemoteTransitionCompat remoteTransition) { + if (mShellTransitions != null) { + try { + mShellTransitions.registerRemote(remoteTransition.getFilter(), + remoteTransition.getTransition()); + } catch (RemoteException e) { + Log.w(TAG, "Failed call registerRemoteTransition"); + } + } + } + + public void unregisterRemoteTransition(RemoteTransitionCompat remoteTransition) { + if (mShellTransitions != null) { + try { + mShellTransitions.unregisterRemote(remoteTransition.getTransition()); + } catch (RemoteException e) { + Log.w(TAG, "Failed call registerRemoteTransition"); + } + } + } + + // + // Starting window + // + /** * Sets listener to get callbacks when launching a task. */ - @Override public void setStartingWindowListener(IStartingWindowListener listener) { - if (mSystemUiProxy != null) { + if (mStartingWindow != null) { try { - mSystemUiProxy.setStartingWindowListener(listener); + mStartingWindow.setStartingWindowListener(listener); } catch (RemoteException e) { Log.w(TAG, "Failed call setStartingWindowListener", e); } diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 8e6f663bed..4747f1898d 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -25,6 +25,11 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.quickstep.GestureState.DEFAULT_STATE; import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; +import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_ONE_HANDED; +import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_PIP; +import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SHELL_TRANSITIONS; +import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SPLIT_SCREEN; +import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_STARTING_WINDOW; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED; @@ -102,6 +107,11 @@ import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.tracing.ProtoTraceable; +import com.android.wm.shell.onehanded.IOneHanded; +import com.android.wm.shell.pip.IPip; +import com.android.wm.shell.splitscreen.ISplitScreen; +import com.android.wm.shell.startingsurface.IStartingWindow; +import com.android.wm.shell.transition.IShellTransitions; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -141,8 +151,18 @@ public class TouchInteractionService extends Service implements PluginListener { - SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy); + SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy, pip, + splitscreen, onehanded, shellTransitions, startingWindow); TouchInteractionService.this.initInputMonitor(); preloadOverview(true /* fromInit */); mDeviceState.runOnUserUnlocked(() -> { @@ -432,7 +452,7 @@ public class TouchInteractionService extends Service implements PluginListener extends PagedView } }; - private final PinnedStackAnimationListener mIPinnedStackAnimationListener = + private final PinnedStackAnimationListener mIPipAnimationListener = new PinnedStackAnimationListener(); // Used to keep track of the last requested task list id, so that we do not request to load the @@ -653,9 +654,9 @@ public abstract class RecentsView extends PagedView mLiveTileParams.setSyncTransactionApplier(mSyncTransactionApplier); RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this); mIdp.addOnChangeListener(this); - mIPinnedStackAnimationListener.setActivity(mActivity); + mIPipAnimationListener.setActivity(mActivity); SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener( - mIPinnedStackAnimationListener); + mIPipAnimationListener); mOrientationState.initListeners(); SplitScreenBounds.INSTANCE.addOnChangeListener(this); mTaskOverlayFactory.initListeners(); @@ -674,7 +675,7 @@ public abstract class RecentsView extends PagedView mIdp.removeOnChangeListener(this); SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null); SplitScreenBounds.INSTANCE.removeOnChangeListener(this); - mIPinnedStackAnimationListener.setActivity(null); + mIPipAnimationListener.setActivity(null); mOrientationState.destroyListeners(); mTaskOverlayFactory.removeListeners(); } @@ -3133,7 +3134,7 @@ public abstract class RecentsView extends PagedView } private static class PinnedStackAnimationListener extends - IPinnedStackAnimationListener.Stub { + IPipAnimationListener.Stub { private T mActivity; public void setActivity(T activity) { @@ -3141,10 +3142,12 @@ public abstract class RecentsView extends PagedView } @Override - public void onPinnedStackAnimationStarted() { - // Needed for activities that auto-enter PiP, which will not trigger a remote - // animation to be created - mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS); + public void onPipAnimationStarted() { + MAIN_EXECUTOR.execute(() -> { + // Needed for activities that auto-enter PiP, which will not trigger a remote + // animation to be created + mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS); + }); } } } From e6354c1ab22cec56b3344c0e52a1380883272f3b Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Thu, 18 Mar 2021 19:22:00 +0000 Subject: [PATCH 07/17] Revert "[Live tile] Finish recents animation when the phone goes to sleep in live tile mode" This reverts commit d028937e74a9ea6d36e463de4c87ed37283bbdf6. Reason for revert: Caused a few bugs Change-Id: I1a3f4aa90679dec18ed27d2a5a5f0446c6d52594 Fixes: 174866547 Fixes: 181937887 Fixes: 183124957 --- quickstep/src/com/android/quickstep/views/RecentsView.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index ce97fdcba5..882241ebbe 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -614,9 +614,6 @@ public abstract class RecentsView extends PagedView @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); - if (visibility != VISIBLE && LIVE_TILE.get()) { - finishRecentsAnimation(true /* toRecents */, null); - } updateTaskStackListenerState(); } From b31d8fc379a429d082422151ed5e20b8d72c50a3 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Thu, 18 Mar 2021 13:57:20 -0700 Subject: [PATCH 08/17] Use taskbarSize as bottom inset when taskbar is present. This was done in ag/13841736 but not included in ag/13821586 Test: QSB in correct position when taskbar present and not present Bug: 171917176 Change-Id: I6aa220559afebe8710b5f01cdec9c2baa9f4c926 --- .../src/com/android/launcher3/taskbar/TaskbarController.java | 2 +- src/com/android/launcher3/Hotseat.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java index a2b2ddd5dd..f652961629 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java @@ -472,7 +472,7 @@ public class TaskbarController { public void alignRealHotseatWithTaskbar() { Rect hotseatBounds = new Rect(); DeviceProfile grid = mLauncher.getDeviceProfile(); - int hotseatHeight = grid.workspacePadding.bottom + grid.getInsets().bottom; + int hotseatHeight = grid.workspacePadding.bottom + grid.taskbarSize; int hotseatTopDiff = hotseatHeight - grid.taskbarSize; mTaskbarView.getHotseatBoundsAtScale(getTaskbarScaleOnHome()).roundOut(hotseatBounds); diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 0e9de45e2f..5007d0d450 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -123,7 +123,7 @@ public class Hotseat extends CellLayout implements Insettable { lp.height = (grid.isTaskbarPresent ? grid.workspacePadding.bottom : grid.hotseatBarSizePx) - + insets.bottom; + + (grid.isTaskbarPresent ? grid.taskbarSize : insets.bottom); } if (!grid.isTaskbarPresent) { @@ -214,7 +214,7 @@ public class Hotseat extends CellLayout implements Insettable { : dp.hotseatBarSizePx - dp.hotseatCellHeightPx - mQsbHeight; int bottom = b - t - (int) (freeSpace * QSB_CENTER_FACTOR) - - dp.getInsets().bottom; + - (dp.isTaskbarPresent ? dp.taskbarSize : dp.getInsets().bottom); int top = bottom - mQsbHeight; mQsb.layout(left, top, right, bottom); } From 6f98e1ebd0133f069cad0098126e75beb352eaa0 Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Thu, 18 Mar 2021 22:00:51 +0000 Subject: [PATCH 09/17] Notify WidgetHostView drag content change only at onDraw Reapply RemoteViews can happen asynchronously. RemoteViews may not finish reinflation right after setColorResource. Let's call it onDraw. Test: Manual Bug: 182282587 Change-Id: I3653b4c64a5897637181f61096464b75945ab5f5 --- .../launcher3/widget/LauncherAppWidgetHostView.java | 7 ++++++- .../widget/dragndrop/AppWidgetHostViewDragListener.java | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index 8df70fbf3a..5c18faf213 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -19,6 +19,7 @@ package com.android.launcher3.widget; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.res.Configuration; +import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.RectF; import android.os.Handler; @@ -120,8 +121,12 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView } else { super.setColorResources(colors); } + } - if (mDragListener != null) { + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (mIsInDragMode && mDragListener != null) { mDragListener.onDragContentChanged(); } } diff --git a/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java b/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java index c5e6fbd827..66bb363dde 100644 --- a/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java +++ b/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java @@ -54,6 +54,8 @@ public final class AppWidgetHostViewDragListener implements DragController.DragL /** Notifies when there is a content change in the drag view. */ public void onDragContentChanged() { - mDragObject.dragView.invalidate(); + if (mDragObject.dragView != null) { + mDragObject.dragView.invalidate(); + } } } From a8bbcb9c0401bfa1dbc5c68d8be4d5b59e82a02f Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 18 Mar 2021 15:48:04 -0700 Subject: [PATCH 10/17] Fixing ActivityInit getting called before the full launcher components are initialized Bug: 182575999 Test: Presubmit Change-Id: Iea6986624b70caf2d502c1b21318b57a8b2fde03 --- .../src/com/android/launcher3/BaseQuickstepLauncher.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index 20a645e996..c4becf105f 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -95,9 +95,6 @@ public abstract class BaseQuickstepLauncher extends Launcher @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mAppTransitionManager = new QuickstepTransitionManager(this); - mAppTransitionManager.registerRemoteAnimations(); - SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this); addMultiWindowModeChangedListener(mDepthController); } @@ -225,6 +222,9 @@ public abstract class BaseQuickstepLauncher extends Launcher overviewPanel.init(mActionsView, splitPlaceholderView); mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this)); + mAppTransitionManager = new QuickstepTransitionManager(this); + mAppTransitionManager.registerRemoteAnimations(); + addTaskbarIfNecessary(); addOnDeviceProfileChangeListener(newDp -> addTaskbarIfNecessary()); } From cc505b8ae4eb921ab98583997869057a6c540d2d Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Thu, 18 Mar 2021 23:04:35 +0000 Subject: [PATCH 11/17] Don't store Launcher as a class variable in CellLayout CellLayout can be used by non launcher context, e.g. style & wallpaper preview. To be safe, don't store Launcher as class variable. Test: Preview in style & wallpaper works fine Drag icons from hotseat. Drag widgets from workspace. Bug: b/182282587 Change-Id: I9358eebce66ff1a46adbfb0602ae2bc970a921a6 --- src/com/android/launcher3/CellLayout.java | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index cc4bfe8c74..9df8d44d58 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -181,8 +181,6 @@ public class CellLayout extends ViewGroup { private final ArrayList mIntersectingViews = new ArrayList<>(); private final Rect mOccupiedRect = new Rect(); private final int[] mDirectionVector = new int[2]; - private final Workspace mWorkspace; - private final DeviceProfile mDeviceProfile; final int[] mPreviousReorderDirection = new int[2]; private static final int INVALID_DIRECTION = -100; @@ -213,15 +211,14 @@ public class CellLayout extends ViewGroup { setWillNotDraw(false); setClipToPadding(false); mActivity = ActivityContext.lookupContext(context); - mWorkspace = Launcher.cast(mActivity).getWorkspace(); - mDeviceProfile = mActivity.getDeviceProfile(); + DeviceProfile deviceProfile = mActivity.getDeviceProfile(); - mBorderSpacing = mDeviceProfile.cellLayoutBorderSpacingPx; + mBorderSpacing = deviceProfile.cellLayoutBorderSpacingPx; mCellWidth = mCellHeight = -1; mFixedCellWidth = mFixedCellHeight = -1; - mCountX = mDeviceProfile.inv.numColumns; - mCountY = mDeviceProfile.inv.numRows; + mCountX = deviceProfile.inv.numColumns; + mCountY = deviceProfile.inv.numRows; mOccupied = new GridOccupancy(mCountX, mCountY); mTmpOccupied = new GridOccupancy(mCountX, mCountY); @@ -238,7 +235,7 @@ public class CellLayout extends ViewGroup { mBackground.setCallback(this); mBackground.setAlpha(0); - mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * mDeviceProfile.iconSizePx); + mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * deviceProfile.iconSizePx); // Initialize the data structures used for the drag visualization. mEaseOutInterpolator = Interpolators.DEACCEL_2_5; // Quint ease out @@ -1024,8 +1021,10 @@ public class CellLayout extends ViewGroup { // Apply local extracted color if the DragView is an AppWidgetHostViewDrawable. Drawable drawable = dragObject.dragView.getDrawable(); if (drawable instanceof AppWidgetHostViewDrawable) { - int screenId = mWorkspace.getIdForScreen(this); - int pageId = mWorkspace.getPageIndexForScreenId(screenId); + Workspace workspace = + Launcher.getLauncher(dragObject.dragView.getContext()).getWorkspace(); + int screenId = workspace.getIdForScreen(this); + int pageId = workspace.getPageIndexForScreenId(screenId); AppWidgetHostViewDrawable hostViewDrawable = ((AppWidgetHostViewDrawable) drawable); cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect); hostViewDrawable.getAppWidgetHostView().handleDrag(mTempRect, pageId); @@ -2097,7 +2096,7 @@ public class CellLayout extends ViewGroup { private void commitTempPlacement() { mTmpOccupied.copyTo(mOccupied); - int screenId = mWorkspace.getIdForScreen(this); + int screenId = Launcher.cast(mActivity).getWorkspace().getIdForScreen(this); int container = Favorites.CONTAINER_DESKTOP; if (mContainerType == HOTSEAT) { From 8eb1f73d58166684a141e440781fcec4dc9317da Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Thu, 18 Mar 2021 14:59:18 +0000 Subject: [PATCH 12/17] A11y fix for all widgets tray (Part 1 / n) Mark some image view unimportant for accessibility. Still need to update the content description for widget list header to describe the expand / collapse action. Test: Navigate all widgets tray with talkback enabled. Bug: 183120145 Change-Id: I1801d8351ac7f22a0135a96a36de706377781b31 --- res/layout/widget_cell_content.xml | 1 + res/layout/widgets_full_sheet_paged_view.xml | 9 ++++----- res/layout/widgets_list_row_header.xml | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/res/layout/widget_cell_content.xml b/res/layout/widget_cell_content.xml index 50908a49ba..7b85d9bcd5 100644 --- a/res/layout/widget_cell_content.xml +++ b/res/layout/widget_cell_content.xml @@ -24,6 +24,7 @@ android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" + android:importantForAccessibility="no" android:layout_marginVertical="8dp" /> diff --git a/res/layout/widgets_full_sheet_paged_view.xml b/res/layout/widgets_full_sheet_paged_view.xml index 8125db8333..ae877d46bf 100644 --- a/res/layout/widgets_full_sheet_paged_view.xml +++ b/res/layout/widgets_full_sheet_paged_view.xml @@ -16,11 +16,6 @@ - - + \ No newline at end of file diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml index 62345b39a6..ed3a042148 100644 --- a/res/layout/widgets_list_row_header.xml +++ b/res/layout/widgets_list_row_header.xml @@ -71,6 +71,7 @@ android:layout_gravity="center_vertical" android:layout_alignParentEnd="true" android:clickable="false" + android:importantForAccessibility="no" android:button="@drawable/widgets_tray_expand_button"/> \ No newline at end of file From 72c15ef913f3b0ee11e523a9b2c523841d8e8c10 Mon Sep 17 00:00:00 2001 From: Tony Wickham Date: Thu, 18 Mar 2021 18:04:02 -0700 Subject: [PATCH 13/17] Fix QSB and Hotseat positions when ENABLE_DEVICE_SEARCH is enabled Test: visual Change-Id: I755de7552e2bb3f927f6be59c07f910ddfbc4650 --- src/com/android/launcher3/Hotseat.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 0e9de45e2f..a3e01a98b9 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -29,7 +29,6 @@ import android.widget.FrameLayout; import androidx.annotation.Nullable; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.MultiValueAlpha; import java.util.function.Consumer; @@ -96,7 +95,7 @@ public class Hotseat extends CellLayout implements Insettable { if (hasVerticalHotseat) { setGridSize(1, idp.numHotseatIcons); } else { - setGridSize(idp.numHotseatIcons, FeatureFlags.ENABLE_DEVICE_SEARCH.get() ? 2 : 1); + setGridSize(idp.numHotseatIcons, 1); } showInlineQsb(); } @@ -130,11 +129,7 @@ public class Hotseat extends CellLayout implements Insettable { // When taskbar is present, we set the padding separately to ensure a seamless visual // handoff between taskbar and hotseat during drag and drop. Rect padding = grid.getHotseatLayoutPadding(); - int paddingBottom = padding.bottom; - if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && !grid.isVerticalBarLayout()) { - paddingBottom -= grid.hotseatBarBottomPaddingPx; - } - setPadding(padding.left, padding.top, padding.right, paddingBottom); + setPadding(padding.left, padding.top, padding.right, padding.bottom); } setLayoutParams(lp); From 8dbf38e30f67ce913de247bd5a4e2ead801623a1 Mon Sep 17 00:00:00 2001 From: Sreyas Date: Wed, 17 Mar 2021 14:33:30 -0700 Subject: [PATCH 14/17] Fixes OverviewActionsView height sizing. By fixing the action buttons container height and allowing wrap content on overviewActionsView all views have enough room to be displayed and actions button container height can be calculated. Bug: 182854439 Test: Manual Change-Id: I34516ba42430d8fe6774e10215dd8ac1127920c8 --- .../res/layout/overview_actions_container.xml | 6 +++--- .../res/layout/overview_actions_container.xml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/quickstep/overview_ui_overrides/res/layout/overview_actions_container.xml b/go/quickstep/overview_ui_overrides/res/layout/overview_actions_container.xml index b438da32eb..e6af84868e 100644 --- a/go/quickstep/overview_ui_overrides/res/layout/overview_actions_container.xml +++ b/go/quickstep/overview_ui_overrides/res/layout/overview_actions_container.xml @@ -17,14 +17,14 @@ Date: Mon, 8 Feb 2021 14:32:00 -0800 Subject: [PATCH 15/17] Return empty, not null, a11y node in Workspace It's not valid to return a null accessbilitynode. Test: local Bug: 182529089 Change-Id: I94245fb33128c68e33ce388284f64e5ac3bb23dc --- src/com/android/launcher3/Workspace.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index c84724ff90..6a16da9cf9 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -1455,7 +1455,7 @@ public class Workspace extends PagedView // TAPL can work only if UIDevice is set up as setCompressedLayoutHeirarchy(false). // Hiding workspace from the tests when it's // IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS. - return null; + return AccessibilityNodeInfo.obtain(); } return super.createAccessibilityNodeInfo(); } From c4f3f49805ec03b7e115ab8e4ca4117e44fadc97 Mon Sep 17 00:00:00 2001 From: Alina Zaidi Date: Fri, 19 Mar 2021 14:22:43 +0000 Subject: [PATCH 16/17] Fix bugs for Widgets picker Search UI. - On orientation change, clear search bar. - Change text and search bar color to make similar to mocks/ all apps search bar. - Fix search recycler view visual bugs. - If back is pressed in search mode, exit search mode instead of exiting widget picker. Test: Manually seen widget picker on phone. Bug: 183103133 Bug: 183103936 Bug: 183115050 Bug: 157286785 Change-Id: I056f089eada84d00133038f4a3d7b18bc51be564 --- res/drawable/bg_widgets_searchbox.xml | 2 +- res/layout/widgets_search_bar.xml | 5 ++++- .../widget/picker/WidgetsFullSheet.java | 21 +++++++++++++++++++ .../search/LauncherWidgetsSearchBar.java | 5 +++++ .../picker/search/WidgetsSearchBar.java | 5 +++++ 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/res/drawable/bg_widgets_searchbox.xml b/res/drawable/bg_widgets_searchbox.xml index 81dd2aa0c6..2a50a51fae 100644 --- a/res/drawable/bg_widgets_searchbox.xml +++ b/res/drawable/bg_widgets_searchbox.xml @@ -14,6 +14,6 @@ limitations under the License. --> - + \ No newline at end of file diff --git a/res/layout/widgets_search_bar.xml b/res/layout/widgets_search_bar.xml index cf693bbd1d..021058b65d 100644 --- a/res/layout/widgets_search_bar.xml +++ b/res/layout/widgets_search_bar.xml @@ -19,12 +19,15 @@ android:hint="@string/widgets_full_sheet_search_bar_hint" android:maxLines="1" android:layout_weight="1" - android:inputType="text"/> + android:inputType="text" + android:textColor="?android:attr/textColorSecondary" + android:textColorHint="?android:attr/textColorTertiary"/> allWidgets, SearchModeListener searchModeListener); + /** + * Clears search bar. + */ + void reset(); + /** * Sets the vertical location, in pixels, of this search bar relative to its top position. */ From b0b2a9acd0db64d6af130db6e6d41cd74c871985 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 24 Feb 2021 13:58:35 -0800 Subject: [PATCH 17/17] Continue receiving key events from input consumer after settling into Overview This builds on ag/13732971. In live tile mode after settling into overview, recents_animation_input_consumer should have the focus, and thus we will need to extend the lifecycle of input consumers so that key events can be routed to launcher Overall, since live tile extends the lifecycle of certain private variables of AbsSwipeHandler, I am thinking of doing a refactor by putting those things into a separate class, but it might be too big for this change. TODO: I've verified that this change works while if we don't process motion events, it would cause b/182932863. Will investigate on that. Fixes: 181404912 Test: Cherry pick ag/13732971; Go to overview; Swipe back; Observe the animation to go back to app Change-Id: I5afd397be387b75f373442781dd1d00560dca99e --- .../src/com/android/quickstep/AbsSwipeUpHandler.java | 7 ++++++- .../com/android/quickstep/TaskAnimationManager.java | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 6da2201dc9..30945007a9 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -1334,7 +1334,11 @@ public abstract class AbsSwipeUpHandler, } private void invalidateHandler() { - mInputConsumerProxy.destroy(); + if (!LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode() + || mGestureState.getEndTarget() != RECENTS) { + mInputConsumerProxy.destroy(); + mTaskAnimationManager.setLiveTileCleanUpHandler(null); + } endRunningWindowAnim(false /* cancel */); if (mGestureEndCallback != null) { @@ -1526,6 +1530,7 @@ public abstract class AbsSwipeUpHandler, apps[apps.length - 1] = appearedTaskTarget; launchOtherTaskInLiveTileMode(appearedTaskTarget.taskId, apps); }); + mTaskAnimationManager.setLiveTileCleanUpHandler(mInputConsumerProxy::destroy); ActivityManagerWrapper.getInstance().registerTaskStackListener( mLiveTileRestartListener); } diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index 02c27636fc..9a454f2bd7 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -50,6 +50,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn private GestureState mLastGestureState; private RemoteAnimationTargetCompat mLastAppearedTaskTarget; private Consumer mLaunchOtherTaskHandler; + private Runnable mLiveTileCleanUpHandler; private Context mCtx; TaskAnimationManager(Context ctx) { @@ -169,6 +170,10 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn mLaunchOtherTaskHandler = handler; } + public void setLiveTileCleanUpHandler(Runnable runnable) { + mLiveTileCleanUpHandler = runnable; + } + /** * Finishes the running recents animation. */ @@ -206,6 +211,11 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn * Cleans up the recents animation entirely. */ private void cleanUpRecentsAnimation() { + if (mLiveTileCleanUpHandler != null) { + mLiveTileCleanUpHandler.run(); + mLiveTileCleanUpHandler = null; + } + // Release all the target leashes if (mTargets != null) { mTargets.release();