Allow configuring home button longpress duration with a flag

Bug: 182169548
Test: tried various flag values locally on a Pixel 3 + atest SystemUITests
Change-Id: I738d86e5ef3069a03de41fa6a5bc7cdd58e3bc88
This commit is contained in:
Teddy Katz
2021-03-03 18:27:29 +00:00
parent b4d712a873
commit 9e64d0934a
3 changed files with 94 additions and 3 deletions

View File

@@ -488,6 +488,12 @@ public final class SystemUiDeviceConfigFlags {
public static final String APPLY_SHARING_APP_LIMITS_IN_SYSUI =
"apply_sharing_app_limits_in_sysui";
/*
* (long) The duration that the home button must be pressed before triggering Assist
*/
public static final String HOME_BUTTON_LONG_PRESS_DURATION_MS =
"home_button_long_press_duration_ms";
private SystemUiDeviceConfigFlags() {
}
}

View File

@@ -35,6 +35,7 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_FORCE_OPAQUE;
import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
@@ -85,6 +86,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.IWindowManager;
import android.view.InsetsState.InternalInsetsType;
import android.view.KeyEvent;
@@ -212,6 +214,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
private int mLayoutDirection;
private boolean mForceNavBarHandleOpaque;
private Optional<Long> mHomeButtonLongPressDurationMs;
private boolean mIsCurrentUserSetup;
/** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */
@@ -373,6 +376,14 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
private final Runnable mAutoDim = () -> getBarTransitions().setAutoDim(true);
private final Runnable mOnVariableDurationHomeLongClick = () -> {
if (onHomeLongClick(mNavigationBarView.getHomeButton().getCurrentView())) {
mNavigationBarView.getHomeButton().getCurrentView().performHapticFeedback(
HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
}
};
private final ContentObserver mAssistContentObserver = new ContentObserver(
new Handler(Looper.getMainLooper())) {
@Override
@@ -394,6 +405,13 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
mForceNavBarHandleOpaque = properties.getBoolean(
NAV_BAR_HANDLE_FORCE_OPAQUE, /* defaultValue = */ true);
}
if (properties.getKeyset().contains(HOME_BUTTON_LONG_PRESS_DURATION_MS)) {
mHomeButtonLongPressDurationMs = Optional.of(
properties.getLong(HOME_BUTTON_LONG_PRESS_DURATION_MS, 0)
).filter(duration -> duration != 0);
reconfigureHomeLongClick();
}
}
};
@@ -510,6 +528,11 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
DeviceConfig.NAMESPACE_SYSTEMUI,
NAV_BAR_HANDLE_FORCE_OPAQUE,
/* defaultValue = */ true);
mHomeButtonLongPressDurationMs = Optional.of(DeviceConfig.getLong(
DeviceConfig.NAMESPACE_SYSTEMUI,
HOME_BUTTON_LONG_PRESS_DURATION_MS,
/* defaultValue = */ 0
)).filter(duration -> duration != 0);
DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_SYSTEMUI, mHandler::post, mOnPropertiesChangedListener);
@@ -769,6 +792,22 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
}
}
private void reconfigureHomeLongClick() {
if (mNavigationBarView == null
|| mNavigationBarView.getHomeButton().getCurrentView() == null) {
return;
}
if (mHomeButtonLongPressDurationMs.isPresent()) {
mNavigationBarView.getHomeButton().getCurrentView().setLongClickable(false);
mNavigationBarView.getHomeButton().getCurrentView().setHapticFeedbackEnabled(false);
mNavigationBarView.getHomeButton().setOnLongClickListener(null);
} else {
mNavigationBarView.getHomeButton().getCurrentView().setLongClickable(true);
mNavigationBarView.getHomeButton().getCurrentView().setHapticFeedbackEnabled(true);
mNavigationBarView.getHomeButton().setOnLongClickListener(this::onHomeLongClick);
}
}
private int deltaRotation(int oldRotation, int newRotation) {
int delta = newRotation - oldRotation;
if (delta < 0) delta += 4;
@@ -779,6 +818,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
pw.println("NavigationBar (displayId=" + mDisplayId + "):");
pw.println(" mStartingQuickSwitchRotation=" + mStartingQuickSwitchRotation);
pw.println(" mCurrentRotation=" + mCurrentRotation);
pw.println(" mHomeButtonLongPressDurationMs=" + mHomeButtonLongPressDurationMs);
if (mNavigationBarView != null) {
pw.println(" mNavigationBarWindowState="
@@ -1108,7 +1148,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
homeButton.setOnTouchListener(this::onHomeTouch);
homeButton.setOnLongClickListener(this::onHomeLongClick);
reconfigureHomeLongClick();
ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
accessibilityButton.setOnClickListener(this::onAccessibilityClick);
@@ -1118,7 +1159,8 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
updateScreenPinningGestures();
}
private boolean onHomeTouch(View v, MotionEvent event) {
@VisibleForTesting
boolean onHomeTouch(View v, MotionEvent event) {
if (mHomeBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
return true;
}
@@ -1138,9 +1180,13 @@ public class NavigationBar implements View.OnAttachStateChangeListener,
return true;
}
}
mHomeButtonLongPressDurationMs.ifPresent(longPressDuration -> {
mHandler.postDelayed(mOnVariableDurationHomeLongClick, longPressDuration);
});
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
mStatusBarLazy.get().awakenDreams();
break;
}

View File

@@ -23,6 +23,7 @@ import static android.inputmethodservice.InputMethodService.IME_VISIBLE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
import static com.android.systemui.navigationbar.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
import static org.junit.Assert.assertEquals;
@@ -31,6 +32,7 @@ import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -44,12 +46,16 @@ import android.content.IntentFilter;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityManager;
@@ -79,6 +85,7 @@ import com.android.systemui.utils.leaks.LeakCheckedTest;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.pip.Pip;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -101,6 +108,7 @@ public class NavigationBarTest extends SysuiTestCase {
private OverviewProxyService mOverviewProxyService;
private CommandQueue mCommandQueue;
private SysUiState mMockSysUiState;
@Mock
private Handler mHandler;
@Mock
private BroadcastDispatcher mBroadcastDispatcher;
@@ -124,12 +132,17 @@ public class NavigationBarTest extends SysuiTestCase {
mDependency.injectMockDependency(NavigationBarController.class);
mOverviewProxyService = mDependency.injectMockDependency(OverviewProxyService.class);
TestableLooper.get(this).runWithLooper(() -> {
mHandler = new Handler();
mNavigationBar = createNavBar(mContext);
mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal);
});
}
@After
public void tearDown() throws Exception {
DeviceConfig.resetToDefaults(
Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI);
}
private void setupSysuiDependency() {
Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY_ID,
new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
@@ -162,6 +175,32 @@ public class NavigationBarTest extends SysuiTestCase {
verify(mUiEventLogger, times(1)).log(NAVBAR_ASSIST_LONGPRESS);
}
@Test
public void testHomeLongPressWithCustomDuration() throws Exception {
DeviceConfig.setProperties(
new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_SYSTEMUI)
.setLong(HOME_BUTTON_LONG_PRESS_DURATION_MS, 100)
.build());
mNavigationBar.onViewAttachedToWindow(mNavigationBar.createView(null));
mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
/*downTime=*/SystemClock.uptimeMillis(),
/*eventTime=*/SystemClock.uptimeMillis(),
/*action=*/MotionEvent.ACTION_DOWN,
0, 0, 0
));
verify(mHandler, times(1)).postDelayed(any(), eq(100L));
mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
/*downTime=*/SystemClock.uptimeMillis(),
/*eventTime=*/SystemClock.uptimeMillis(),
/*action=*/MotionEvent.ACTION_UP,
0, 0, 0
));
verify(mHandler, times(1)).removeCallbacks(any());
}
@Test
public void testRegisteredWithDispatcher() {
mNavigationBar.onViewAttachedToWindow(mNavigationBar.createView(null));