From 2c1134052e92ccf437cd12a4ac4b1c3797f93a6c Mon Sep 17 00:00:00 2001 From: Govinda Wasserman Date: Fri, 24 May 2019 14:11:24 -0400 Subject: [PATCH] Update assist handle behavior control Improves behavior modes to use more reliable callback mechanisms. Added phenotype flag hooks for control of behavior and behavior parameters. Added more robust null guarding. Test: Tested locally BUG:132983599 Change-Id: I42039152836071941d6b4f1cafb3670c62a65824 --- .../sysui/SystemUiDeviceConfigFlags.java | 20 +++++ .../AssistHandleBehaviorController.java | 44 +++++++++-- .../assist/AssistHandleLikeHomeBehavior.java | 75 ++++++++++++------- .../AssistHandleReminderExpBehavior.java | 71 +++++++----------- 4 files changed, 135 insertions(+), 75 deletions(-) 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();