diff --git a/quickstep/res/values/override.xml b/quickstep/res/values/override.xml index 67be0dd113..860abc1cc3 100644 --- a/quickstep/res/values/override.xml +++ b/quickstep/res/values/override.xml @@ -27,6 +27,8 @@ + + com.android.launcher3.secondarydisplay.SecondaryDisplayPredictionsImpl com.android.launcher3.taskbar.TaskbarModelCallbacksFactory diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java index 0f8de34461..993f13eaa4 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java @@ -51,6 +51,7 @@ import com.android.quickstep.OverviewCommandHelper; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskUtils; import com.android.quickstep.TouchInteractionService; +import com.android.quickstep.util.AssistUtilsBase; import com.android.quickstep.views.DesktopTaskView; import java.io.PrintWriter; @@ -158,7 +159,7 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa switch (buttonType) { case BUTTON_HOME: logEvent(LAUNCHER_TASKBAR_HOME_BUTTON_LONGPRESS); - startAssistant(); + onLongPressHome(); return true; case BUTTON_A11Y: logEvent(LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS); @@ -307,13 +308,17 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa } } - private void startAssistant() { + private void onLongPressHome() { if (mScreenPinned || !mAssistantLongPressEnabled) { return; } - Bundle args = new Bundle(); - args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS); - mSystemUiProxy.startAssistant(args); + // Attempt to start Assist with AssistUtils, otherwise fall back to SysUi's implementation. + if (!AssistUtilsBase.newInstance(mService.getApplicationContext()).tryStartAssistOverride( + INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS)) { + Bundle args = new Bundle(); + args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS); + mSystemUiProxy.startAssistant(args); + } } private void showQuickSettings() { diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index e73b52585f..823e1378f3 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -62,6 +62,7 @@ import com.android.internal.view.AppearanceRegion; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.SplitConfigurationOptions; +import com.android.quickstep.util.AssistUtilsBase; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.RecentsAnimationControllerCompat; @@ -250,6 +251,8 @@ public class SystemUiProxy implements ISystemUiProxy { setBackToLauncherCallback(mBackToLauncherCallback, mBackToLauncherRunner); setUnfoldAnimationListener(mUnfoldAnimationListener); setDesktopTaskListener(mDesktopTaskListener); + setAssistantOverridesRequested( + AssistUtilsBase.newInstance(mContext).getSysUiAssistOverrideInvocationTypes()); } /** @@ -373,6 +376,17 @@ public class SystemUiProxy implements ISystemUiProxy { } } + @Override + public void setAssistantOverridesRequested(int[] invocationTypes) { + if (mSystemUiProxy != null) { + try { + mSystemUiProxy.setAssistantOverridesRequested(invocationTypes); + } catch (RemoteException e) { + Log.w(TAG, "Failed call setAssistantOverridesRequested", e); + } + } + } + @Override public void notifyAccessibilityButtonClicked(int displayId) { if (mSystemUiProxy != null) { diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 22aca2571d..cd88894936 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -117,6 +117,7 @@ import com.android.quickstep.inputconsumers.TaskbarUnstashInputConsumer; import com.android.quickstep.inputconsumers.TrackpadStatusBarInputConsumer; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.ActiveGestureLog.CompoundString; +import com.android.quickstep.util.AssistUtilsBase; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -280,6 +281,20 @@ public class TouchInteractionService extends Service { })); } + /** + * Sent when the assistant has been invoked with the given type (defined in AssistManager) + * and should be shown. This method is used if SystemUiProxy#setAssistantOverridesRequested + * was previously called including this invocation type. + */ + @Override + public void onAssistantOverrideInvoked(int invocationType) { + executeForTouchInteractionService(tis -> { + if (!AssistUtilsBase.newInstance(tis).tryStartAssistOverride(invocationType)) { + Log.w(TAG, "Failed to invoke Assist override"); + } + }); + } + @Override public void onNavigationBarSurface(SurfaceControl surface) { // TODO: implement diff --git a/quickstep/src/com/android/quickstep/util/AssistUtilsBase.java b/quickstep/src/com/android/quickstep/util/AssistUtilsBase.java new file mode 100644 index 0000000000..7b270204bf --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/AssistUtilsBase.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.quickstep.util; + +import android.content.Context; + +import com.android.launcher3.R; +import com.android.launcher3.util.ResourceBasedOverride; + +/** Utilities to work with Assistant functionality. */ +public class AssistUtilsBase implements ResourceBasedOverride { + + public AssistUtilsBase() {} + + /** Creates AssistUtils as specified by overrides */ + public static AssistUtilsBase newInstance(Context context) { + return Overrides.getObject(AssistUtilsBase.class, context, R.string.assist_utils_class); + } + + /** @return Array of AssistUtils.INVOCATION_TYPE_* that we want to handle instead of SysUI. */ + public int[] getSysUiAssistOverrideInvocationTypes() { + return new int[0]; + } + + /** + * @return {@code true} if the override was handled, i.e. an assist surface was shown or the + * request should be ignored. {@code false} means the caller should start assist another way. + */ + public boolean tryStartAssistOverride(int invocationType) { + return false; + } +} diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java index 962261940c..b3d04c6ff8 100644 --- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java +++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.when; import android.os.Handler; import android.view.View; +import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.logging.StatsLogManager; @@ -70,6 +71,9 @@ public class TaskbarNavButtonControllerTest { MockitoAnnotations.initMocks(this); when(mockService.getDisplayId()).thenReturn(DISPLAY_ID); when(mockService.getOverviewCommandHelper()).thenReturn(mockCommandHelper); + when(mockService.getApplicationContext()) + .thenReturn(InstrumentationRegistry.getInstrumentation().getTargetContext() + .getApplicationContext()); when(mockStatsLogManager.logger()).thenReturn(mockStatsLogger); when(mockTaskbarControllers.getTaskbarActivityContext()) .thenReturn(mockTaskbarActivityContext);