From edd5f77c51f58dd923e4bbff1b86171bfeb501da Mon Sep 17 00:00:00 2001 From: My Name Date: Tue, 2 Nov 2021 12:22:58 +0000 Subject: [PATCH 1/8] Sending broadcast message when home screen is ready. There is a lag between Pixel/Phone is starting message is displayed and when the home screen is actually ready. The lag is visible in low-end devices like JioPhone Next. To solve that a broadcast message is sent from QuickstepLauncher class when the UI is ready. Bug: 199120420 Test: manual - tested on the device Change-Id: I18628552a1513454127ef2f8ad5acd711d9015e6 --- .../launcher3/uioverrides/QuickstepLauncher.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 9050ddc511..72195a0512 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -68,9 +68,11 @@ import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchControll import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController; import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController; import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController; +import com.android.launcher3.util.IntSet; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.OnboardingPrefs; import com.android.launcher3.util.PendingRequestArgs; +import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.UiThreadHelper; import com.android.launcher3.util.UiThreadHelper.AsyncCommand; @@ -91,6 +93,8 @@ import java.util.stream.Stream; public class QuickstepLauncher extends BaseQuickstepLauncher { + public static final String HOME_IS_READY = "com.android.launcher3.HOME_IS_READY"; + public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false; /** * Reusable command for applying the shelf height on the background thread. @@ -231,6 +235,12 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } + @Override + public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) { + super.onInitialBindComplete(boundPages, pendingTasks); + sendBroadcast(new Intent(HOME_IS_READY).setPackage("com.android.settings")); + } + @Override public void bindExtraContainerItems(FixedContainerItems item) { if (item.containerId == Favorites.CONTAINER_PREDICTION) { From f957244b889faafc23d6bd03f5f1f46f43527a09 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Thu, 18 Nov 2021 17:42:35 -0800 Subject: [PATCH 2/8] Show multiple App Info A11y options for split app icons * AccessibilityNode actions are required to have a unique resourceId to show as an action in A11y dialog. For now, only AppInfo option is shown for each app in split, but moving forward we'll need to add resourceIDs for each option that can show up for either app. Fixes: 200609838 Test: Saw multiple options for App Info for each app come up in talkback mode Change-Id: I92b349347354ac639537021d775eea814c866a0e --- .../quickstep/TaskShortcutFactory.java | 8 ++- .../com/android/quickstep/views/TaskView.java | 39 ++++++++++----- res/values/id.xml | 4 ++ res/values/strings.xml | 7 +-- .../launcher3/popup/SystemShortcut.java | 49 ++++++++++++++++++- 5 files changed, 90 insertions(+), 17 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java index 8c4ba97c07..cbdbdb5571 100644 --- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java +++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java @@ -72,7 +72,13 @@ public interface TaskShortcutFactory { @Override public SystemShortcut getShortcut(BaseDraggingActivity activity, TaskIdAttributeContainer taskContainer) { - return new AppInfo(activity, taskContainer.getItemInfo()); + TaskView taskView = taskContainer.getTaskView(); + AppInfo.SplitAccessibilityInfo accessibilityInfo = + new AppInfo.SplitAccessibilityInfo(taskView.containsMultipleTasks(), + TaskUtils.getTitle(taskView.getContext(), taskContainer.getTask()), + taskContainer.getA11yNodeId() + ); + return new AppInfo(activity, taskContainer.getItemInfo(), accessibilityInfo); } @Override diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 67128f01fe..f4944a642a 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -30,6 +30,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; +import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -38,6 +39,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; +import android.annotation.IdRes; import android.app.ActivityOptions; import android.content.Context; import android.content.Intent; @@ -1300,10 +1302,14 @@ public class TaskView extends FrameLayout implements Reusable { getContext().getText(R.string.accessibility_close))); final Context context = getContext(); - // TODO(b/200609838) Determine which task to run A11y action on when in split screen - for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this, - mActivity.getDeviceProfile(), mTaskIdAttributeContainer[0])) { - info.addAction(s.createAccessibilityAction(context)); + for (TaskIdAttributeContainer taskContainer : mTaskIdAttributeContainer) { + if (taskContainer == null) { + continue; + } + for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this, + mActivity.getDeviceProfile(), taskContainer)) { + info.addAction(s.createAccessibilityAction(context)); + } } if (mDigitalWellBeingToast.hasLimit()) { @@ -1334,12 +1340,16 @@ public class TaskView extends FrameLayout implements Reusable { return true; } - // TODO(b/200609838) Determine which task to run A11y action on when in split screen - for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this, - mActivity.getDeviceProfile(), mTaskIdAttributeContainer[0])) { - if (s.hasHandlerForAction(action)) { - s.onClick(this); - return true; + for (TaskIdAttributeContainer taskContainer : mTaskIdAttributeContainer) { + if (taskContainer == null) { + continue; + } + for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this, + mActivity.getDeviceProfile(), taskContainer)) { + if (s.hasHandlerForAction(action)) { + s.onClick(this); + return true; + } } } @@ -1556,7 +1566,6 @@ public class TaskView extends FrameLayout implements Reusable { mScale = previewWidth / (previewWidth + currentInsetsLeft + currentInsetsRight); } } - } public class TaskIdAttributeContainer { @@ -1564,12 +1573,16 @@ public class TaskView extends FrameLayout implements Reusable { private final Task mTask; /** Defaults to STAGE_POSITION_UNDEFINED if in not a split screen task view */ private @SplitConfigurationOptions.StagePosition int mStagePosition; + @IdRes + private final int mA11yNodeId; public TaskIdAttributeContainer(Task task, TaskThumbnailView thumbnailView, int stagePosition) { this.mTask = task; this.mThumbnailView = thumbnailView; this.mStagePosition = stagePosition; + this.mA11yNodeId = (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) ? + R.id.split_bottomRight_appInfo : R.id.split_topLeft_appInfo; } public TaskThumbnailView getThumbnailView() { @@ -1595,5 +1608,9 @@ public class TaskView extends FrameLayout implements Reusable { void setStagePosition(@SplitConfigurationOptions.StagePosition int stagePosition) { this.mStagePosition = stagePosition; } + + public int getA11yNodeId() { + return mA11yNodeId; + } } } diff --git a/res/values/id.xml b/res/values/id.xml index ebc4075214..508caffd48 100644 --- a/res/values/id.xml +++ b/res/values/id.xml @@ -21,6 +21,10 @@ + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 5f53d4e24a..868b5f39b8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -40,9 +40,10 @@ Split screen - Split top - Split left - Split right + Split top + Split left + Split right + App info for %1$s diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java index 826c79b289..af872750a0 100644 --- a/src/com/android/launcher3/popup/SystemShortcut.java +++ b/src/com/android/launcher3/popup/SystemShortcut.java @@ -41,8 +41,8 @@ public abstract class SystemShortcut extend implements View.OnClickListener { private final int mIconResId; - private final int mLabelResId; - private final int mAccessibilityActionId; + protected final int mLabelResId; + protected int mAccessibilityActionId; protected final T mTarget; protected final ItemInfo mItemInfo; @@ -139,11 +139,43 @@ public abstract class SystemShortcut extend public static class AppInfo extends SystemShortcut { + @Nullable + private SplitAccessibilityInfo mSplitA11yInfo; + public AppInfo(T target, ItemInfo itemInfo) { super(R.drawable.ic_info_no_shadow, R.string.app_info_drop_target_label, target, itemInfo); } + /** + * Constructor used by overview for staged split to provide custom A11y information. + * + * Future improvements considerations: + * Have the logic in {@link #createAccessibilityAction(Context)} be moved to super + * call in {@link SystemShortcut#createAccessibilityAction(Context)} by having + * SystemShortcut be aware of TaskContainers and staged split. + * That way it could directly create the correct node info for any shortcut that supports + * split, but then we'll need custom resIDs for each pair of shortcuts. + */ + public AppInfo(T target, ItemInfo itemInfo, SplitAccessibilityInfo accessibilityInfo) { + this(target, itemInfo); + mSplitA11yInfo = accessibilityInfo; + mAccessibilityActionId = accessibilityInfo.nodeId; + } + + @Override + public AccessibilityNodeInfo.AccessibilityAction createAccessibilityAction( + Context context) { + if (mSplitA11yInfo != null && mSplitA11yInfo.containsMultipleTasks) { + String accessibilityLabel = context.getString(R.string.split_app_info_accessibility, + mSplitA11yInfo.taskTitle); + return new AccessibilityNodeInfo.AccessibilityAction(mAccessibilityActionId, + accessibilityLabel); + } else { + return super.createAccessibilityAction(context); + } + } + @Override public void onClick(View view) { dismissTaskMenuView(mTarget); @@ -153,6 +185,19 @@ public abstract class SystemShortcut extend mTarget.getStatsLogManager().logger().withItemInfo(mItemInfo) .log(LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP); } + + public static class SplitAccessibilityInfo { + public final boolean containsMultipleTasks; + public final CharSequence taskTitle; + public final int nodeId; + + public SplitAccessibilityInfo(boolean containsMultipleTasks, + CharSequence taskTitle, int nodeId) { + this.containsMultipleTasks = containsMultipleTasks; + this.taskTitle = taskTitle; + this.nodeId = nodeId; + } + } } public static final Factory INSTALL = (activity, itemInfo) -> { From e2074f01c06e1a4655cc095ea112a3553d48eade Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Sat, 20 Nov 2021 00:58:43 +0000 Subject: [PATCH 3/8] Skip scheduling frame callback if view root is already detached - Also remove references to deprecrated compat class Bug: 206932656 Test: Presubmit Change-Id: I1add65b0fe03dedea872d162e51095bf9c648acf --- quickstep/src/com/android/quickstep/ViewUtils.java | 12 +++++++----- .../quickstep/util/SurfaceTransactionApplier.java | 10 +++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/quickstep/ViewUtils.java b/quickstep/src/com/android/quickstep/ViewUtils.java index 184ab17ae2..e290be8e33 100644 --- a/quickstep/src/com/android/quickstep/ViewUtils.java +++ b/quickstep/src/com/android/quickstep/ViewUtils.java @@ -15,8 +15,10 @@ */ package com.android.quickstep; +import android.graphics.HardwareRenderer; import android.os.Handler; import android.view.View; +import android.view.ViewRootImpl; import com.android.launcher3.Utilities; import com.android.systemui.shared.system.ViewRootImplCompat; @@ -45,9 +47,9 @@ public class ViewUtils { return new FrameHandler(view, onFinishRunnable, canceled).schedule(); } - private static class FrameHandler implements LongConsumer { + private static class FrameHandler implements HardwareRenderer.FrameDrawingCallback { - final ViewRootImplCompat mViewRoot; + final ViewRootImpl mViewRoot; final Runnable mFinishCallback; final BooleanSupplier mCancelled; final Handler mHandler; @@ -55,14 +57,14 @@ public class ViewUtils { int mDeferFrameCount = 1; FrameHandler(View view, Runnable finishCallback, BooleanSupplier cancelled) { - mViewRoot = new ViewRootImplCompat(view); + mViewRoot = view.getViewRootImpl(); mFinishCallback = finishCallback; mCancelled = cancelled; mHandler = new Handler(); } @Override - public void accept(long l) { + public void onFrameDraw(long frame) { Utilities.postAsyncCallback(mHandler, this::onFrame); } @@ -83,7 +85,7 @@ public class ViewUtils { } private boolean schedule() { - if (mViewRoot.isValid()) { + if (mViewRoot.getView() != null) { mViewRoot.registerRtFrameCallback(this); mViewRoot.getView().invalidate(); return true; diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java index 3b4fd31fa5..3b1c150563 100644 --- a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java +++ b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java @@ -22,10 +22,10 @@ import android.os.Message; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.View; +import android.view.ViewRootImpl; import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; -import com.android.systemui.shared.system.ViewRootImplCompat; import java.util.function.Consumer; @@ -41,7 +41,7 @@ public class SurfaceTransactionApplier extends ReleaseCheck { private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0; private final SurfaceControl mBarrierSurfaceControl; - private final ViewRootImplCompat mTargetViewRootImpl; + private final ViewRootImpl mTargetViewRootImpl; private final Handler mApplyHandler; private int mLastSequenceNumber = 0; @@ -50,8 +50,8 @@ public class SurfaceTransactionApplier extends ReleaseCheck { * @param targetView The view in the surface that acts as synchronization anchor. */ public SurfaceTransactionApplier(View targetView) { - mTargetViewRootImpl = new ViewRootImplCompat(targetView); - mBarrierSurfaceControl = mTargetViewRootImpl.getRenderSurfaceControl(); + mTargetViewRootImpl = targetView.getViewRootImpl(); + mBarrierSurfaceControl = mTargetViewRootImpl.getSurfaceControl(); mApplyHandler = new Handler(this::onApplyMessage); } @@ -109,7 +109,7 @@ public class SurfaceTransactionApplier extends ReleaseCheck { if (targetView == null) { // No target view, no applier callback.accept(null); - } else if (new ViewRootImplCompat(targetView).isValid()) { + } else if (targetView.isAttachedToWindow()) { // Already attached, we're good to go callback.accept(new SurfaceTransactionApplier(targetView)); } else { From bca13abc82879977dde43ee7cb4b51e2e47886bb Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Fri, 19 Nov 2021 17:27:17 -0800 Subject: [PATCH 4/8] Invoke Assistant on 3 button long click on Taskbar Bug: 204273914 Change-Id: I757fa40ad9ac0ace44b57c7dd08ec30b4c0ae6d0 --- .../taskbar/NavbarButtonsViewController.java | 10 ++---- .../taskbar/TaskbarNavButtonController.java | 36 ++++++++++++++----- .../AssistantInputConsumer.java | 4 +-- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 787aa19410..0565f7e976 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -17,7 +17,6 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y; -import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y_LONG_CLICK; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH; @@ -90,7 +89,6 @@ public class NavbarButtonsViewController { private static final int MASK_IME_SWITCHER_VISIBLE = FLAG_SWITCHER_SUPPORTED | FLAG_IME_VISIBLE; - private View.OnLongClickListener mA11yLongClickListener; private final ArrayList mPropertyHolders = new ArrayList<>(); private final ArrayList mAllButtons = new ArrayList<>(); private int mState; @@ -142,11 +140,6 @@ public class NavbarButtonsViewController { mNavButtonsView.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize; mNavButtonTranslationYMultiplier.value = 1; - mA11yLongClickListener = view -> { - mControllers.navButtonController.onButtonClick(BUTTON_A11Y_LONG_CLICK); - return true; - }; - mPropertyHolders.add(new StatePropertyHolder( mControllers.taskbarViewController.getTaskbarIconAlpha() .getProperty(ALPHA_INDEX_IME), @@ -285,7 +278,6 @@ public class NavbarButtonsViewController { mPropertyHolders.add(new StatePropertyHolder(mA11yButton, flags -> (flags & FLAG_A11Y_VISIBLE) != 0 && (flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0)); - mA11yButton.setOnLongClickListener(mA11yLongClickListener); } private void parseSystemUiFlags(int sysUiStateFlags) { @@ -441,6 +433,8 @@ public class NavbarButtonsViewController { ImageView buttonView = addButton(parent, id, layoutId); buttonView.setImageResource(drawableId); buttonView.setOnClickListener(view -> navButtonController.onButtonClick(buttonType)); + buttonView.setOnLongClickListener(view -> + navButtonController.onButtonLongClick(buttonType)); return buttonView; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java index a8a0b59f87..ae23eda2a4 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java @@ -16,9 +16,11 @@ package com.android.launcher3.taskbar; -import static android.view.Display.DEFAULT_DISPLAY; -import android.view.inputmethod.InputMethodManager; +import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS; +import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_KEY; + +import android.os.Bundle; import androidx.annotation.IntDef; @@ -35,11 +37,9 @@ import java.lang.annotation.RetentionPolicy; * Controller for 3 button mode in the taskbar. * Handles all the functionality of the various buttons, making/routing the right calls into * launcher or sysui/system. - * - * TODO: Create callbacks to hook into UI layer since state will change for more context buttons/ - * assistant invocation. */ public class TaskbarNavButtonController { + @Retention(RetentionPolicy.SOURCE) @IntDef(value = { BUTTON_BACK, @@ -47,7 +47,6 @@ public class TaskbarNavButtonController { BUTTON_RECENTS, BUTTON_IME_SWITCH, BUTTON_A11Y, - BUTTON_A11Y_LONG_CLICK }) public @interface TaskbarButton {} @@ -57,7 +56,6 @@ public class TaskbarNavButtonController { static final int BUTTON_RECENTS = BUTTON_HOME << 1; static final int BUTTON_IME_SWITCH = BUTTON_RECENTS << 1; static final int BUTTON_A11Y = BUTTON_IME_SWITCH << 1; - static final int BUTTON_A11Y_LONG_CLICK = BUTTON_A11Y << 1; private final TouchInteractionService mService; @@ -82,9 +80,22 @@ public class TaskbarNavButtonController { case BUTTON_A11Y: notifyImeClick(false /* longClick */); break; - case BUTTON_A11Y_LONG_CLICK: + } + } + + public boolean onButtonLongClick(@TaskbarButton int buttonType) { + switch (buttonType) { + case BUTTON_HOME: + startAssistant(); + return true; + case BUTTON_A11Y: notifyImeClick(true /* longClick */); - break; + return true; + case BUTTON_BACK: + case BUTTON_IME_SWITCH: + case BUTTON_RECENTS: + default: + return false; } } @@ -113,4 +124,11 @@ public class TaskbarNavButtonController { systemUiProxy.notifyAccessibilityButtonClicked(mService.getDisplayId()); } } + + private void startAssistant() { + Bundle args = new Bundle(); + args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS); + SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate(); + systemUiProxy.startAssistant(args); + } } diff --git a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java index 510820a1e5..162ace4965 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java @@ -24,6 +24,8 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN; import static android.view.MotionEvent.ACTION_POINTER_UP; import static android.view.MotionEvent.ACTION_UP; +import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_GESTURE; +import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_KEY; import static com.android.launcher3.Utilities.squaredHypot; import android.animation.Animator; @@ -64,8 +66,6 @@ public class AssistantInputConsumer extends DelegateInputConsumer { private static final String OPA_BUNDLE_TRIGGER = "triggered_by"; // From //java/com/google/android/apps/gsa/assistant/shared/proto/opa_trigger.proto. private static final int OPA_BUNDLE_TRIGGER_DIAG_SWIPE_GESTURE = 83; - private static final String INVOCATION_TYPE_KEY = "invocation_type"; - private static final int INVOCATION_TYPE_GESTURE = 1; private final PointF mDownPos = new PointF(); private final PointF mLastPos = new PointF(); From 34e384d2e1a381e1b18e7da90227fb61b2e75172 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 23 Nov 2021 08:04:14 +0000 Subject: [PATCH 5/8] Fix issue with Shell listeners being unbound if SysUI is restarted - If SysUI is restarted (ie. during dev or a crash), the components registering the shell listeners may not be aware of this, and listener callbacks will not be re-registered. Currently all the listeners are managed correctly (bound & later unbound) so we can just keep the active listener references to re-register if this happens. Bug: 207142749 Test: Kill SysUI, start some apps and ensure Launcher still shows them in recents Change-Id: Iba3b11ee972caf8f0b482942d38c3a7359211180 --- .../android/quickstep/RecentTasksList.java | 21 ++++++ .../com/android/quickstep/RecentsModel.java | 6 ++ .../com/android/quickstep/SystemUiProxy.java | 72 ++++++++----------- .../quickstep/TouchInteractionService.java | 1 + 4 files changed, 59 insertions(+), 41 deletions(-) diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index c5f4a53877..097850fd6f 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -36,6 +36,7 @@ import com.android.wm.shell.recents.IRecentTasksListener; import com.android.wm.shell.util.GroupedRecentTaskInfo; import com.android.wm.shell.util.StagedSplitBounds; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.function.Consumer; @@ -219,6 +220,26 @@ public class RecentTasksList { return newTasks; } + public void dump(String prefix, PrintWriter writer) { + writer.println(prefix + "RecentTasksList:"); + writer.println(prefix + " mChangeId=" + mChangeId); + writer.println(prefix + " mResultsUi=[id=" + mResultsUi.mRequestId + ", tasks="); + for (GroupTask task : mResultsUi) { + writer.println(prefix + " t1=" + task.task1.key.id + + " t2=" + (task.hasMultipleTasks() ? task.task2.key.id : "-1")); + } + writer.println(prefix + " ]"); + int currentUserId = Process.myUserHandle().getIdentifier(); + ArrayList rawTasks = + mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId); + writer.println(prefix + " rawTasks=["); + for (GroupedRecentTaskInfo task : rawTasks) { + writer.println(prefix + " t1=" + task.mTaskInfo1.taskId + + " t2=" + (task.mTaskInfo2 != null ? task.mTaskInfo2.taskId : "-1")); + } + writer.println(prefix + " ]"); + } + private static class TaskLoadResult extends ArrayList { final int mRequestId; diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java index e539a8c7c4..5d77a6e916 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -43,6 +43,7 @@ import com.android.systemui.shared.system.KeyguardManagerCompat; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; @@ -220,6 +221,11 @@ public class RecentsModel extends TaskStackChangeListener implements IconChangeL mThumbnailChangeListeners.remove(listener); } + public void dump(String prefix, PrintWriter writer) { + writer.println(prefix + "RecentsModel:"); + mTaskList.dump(" ", writer); + } + /** * Listener for receiving various task properties changes */ diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 68b7558cf2..c8abd14d22 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -83,14 +83,16 @@ public class SystemUiProxy implements ISystemUiProxy, MAIN_EXECUTOR.execute(() -> clearProxy()); }; - // Save the listeners passed into the proxy since when set/register these listeners, - // setProxy may not have been called, eg. OverviewProxyService is not connected yet. - private IPipAnimationListener mPendingPipAnimationListener; - private ISplitScreenListener mPendingSplitScreenListener; - private IStartingWindowListener mPendingStartingWindowListener; - private ISmartspaceCallback mPendingSmartspaceCallback; - private IRecentTasksListener mPendingRecentTasksListener; - private final ArrayList mPendingRemoteTransitions = new ArrayList<>(); + // Save the listeners passed into the proxy since OverviewProxyService may not have been bound + // yet, and we'll need to set/register these listeners with SysUI when they do. Note that it is + // up to the caller to clear the listeners to prevent leaks as these can be held indefinitely + // in case SysUI needs to rebind. + private IPipAnimationListener mPipAnimationListener; + private ISplitScreenListener mSplitScreenListener; + private IStartingWindowListener mStartingWindowListener; + private ISmartspaceCallback mSmartspaceCallback; + private IRecentTasksListener mRecentTasksListener; + private final ArrayList mRemoteTransitions = new ArrayList<>(); // Used to dedupe calls to SystemUI private int mLastShelfHeight; @@ -167,29 +169,23 @@ public class SystemUiProxy implements ISystemUiProxy, mRecentTasks = recentTasks; linkToDeath(); // re-attach the listeners once missing due to setProxy has not been initialized yet. - if (mPendingPipAnimationListener != null && mPip != null) { - setPinnedStackAnimationListener(mPendingPipAnimationListener); - mPendingPipAnimationListener = null; + if (mPipAnimationListener != null && mPip != null) { + setPinnedStackAnimationListener(mPipAnimationListener); } - if (mPendingSplitScreenListener != null && mSplitScreen != null) { - registerSplitScreenListener(mPendingSplitScreenListener); - mPendingSplitScreenListener = null; + if (mSplitScreenListener != null && mSplitScreen != null) { + registerSplitScreenListener(mSplitScreenListener); } - if (mPendingStartingWindowListener != null && mStartingWindow != null) { - setStartingWindowListener(mPendingStartingWindowListener); - mPendingStartingWindowListener = null; + if (mStartingWindowListener != null && mStartingWindow != null) { + setStartingWindowListener(mStartingWindowListener); } - if (mPendingSmartspaceCallback != null && mSmartspaceTransitionController != null) { - setSmartspaceCallback(mPendingSmartspaceCallback); - mPendingSmartspaceCallback = null; + if (mSmartspaceCallback != null && mSmartspaceTransitionController != null) { + setSmartspaceCallback(mSmartspaceCallback); } - for (int i = mPendingRemoteTransitions.size() - 1; i >= 0; --i) { - registerRemoteTransition(mPendingRemoteTransitions.get(i)); + for (int i = mRemoteTransitions.size() - 1; i >= 0; --i) { + registerRemoteTransition(mRemoteTransitions.get(i)); } - mPendingRemoteTransitions.clear(); - if (mPendingRecentTasksListener != null && mRecentTasks != null) { - registerRecentTasksListener(mPendingRecentTasksListener); - mPendingRecentTasksListener = null; + if (mRecentTasksListener != null && mRecentTasks != null) { + registerRecentTasksListener(mRecentTasksListener); } if (mPendingSetNavButtonAlpha != null) { @@ -513,9 +509,8 @@ public class SystemUiProxy implements ISystemUiProxy, } catch (RemoteException e) { Log.w(TAG, "Failed call setPinnedStackAnimationListener", e); } - } else { - mPendingPipAnimationListener = listener; } + mPipAnimationListener = listener; } public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo, @@ -553,9 +548,8 @@ public class SystemUiProxy implements ISystemUiProxy, } catch (RemoteException e) { Log.w(TAG, "Failed call registerSplitScreenListener"); } - } else { - mPendingSplitScreenListener = listener; } + mSplitScreenListener = listener; } public void unregisterSplitScreenListener(ISplitScreenListener listener) { @@ -566,7 +560,7 @@ public class SystemUiProxy implements ISystemUiProxy, Log.w(TAG, "Failed call unregisterSplitScreenListener"); } } - mPendingSplitScreenListener = null; + mSplitScreenListener = null; } /** Start multiple tasks in split-screen simultaneously. */ @@ -687,9 +681,8 @@ public class SystemUiProxy implements ISystemUiProxy, } catch (RemoteException e) { Log.w(TAG, "Failed call registerRemoteTransition"); } - } else { - mPendingRemoteTransitions.add(remoteTransition); } + mRemoteTransitions.add(remoteTransition); } public void unregisterRemoteTransition(RemoteTransitionCompat remoteTransition) { @@ -700,7 +693,7 @@ public class SystemUiProxy implements ISystemUiProxy, Log.w(TAG, "Failed call registerRemoteTransition"); } } - mPendingRemoteTransitions.remove(remoteTransition); + mRemoteTransitions.remove(remoteTransition); } // @@ -717,9 +710,8 @@ public class SystemUiProxy implements ISystemUiProxy, } catch (RemoteException e) { Log.w(TAG, "Failed call setStartingWindowListener", e); } - } else { - mPendingStartingWindowListener = listener; } + mStartingWindowListener = listener; } // @@ -733,9 +725,8 @@ public class SystemUiProxy implements ISystemUiProxy, } catch (RemoteException e) { Log.w(TAG, "Failed call setStartingWindowListener", e); } - } else { - mPendingSmartspaceCallback = callback; } + mSmartspaceCallback = callback; } // @@ -749,9 +740,8 @@ public class SystemUiProxy implements ISystemUiProxy, } catch (RemoteException e) { Log.w(TAG, "Failed call registerRecentTasksListener", e); } - } else { - mPendingRecentTasksListener = listener; } + mRecentTasksListener = listener; } public void unregisterRecentTasksListener(IRecentTasksListener listener) { @@ -762,7 +752,7 @@ public class SystemUiProxy implements ISystemUiProxy, Log.w(TAG, "Failed call unregisterRecentTasksListener"); } } - mPendingRecentTasksListener = null; + mRecentTasksListener = null; } public ArrayList getRecentTasks(int numTasks, int userId) { diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index bda5a3044c..30dce61422 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -976,6 +976,7 @@ public class TouchInteractionService extends Service pw.println(" resumed=" + resumed); pw.println(" mConsumer=" + mConsumer.getName()); ActiveGestureLog.INSTANCE.dump("", pw); + RecentsModel.INSTANCE.get(this).dump("", pw); pw.println("ProtoTrace:"); pw.println(" file=" + ProtoTracer.INSTANCE.get(this).getTraceFile()); } From f316a267d828e2fd8ed1fe1656be381a1121ed9d Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Fri, 19 Nov 2021 13:05:26 -0300 Subject: [PATCH 6/8] Add scrim below TaskMenu When opening a menu, a scrim with 80% alpha should be shown on top of Recents view. Align task menu second row with icon: when the menu shows up in the bottom row in landscape, the menu should be aligned on the second row. TODO: there is a RTL bug that I'm waiting because it also affects other parts, not only this menu. Bug: 193432925 Test: open Overview and tap the app icon Change-Id: I6846ee937cb5e739e8be64d17045bc3b32e28e46 --- .../com/android/quickstep/views/IconView.java | 8 ++ .../android/quickstep/views/RecentsView.java | 13 ++- .../quickstep/views/TaskMenuViewWithArrow.kt | 100 ++++++++++++++---- .../com/android/quickstep/views/TaskView.java | 4 +- 4 files changed, 102 insertions(+), 23 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/IconView.java b/quickstep/src/com/android/quickstep/views/IconView.java index ccb1a991ea..5895c05dcd 100644 --- a/quickstep/src/com/android/quickstep/views/IconView.java +++ b/quickstep/src/com/android/quickstep/views/IconView.java @@ -87,6 +87,14 @@ public class IconView extends View { return mDrawable; } + public int getDrawableWidth() { + return mDrawableWidth; + } + + public int getDrawableHeight() { + return mDrawableHeight; + } + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 017a3b8589..c14cead0ee 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -2612,10 +2612,8 @@ public abstract class RecentsView secondaryViewTranslate = taskView.getSecondaryDissmissTranslationProperty(); int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView); @@ -4681,6 +4679,15 @@ public abstract class RecentsView getEventDispatcher(float navbarRotation) { float degreesRotated; if (navbarRotation == 0) { diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt index cd1691ba53..06a579300a 100644 --- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt +++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt @@ -45,7 +45,10 @@ class TaskMenuViewWithArrow : ArrowPopup { companion object { const val TAG = "TaskMenuViewWithArrow" - fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean { + fun showForTask( + taskContainer: TaskIdAttributeContainer, + alignSecondRow: Boolean = false + ): Boolean { val activity = BaseDraggingActivity .fromContext(taskContainer.taskView.context) val taskMenuViewWithArrow = activity.layoutInflater @@ -55,7 +58,7 @@ class TaskMenuViewWithArrow : ArrowPopup { false ) as TaskMenuViewWithArrow<*> - return taskMenuViewWithArrow.populateAndShowForTask(taskContainer) + return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignSecondRow) } } @@ -78,6 +81,9 @@ class TaskMenuViewWithArrow : ArrowPopup { CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION } + private var alignSecondRow: Boolean = false + private val extraSpaceForSecondRowAlignment: Int + get() = if (alignSecondRow) optionMeasuredHeight else 0 private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid) private lateinit var taskView: TaskView @@ -91,6 +97,10 @@ class TaskMenuViewWithArrow : ArrowPopup { else 0 + private var iconView: IconView? = null + private var scrim: View? = null + private val scrimAlpha = 0.8f + override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0 override fun getTargetObjectLocation(outPos: Rect?) { @@ -112,18 +122,35 @@ class TaskMenuViewWithArrow : ArrowPopup { optionLayout = findViewById(KtR.id.menu_option_layout) } - private fun populateAndShowForTask(taskContainer: TaskIdAttributeContainer): Boolean { + private fun populateAndShowForTask( + taskContainer: TaskIdAttributeContainer, + alignSecondRow: Boolean + ): Boolean { if (isAttachedToWindow) { return false } taskView = taskContainer.taskView this.taskContainer = taskContainer + this.alignSecondRow = alignSecondRow if (!populateMenu()) return false + addScrim() show() return true } + private fun addScrim() { + scrim = View(context).apply { + layoutParams = FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT + ) + setBackgroundColor(Themes.getAttrColor(context, R.attr.overviewScrimColor)) + alpha = 0f + } + popupContainer.addView(scrim) + } + /** @return true if successfully able to populate task view menu, false otherwise */ private fun populateMenu(): Boolean { @@ -180,18 +207,50 @@ class TaskMenuViewWithArrow : ArrowPopup { } override fun onCreateOpenAnimation(anim: AnimatorSet) { - anim.play( - ObjectAnimator.ofFloat( - taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, - TaskView.MAX_PAGE_SCRIM_ALPHA + scrim?.let { + anim.play( + ObjectAnimator.ofFloat(it, View.ALPHA, 0f, scrimAlpha) + .setDuration(OPEN_DURATION.toLong()) ) - ) + } } override fun onCreateCloseAnimation(anim: AnimatorSet) { - anim.play( - ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f) - ) + scrim?.let { + anim.play( + ObjectAnimator.ofFloat(it, View.ALPHA, scrimAlpha, 0f) + .setDuration(CLOSE_DURATION.toLong()) + ) + } + } + + override fun closeComplete() { + super.closeComplete() + popupContainer.removeView(scrim) + popupContainer.removeView(iconView) + } + + /** + * Copy the iconView from taskView to dragLayer so it can stay on top of the scrim. + * It needs to be called after [getTargetObjectLocation] because [mTempRect] needs to be + * populated. + */ + private fun copyIconToDragLayer(insets: Rect) { + iconView = IconView(context).apply { + layoutParams = FrameLayout.LayoutParams( + taskContainer.iconView.width, + taskContainer.iconView.height + ) + x = mTempRect.left.toFloat() - insets.left + y = mTempRect.top.toFloat() - insets.top + drawable = taskContainer.iconView.drawable + setDrawableSize( + taskContainer.iconView.drawableWidth, + taskContainer.iconView.drawableHeight + ) + } + + popupContainer.addView(iconView) } /** @@ -217,7 +276,10 @@ class TaskMenuViewWithArrow : ArrowPopup { val dragLayer: InsettableFrameLayout = popupContainer val insets = dragLayer.insets - // Put to the right of the icon if there is space, which means left aligned with the menu + copyIconToDragLayer(insets) + + // Put this menu to the right of the icon if there is space, + // which means the arrow is left aligned with the menu val rightAlignedMenuStartX = mTempRect.left - widthWithArrow val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace mIsLeftAligned = if (mIsRtl) { @@ -229,18 +291,17 @@ class TaskMenuViewWithArrow : ArrowPopup { var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX - // Offset y so that the arrow and first row are center-aligned with the original icon. + // Offset y so that the arrow and row are center-aligned with the original icon. val iconHeight = mTempRect.height() - val optionHeight = optionMeasuredHeight - val yOffset = (optionHeight - iconHeight) / 2 - var menuStartY = mTempRect.top - yOffset + val yOffset = (optionMeasuredHeight - iconHeight) / 2 + var menuStartY = mTempRect.top - yOffset - extraSpaceForSecondRowAlignment // Insets are added later, so subtract them now. menuStartX -= insets.left menuStartY -= insets.top - setX(menuStartX.toFloat()) - setY(menuStartY.toFloat()) + x = menuStartX.toFloat() + y = menuStartY.toFloat() val lp = layoutParams as FrameLayout.LayoutParams val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams @@ -251,7 +312,8 @@ class TaskMenuViewWithArrow : ArrowPopup { override fun addArrow() { popupContainer.addView(mArrow) mArrow.x = getArrowX() - mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) + mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) + + extraSpaceForSecondRowAlignment updateArrowColor() diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 1ff2a88b31..7778813200 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -840,7 +840,9 @@ public class TaskView extends FrameLayout implements Reusable { TaskIdAttributeContainer menuContainer = mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1]; if (mActivity.getDeviceProfile().overviewShowAsGrid) { - return TaskMenuViewWithArrow.Companion.showForTask(menuContainer); + boolean alignSecondRow = getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) + && mActivity.getDeviceProfile().isLandscape; + return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignSecondRow); } else { return TaskMenuView.showForTask(menuContainer); } From d4c6ecdca6b1ce008fb0dc24d966893e51894adb Mon Sep 17 00:00:00 2001 From: Stefano Galarraga Date: Tue, 23 Nov 2021 13:25:21 +0000 Subject: [PATCH 7/8] Revert "Sending broadcast message when home screen is ready." Revert "Receiving a broadcast message when home screen is ready." Revert submission 16169565-b/199120420 Reason for revert: Breaking Build (b/207471332) Reverted Changes: Ibc101a249:Receiving a broadcast message when home screen is ... I18628552a:Sending broadcast message when home screen is read... Change-Id: Ib29eae2d58c9ae2e3002c0fa18265c6767733e22 --- .../launcher3/uioverrides/QuickstepLauncher.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 72195a0512..9050ddc511 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -68,11 +68,9 @@ import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchControll import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController; import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController; import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController; -import com.android.launcher3.util.IntSet; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.OnboardingPrefs; import com.android.launcher3.util.PendingRequestArgs; -import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.TouchController; import com.android.launcher3.util.UiThreadHelper; import com.android.launcher3.util.UiThreadHelper.AsyncCommand; @@ -93,8 +91,6 @@ import java.util.stream.Stream; public class QuickstepLauncher extends BaseQuickstepLauncher { - public static final String HOME_IS_READY = "com.android.launcher3.HOME_IS_READY"; - public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false; /** * Reusable command for applying the shelf height on the background thread. @@ -235,12 +231,6 @@ public class QuickstepLauncher extends BaseQuickstepLauncher { } } - @Override - public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) { - super.onInitialBindComplete(boundPages, pendingTasks); - sendBroadcast(new Intent(HOME_IS_READY).setPackage("com.android.settings")); - } - @Override public void bindExtraContainerItems(FixedContainerItems item) { if (item.containerId == Favorites.CONTAINER_PREDICTION) { From 804dd0a2e17985dde351a22a5e1335ab07960ef7 Mon Sep 17 00:00:00 2001 From: Fedor Kudasov Date: Tue, 23 Nov 2021 14:20:49 +0000 Subject: [PATCH 8/8] Annotate getMaxRadius Bug: 205828770 Test: m LauncherGoResLib Change-Id: I9a3561f415fa5a20167002e42f7fe41b60b3dc9c --- .../android/quickstep/views/FloatingWidgetBackgroundView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java index c3b166fada..adea1a40cf 100644 --- a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java +++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java @@ -136,7 +136,7 @@ final class FloatingWidgetBackgroundView extends View { } /** Returns the maximum corner radius of {@param drawable}. */ - private static float getMaxRadius(Drawable drawable) { + private static float getMaxRadius(@Nullable Drawable drawable) { if (!(drawable instanceof GradientDrawable)) return 0; float[] cornerRadii = ((GradientDrawable) drawable).getCornerRadii(); float cornerRadius = ((GradientDrawable) drawable).getCornerRadius();