diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java index 14fe6ab7df1c3..28ac8cc8b8bd1 100644 --- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java +++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java @@ -113,5 +113,25 @@ public final class SystemUiDeviceConfigFlags { */ public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled"; + // Flags related to Assistant Handles + + /** + * (String) Which behavior mode for the Assistant Handles to use. + */ + public static final String ASSIST_HANDLES_BEHAVIOR_MODE = "assist_handles_behavior_mode"; + + /** + * (long) How long, in milliseconds, to display Assist Handles when showing them temporarily. + */ + public static final String ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS = + "assist_handles_show_and_go_duration_ms"; + + /** + * (long) How long, in milliseconds, to wait before displaying Assist Handles temporarily after + * hiding them. + */ + public static final String ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS = + "assist_handles_shown_frequency_threshold_ms"; + private SystemUiDeviceConfigFlags() { } } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java index 0203d9ed23763..ff508ade72f81 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java @@ -24,9 +24,13 @@ import android.os.Build; import android.os.Handler; import android.os.SystemClock; import android.os.SystemProperties; +import android.provider.DeviceConfig; import android.util.Log; +import androidx.annotation.Nullable; + import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.systemui.Dependency; import com.android.systemui.ScreenDecorations; import com.android.systemui.SysUiServiceProvider; @@ -46,6 +50,7 @@ import java.util.function.Supplier; public final class AssistHandleBehaviorController implements AssistHandleCallbacks { private static final String TAG = "AssistHandleBehavior"; + private static final boolean IS_DEBUG_DEVICE = Build.TYPE.toLowerCase(Locale.ROOT).contains("debug") || Build.TYPE.toLowerCase(Locale.ROOT).equals("eng"); @@ -87,6 +92,19 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac Dependency.get(NavigationModeController.class) .addListener(this::handleNavigationModeChange)); + setBehavior(DeviceConfig.getString( + DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE, + mCurrentBehavior.toString())); + DeviceConfig.addOnPropertyChangedListener( + DeviceConfig.NAMESPACE_SYSTEMUI, + mHandler::post, + (namespace, name, value) -> { + if (SystemUiDeviceConfigFlags.ASSIST_HANDLES_BEHAVIOR_MODE.equals(name)) { + setBehavior(value); + } + }); + if (IS_DEBUG_DEVICE) { context.registerReceiver(new BroadcastReceiver() { @Override @@ -136,13 +154,29 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac mCurrentBehavior = behavior; } - private static long getShownFrequencyThreshold() { - return SystemProperties.getLong( - SHOWN_FREQUENCY_THRESHOLD_KEY, DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS); + private void setBehavior(@Nullable String behavior) { + try { + setBehavior(AssistHandleBehavior.valueOf(behavior)); + } catch (IllegalArgumentException | NullPointerException e) { + Log.e(TAG, "Invalid behavior: " + behavior, e); + } } - private static long getShowAndGoDuration() { - return SystemProperties.getLong(SHOW_AND_GO_DURATION_KEY, DEFAULT_SHOW_AND_GO_DURATION_MS); + private long getShownFrequencyThreshold() { + long configValue = DeviceConfig.getLong( + DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOWN_FREQUENCY_THRESHOLD_MS, + DEFAULT_SHOWN_FREQUENCY_THRESHOLD_MS); + return SystemProperties.getLong( + SHOWN_FREQUENCY_THRESHOLD_KEY, configValue); + } + + private long getShowAndGoDuration() { + long configValue = DeviceConfig.getLong( + DeviceConfig.NAMESPACE_SYSTEMUI, + SystemUiDeviceConfigFlags.ASSIST_HANDLES_SHOW_AND_GO_DURATION_MS, + DEFAULT_SHOW_AND_GO_DURATION_MS); + return SystemProperties.getLong(SHOW_AND_GO_DURATION_KEY, configValue); } private void maybeShowHandles(boolean ignoreThreshold) { diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java index e89e93c0adf07..05e504c93b82e 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleLikeHomeBehavior.java @@ -16,17 +16,15 @@ package com.android.systemui.assist; -import android.app.StatusBarManager; import android.content.Context; import androidx.annotation.Nullable; import com.android.systemui.Dependency; -import com.android.systemui.SysUiServiceProvider; import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController; -import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.NavigationBarController; -import com.android.systemui.statusbar.phone.NavigationBarFragment; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.recents.OverviewProxyService; +import com.android.systemui.shared.system.QuickStepContract; /** * Assistant Handle behavior that makes Assistant handles show/hide when the home handle is @@ -34,47 +32,68 @@ import com.android.systemui.statusbar.phone.NavigationBarFragment; */ final class AssistHandleLikeHomeBehavior implements BehaviorController { - private final CommandQueue.Callbacks mCallbacks = new CommandQueue.Callbacks() { + private final StatusBarStateController.StateListener mStatusBarStateListener = + new StatusBarStateController.StateListener() { + @Override + public void onDozingChanged(boolean isDozing) { + handleDozingChanged(isDozing); + } + }; + private final OverviewProxyService.OverviewProxyListener mOverviewProxyListener = + new OverviewProxyService.OverviewProxyListener() { @Override - public void setWindowState(int displayId, int window, int state) { - if (mNavBarDisplayId == displayId - && window == StatusBarManager.WINDOW_NAVIGATION_BAR) { - handleWindowStateChanged(state); - } + public void onSystemUiStateChanged(int sysuiStateFlags) { + handleSystemUiStateChange(sysuiStateFlags); } }; + private final StatusBarStateController mStatusBarStateController; + private final OverviewProxyService mOverviewProxyService; - private CommandQueue mCommandQueue; - private int mNavBarDisplayId; - private boolean mIsNavBarWindowVisible; + private boolean mIsDozing; + private boolean mIsHomeHandleHiding; @Nullable private AssistHandleCallbacks mAssistHandleCallbacks; + AssistHandleLikeHomeBehavior() { + mStatusBarStateController = Dependency.get(StatusBarStateController.class); + mOverviewProxyService = Dependency.get(OverviewProxyService.class); + } + @Override public void onModeActivated(Context context, AssistHandleCallbacks callbacks) { mAssistHandleCallbacks = callbacks; - NavigationBarFragment navigationBarFragment = - Dependency.get(NavigationBarController.class).getDefaultNavigationBarFragment(); - mNavBarDisplayId = navigationBarFragment.mDisplayId; - mIsNavBarWindowVisible = navigationBarFragment.isNavBarWindowVisible(); - mCommandQueue = SysUiServiceProvider.getComponent(context, CommandQueue.class); - mCommandQueue.addCallback(mCallbacks); + mIsDozing = mStatusBarStateController.isDozing(); + mStatusBarStateController.addCallback(mStatusBarStateListener); + mOverviewProxyService.addCallback(mOverviewProxyListener); callbackForCurrentState(); } @Override public void onModeDeactivated() { mAssistHandleCallbacks = null; - mCommandQueue.removeCallback(mCallbacks); + mOverviewProxyService.removeCallback(mOverviewProxyListener); } - private void handleWindowStateChanged(int state) { - boolean newVisibility = state == StatusBarManager.WINDOW_STATE_SHOWING; - if (mIsNavBarWindowVisible == newVisibility) { + private static boolean isHomeHandleHiding(int sysuiStateFlags) { + return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0; + } + + private void handleDozingChanged(boolean isDozing) { + if (mIsDozing == isDozing) { return; } - mIsNavBarWindowVisible = newVisibility; + mIsDozing = isDozing; + callbackForCurrentState(); + } + + private void handleSystemUiStateChange(int sysuiStateFlags) { + boolean isHomeHandleHiding = isHomeHandleHiding(sysuiStateFlags); + if (mIsHomeHandleHiding == isHomeHandleHiding) { + return; + } + + mIsHomeHandleHiding = isHomeHandleHiding; callbackForCurrentState(); } @@ -83,10 +102,10 @@ final class AssistHandleLikeHomeBehavior implements BehaviorController { return; } - if (mIsNavBarWindowVisible) { - mAssistHandleCallbacks.showAndStay(); - } else { + if (mIsHomeHandleHiding || mIsDozing) { mAssistHandleCallbacks.hide(); + } else { + mAssistHandleCallbacks.showAndStay(); } } } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java index 4a5e0e85107e0..93e48863d2b88 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleReminderExpBehavior.java @@ -16,22 +16,19 @@ package com.android.systemui.assist; +import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; -import android.graphics.Rect; -import android.view.View; -import android.view.WindowManager; import androidx.annotation.Nullable; import com.android.systemui.Dependency; -import com.android.systemui.SysUiServiceProvider; import com.android.systemui.assist.AssistHandleBehaviorController.BehaviorController; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.recents.OverviewProxyService; import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.TaskStackChangeListener; -import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.StatusBarState; /** @@ -65,53 +62,45 @@ final class AssistHandleReminderExpBehavior implements BehaviorController { handleTaskStackTopChanged(taskId); } }; - private final CommandQueue.Callbacks mCallbacks = new CommandQueue.Callbacks() { - @Override - public void setSystemUiVisibility(int displayId, int vis, - int fullscreenStackVis, int dockedStackVis, int mask, - Rect fullscreenStackBounds, Rect dockedStackBounds, - boolean navbarColorManagedByIme) { - if (mStatusBarDisplayId == displayId) { - handleSystemUiVisibilityChange(vis, mask); - } - } - }; private final OverviewProxyService.OverviewProxyListener mOverviewProxyListener = new OverviewProxyService.OverviewProxyListener() { @Override public void onOverviewShown(boolean fromHome) { handleOverviewShown(); } + + @Override + public void onSystemUiStateChanged(int sysuiStateFlags) { + handleSystemUiStateChanged(sysuiStateFlags); + } }; - private StatusBarStateController mStatusBarStateController; - private ActivityManagerWrapper mActivityManagerWrapper; - private OverviewProxyService mOverviewProxyService; - private int mStatusBarDisplayId; - private CommandQueue mCommandQueue; + private final StatusBarStateController mStatusBarStateController; + private final ActivityManagerWrapper mActivityManagerWrapper; + private final OverviewProxyService mOverviewProxyService; + private boolean mOnLockscreen; private boolean mIsDozing; private int mRunningTaskId; - private boolean mIsImmersive; + private boolean mIsNavBarHidden; @Nullable private AssistHandleCallbacks mAssistHandleCallbacks; + AssistHandleReminderExpBehavior() { + mStatusBarStateController = Dependency.get(StatusBarStateController.class); + mActivityManagerWrapper = ActivityManagerWrapper.getInstance(); + mOverviewProxyService = Dependency.get(OverviewProxyService.class); + } + @Override public void onModeActivated(Context context, AssistHandleCallbacks callbacks) { mAssistHandleCallbacks = callbacks; - mStatusBarStateController = Dependency.get(StatusBarStateController.class); mOnLockscreen = onLockscreen(mStatusBarStateController.getState()); mIsDozing = mStatusBarStateController.isDozing(); mStatusBarStateController.addCallback(mStatusBarStateListener); - mActivityManagerWrapper = ActivityManagerWrapper.getInstance(); - mRunningTaskId = mActivityManagerWrapper.getRunningTask().taskId; + ActivityManager.RunningTaskInfo runningTaskInfo = mActivityManagerWrapper.getRunningTask(); + mRunningTaskId = runningTaskInfo == null ? 0 : runningTaskInfo.taskId; mActivityManagerWrapper.registerTaskStackListener(mTaskStackChangeListener); - mStatusBarDisplayId = - ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay().getDisplayId(); - mCommandQueue = SysUiServiceProvider.getComponent(context, CommandQueue.class); - mCommandQueue.addCallback(mCallbacks); - mOverviewProxyService = Dependency.get(OverviewProxyService.class); mOverviewProxyService.addCallback(mOverviewProxyListener); callbackForCurrentState(); } @@ -121,10 +110,13 @@ final class AssistHandleReminderExpBehavior implements BehaviorController { mAssistHandleCallbacks = null; mStatusBarStateController.removeCallback(mStatusBarStateListener); mActivityManagerWrapper.unregisterTaskStackListener(mTaskStackChangeListener); - mCommandQueue.removeCallback(mCallbacks); mOverviewProxyService.removeCallback(mOverviewProxyListener); } + private static boolean isNavBarHidden(int sysuiStateFlags) { + return (sysuiStateFlags & QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN) != 0; + } + private void handleStatusBarStateChanged(int newState) { boolean onLockscreen = onLockscreen(newState); if (mOnLockscreen == onLockscreen) { @@ -153,13 +145,13 @@ final class AssistHandleReminderExpBehavior implements BehaviorController { callbackForCurrentState(); } - private void handleSystemUiVisibilityChange(int vis, int mask) { - boolean isImmersive = isImmersive(vis, mask); - if (mIsImmersive == isImmersive) { + private void handleSystemUiStateChanged(int sysuiStateFlags) { + boolean isNavBarHidden = isNavBarHidden(sysuiStateFlags); + if (mIsNavBarHidden == isNavBarHidden) { return; } - mIsImmersive = isImmersive; + mIsNavBarHidden = isNavBarHidden; callbackForCurrentState(); } @@ -172,17 +164,12 @@ final class AssistHandleReminderExpBehavior implements BehaviorController { || statusBarState == StatusBarState.SHADE_LOCKED; } - private boolean isImmersive(int vis, int mask) { - return ((vis & mask) - & (View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)) != 0; - } - private void callbackForCurrentState() { if (mAssistHandleCallbacks == null) { return; } - if (mIsDozing || mIsImmersive) { + if (mIsDozing || mIsNavBarHidden) { mAssistHandleCallbacks.hide(); } else if (mOnLockscreen) { mAssistHandleCallbacks.showAndStay();