Allow one-handed mode shortcut expand notification
1) Add OneHandedEventCallback for WMShell to register callback, and if one handed mode settings set show notifications, when user tap one handed mode shortcut notify WMShell send KEYCODE_SYSTEM_NAVIGATION_DOWN through OneHandedEventCallback with SysUIMainExecutor. 2) Add isReady() flag in OneHandedDisplayAreaOrganizer and Simplify the flow of onActivatedActionChanged() to prevent potential race problem while auto-enable One-handed and immeditately startOneHanded(), however, DisplayAreaOrganizer#onDisplayAreaAppeared() may not ready for transtion yet, and result mState keep in unfinsihed STATE_ENTERING. 3) Adjust the transiton duration from 800ms to 600ms 800ms is a little bit long to affect timing of apply runtime overlay package. 4) DelayExecute setEnabledGesturalOverlay() until transition finised and at most delay once. - onSwipeToNotificationEnabledChanged() : DelayExecute - onEnabledSettingChanged() : DelayExecute - Ctor setupGesturalOverlay() : No DelayExecute - mState.isTransitioning() : DelayExecute Test: WMShellUnitTests Bug: 182425480 Change-Id: I2615c3b30ad95a858510b4bcc73d8f343843fc96
This commit is contained in:
@@ -40,7 +40,7 @@
|
||||
<integer name="long_press_dock_anim_duration">250</integer>
|
||||
|
||||
<!-- Animation duration for translating of one handed when trigger / dismiss. -->
|
||||
<integer name="config_one_handed_translate_animation_duration">800</integer>
|
||||
<integer name="config_one_handed_translate_animation_duration">600</integer>
|
||||
|
||||
<!-- One handed mode default offset % of display size -->
|
||||
<fraction name="config_one_handed_offset">40%</fraction>
|
||||
|
||||
@@ -67,6 +67,11 @@ public interface OneHanded {
|
||||
*/
|
||||
void setLockedDisabled(boolean locked, boolean enabled);
|
||||
|
||||
/**
|
||||
* Registers callback to notify WMShell when user tap shortcut to expand notification.
|
||||
*/
|
||||
void registerEventCallback(OneHandedEventCallback callback);
|
||||
|
||||
/**
|
||||
* Registers callback to be notified after {@link OneHandedDisplayAreaOrganizer}
|
||||
* transition start or finish
|
||||
|
||||
@@ -43,6 +43,7 @@ import android.util.Slog;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -72,6 +73,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
private static final String ONE_HANDED_MODE_GESTURAL_OVERLAY =
|
||||
"com.android.internal.systemui.onehanded.gestural";
|
||||
private static final int OVERLAY_ENABLED_DELAY_MS = 250;
|
||||
private static final int DISPLAY_AREA_READY_RETRY_MS = 10;
|
||||
|
||||
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
|
||||
|
||||
@@ -99,6 +101,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
private final Handler mMainHandler;
|
||||
private final OneHandedImpl mImpl = new OneHandedImpl();
|
||||
|
||||
private OneHandedEventCallback mEventCallback;
|
||||
private OneHandedDisplayAreaOrganizer mDisplayAreaOrganizer;
|
||||
private OneHandedBackgroundPanelOrganizer mBackgroundPanelOrganizer;
|
||||
|
||||
@@ -288,7 +291,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
mTimeoutObserver = getObserver(this::onTimeoutSettingChanged);
|
||||
mTaskChangeExitObserver = getObserver(this::onTaskChangeExitSettingChanged);
|
||||
mSwipeToNotificationEnabledObserver =
|
||||
getObserver(this::onSwipeToNotificationEnabledSettingChanged);
|
||||
getObserver(this::onSwipeToNotificationEnabledChanged);
|
||||
|
||||
mDisplayController.addDisplayChangingController(mRotationController);
|
||||
setupCallback();
|
||||
@@ -358,14 +361,23 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
Slog.d(TAG, "Temporary lock disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mDisplayAreaOrganizer.isReady()) {
|
||||
// Must wait until DisplayAreaOrganizer is ready for transitioning.
|
||||
mMainExecutor.executeDelayed(this::startOneHanded, DISPLAY_AREA_READY_RETRY_MS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mState.isTransitioning() || mState.isInOneHanded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int currentRotation = mDisplayAreaOrganizer.getDisplayLayout().rotation();
|
||||
if (currentRotation != Surface.ROTATION_0 && currentRotation != Surface.ROTATION_180) {
|
||||
Slog.w(TAG, "One handed mode only support portrait mode");
|
||||
return;
|
||||
}
|
||||
|
||||
mState.setState(STATE_ENTERING);
|
||||
final int yOffSet = Math.round(
|
||||
mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction);
|
||||
@@ -394,6 +406,10 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
mOneHandedUiEventLogger.writeEvent(uiEvent);
|
||||
}
|
||||
|
||||
void registerEventCallback(OneHandedEventCallback callback) {
|
||||
mEventCallback = callback;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void registerTransitionCallback(OneHandedTransitionCallback callback) {
|
||||
mDisplayAreaOrganizer.registerTransitionCallback(callback);
|
||||
@@ -463,9 +479,30 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
};
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void notifyExpandNotification() {
|
||||
mMainExecutor.execute(() -> mEventCallback.notifyExpandNotification());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void notifyUserConfigChanged(boolean success) {
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
// TODO Check UX if popup Toast to notify user when auto-enabled one-handed is good option.
|
||||
Toast.makeText(mContext, R.string.one_handed_tutorial_title, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void onActivatedActionChanged() {
|
||||
if (mState.isTransitioning() || !isOneHandedEnabled()) {
|
||||
if (!isOneHandedEnabled()) {
|
||||
final boolean success = mOneHandedSettingsUtil.setOneHandedModeEnabled(
|
||||
mContext.getContentResolver(), 1 /* Enabled for shortcut */, mUserId);
|
||||
notifyUserConfigChanged(success);
|
||||
}
|
||||
|
||||
if (isSwipeToNotificationEnabled()) {
|
||||
notifyExpandNotification();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -494,11 +531,9 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
setOneHandedEnabled(enabled);
|
||||
|
||||
// Also checks swipe to notification settings since they all need gesture overlay.
|
||||
// Enabled overlay package may affect the current animation(e.g:Settings switch),
|
||||
// so we delay 250ms to enabled overlay after switch animation finish
|
||||
mMainExecutor.executeDelayed(() -> setEnabledGesturalOverlay(
|
||||
setEnabledGesturalOverlay(
|
||||
enabled || mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
|
||||
mContext.getContentResolver(), mUserId)), OVERLAY_ENABLED_DELAY_MS);
|
||||
mContext.getContentResolver(), mUserId), true /* DelayExecute */);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -542,7 +577,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void onSwipeToNotificationEnabledSettingChanged() {
|
||||
void onSwipeToNotificationEnabledChanged() {
|
||||
final boolean enabled =
|
||||
mOneHandedSettingsUtil.getSettingsSwipeToNotificationEnabled(
|
||||
mContext.getContentResolver(), mUserId);
|
||||
@@ -551,7 +586,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
// Also checks one handed mode settings since they all need gesture overlay.
|
||||
setEnabledGesturalOverlay(
|
||||
enabled || mOneHandedSettingsUtil.getSettingsOneHandedModeEnabled(
|
||||
mContext.getContentResolver(), mUserId));
|
||||
mContext.getContentResolver(), mUserId), true /* DelayExecute */);
|
||||
}
|
||||
|
||||
private void setupTimeoutListener() {
|
||||
@@ -569,11 +604,19 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
return mIsOneHandedEnabled;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isSwipeToNotificationEnabled() {
|
||||
return mIsSwipeToNotificationEnabled;
|
||||
}
|
||||
|
||||
private void updateOneHandedEnabled() {
|
||||
if (mState.getState() == STATE_ENTERING || mState.getState() == STATE_ACTIVE) {
|
||||
mMainExecutor.execute(() -> stopOneHanded());
|
||||
}
|
||||
|
||||
// Reset and align shortcut one_handed_mode_activated status with current mState
|
||||
notifyShortcutState(mState.getState());
|
||||
|
||||
mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled);
|
||||
|
||||
if (!mIsOneHandedEnabled) {
|
||||
@@ -608,12 +651,19 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
|
||||
if (info != null && !info.isEnabled()) {
|
||||
// Enable the default gestural one handed overlay.
|
||||
setEnabledGesturalOverlay(true);
|
||||
setEnabledGesturalOverlay(true /* enabled */, false /* delayExecute */);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
private void setEnabledGesturalOverlay(boolean enabled) {
|
||||
private void setEnabledGesturalOverlay(boolean enabled, boolean delayExecute) {
|
||||
if (mState.isTransitioning() || delayExecute) {
|
||||
// Enabled overlay package may affect the current animation(e.g:Settings switch),
|
||||
// so we delay 250ms to enabled overlay after switch animation finish, only delay once.
|
||||
mMainExecutor.executeDelayed(() -> setEnabledGesturalOverlay(enabled, false),
|
||||
OVERLAY_ENABLED_DELAY_MS);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mOverlayManager.setEnabled(ONE_HANDED_MODE_GESTURAL_OVERLAY, enabled, USER_CURRENT);
|
||||
} catch (RemoteException e) {
|
||||
@@ -628,6 +678,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
if (enabled == isFeatureEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLockedDisabled = locked && !enabled;
|
||||
}
|
||||
|
||||
@@ -760,6 +811,13 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEventCallback(OneHandedEventCallback callback) {
|
||||
mMainExecutor.execute(() -> {
|
||||
OneHandedController.this.registerEventCallback(callback);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTransitionCallback(OneHandedTransitionCallback callback) {
|
||||
mMainExecutor.execute(() -> {
|
||||
|
||||
@@ -61,11 +61,12 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
|
||||
|
||||
private DisplayLayout mDisplayLayout = new DisplayLayout();
|
||||
|
||||
private float mLastVisualOffset = 0;
|
||||
private final Rect mLastVisualDisplayBounds = new Rect();
|
||||
private final Rect mDefaultDisplayBounds = new Rect();
|
||||
private final OneHandedSettingsUtil mOneHandedSettingsUtil;
|
||||
|
||||
private boolean mIsReady;
|
||||
private float mLastVisualOffset = 0;
|
||||
private int mEnterExitAnimationDurationMs;
|
||||
|
||||
private ArrayMap<WindowContainerToken, SurfaceControl> mDisplayAreaTokenMap = new ArrayMap();
|
||||
@@ -157,6 +158,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
|
||||
final DisplayAreaAppearedInfo info = displayAreaInfos.get(i);
|
||||
onDisplayAreaAppeared(info.getDisplayAreaInfo(), info.getLeash());
|
||||
}
|
||||
mIsReady = true;
|
||||
updateDisplayBounds();
|
||||
return displayAreaInfos;
|
||||
}
|
||||
@@ -164,9 +166,14 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
|
||||
@Override
|
||||
public void unregisterOrganizer() {
|
||||
super.unregisterOrganizer();
|
||||
mIsReady = false;
|
||||
resetWindowsOffset();
|
||||
}
|
||||
|
||||
boolean isReady() {
|
||||
return mIsReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for display rotation changes by {@link DisplayLayout}
|
||||
*
|
||||
@@ -312,6 +319,8 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
|
||||
pw.println(mDisplayAreaTokenMap);
|
||||
pw.print(innerPrefix + "mDefaultDisplayBounds=");
|
||||
pw.println(mDefaultDisplayBounds);
|
||||
pw.print(innerPrefix + "mIsReady=");
|
||||
pw.println(mIsReady);
|
||||
pw.print(innerPrefix + "mLastVisualDisplayBounds=");
|
||||
pw.println(mLastVisualDisplayBounds);
|
||||
pw.print(innerPrefix + "mLastVisualOffset=");
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.wm.shell.onehanded;
|
||||
|
||||
/**
|
||||
* Additional callback interface for OneHanded events.
|
||||
*/
|
||||
public interface OneHandedEventCallback {
|
||||
/**
|
||||
* Called to notify expand notification shade.
|
||||
*/
|
||||
default void notifyExpandNotification() {
|
||||
}
|
||||
}
|
||||
@@ -104,6 +104,17 @@ public final class OneHandedSettingsUtil {
|
||||
Settings.Secure.ONE_HANDED_MODE_ENABLED, 0 /* Disabled */, userId) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets one handed enable or disable flag from Settings provider.
|
||||
*
|
||||
* @return true if the value was set, false on database errors
|
||||
*/
|
||||
public boolean setOneHandedModeEnabled(ContentResolver resolver, int enabled, int userId) {
|
||||
return Settings.Secure.putIntForUser(resolver,
|
||||
Settings.Secure.ONE_HANDED_MODE_ENABLED, enabled, userId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Queries taps app to exit config from Settings provider.
|
||||
*
|
||||
|
||||
@@ -74,6 +74,8 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
@Mock
|
||||
OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer;
|
||||
@Mock
|
||||
OneHandedEventCallback mMockEventCallback;
|
||||
@Mock
|
||||
OneHandedTouchHandler mMockTouchHandler;
|
||||
@Mock
|
||||
OneHandedTutorialHandler mMockTutorialHandler;
|
||||
@@ -106,6 +108,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
|
||||
when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay);
|
||||
when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>());
|
||||
when(mMockDisplayAreaOrganizer.isReady()).thenReturn(true);
|
||||
when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash);
|
||||
when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn(
|
||||
mDefaultEnabled);
|
||||
@@ -241,7 +244,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
|
||||
@Test
|
||||
public void testSettingsObserverUpdateSwipeToNotification() {
|
||||
mSpiedOneHandedController.onSwipeToNotificationEnabledSettingChanged();
|
||||
mSpiedOneHandedController.onSwipeToNotificationEnabledChanged();
|
||||
|
||||
verify(mSpiedOneHandedController).setSwipeToNotificationEnabled(anyBoolean());
|
||||
}
|
||||
@@ -311,6 +314,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
final DisplayLayout testDisplayLayout = new DisplayLayout(mDisplayLayout);
|
||||
testDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180);
|
||||
mSpiedTransitionState.setState(STATE_NONE);
|
||||
when(mMockDisplayAreaOrganizer.isReady()).thenReturn(true);
|
||||
when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(testDisplayLayout);
|
||||
mSpiedOneHandedController.setOneHandedEnabled(true);
|
||||
mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */);
|
||||
@@ -372,8 +376,7 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
|
||||
mSpiedOneHandedController.onActivatedActionChanged();
|
||||
|
||||
verify(mSpiedOneHandedController, never()).startOneHanded();
|
||||
verify(mSpiedOneHandedController, never()).stopOneHanded();
|
||||
verify(mSpiedTransitionState, never()).setState(STATE_EXITING);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -383,20 +386,20 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
|
||||
mSpiedOneHandedController.onActivatedActionChanged();
|
||||
|
||||
verify(mSpiedOneHandedController, never()).startOneHanded();
|
||||
verify(mSpiedOneHandedController, never()).stopOneHanded();
|
||||
verify(mSpiedTransitionState, never()).setState(STATE_ENTERING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneHandedDisabled_shortcutEnabled_skipActions() {
|
||||
public void testOneHandedDisabled_shortcutTrigger_thenAutoEnabled() {
|
||||
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
|
||||
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
|
||||
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
|
||||
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(true);
|
||||
when(mMockSettingsUitl.getOneHandedModeActivated(any(), anyInt())).thenReturn(false);
|
||||
when(mMockSettingsUitl.setOneHandedModeEnabled(any(), anyInt(), anyInt())).thenReturn(
|
||||
false);
|
||||
mSpiedOneHandedController.onActivatedActionChanged();
|
||||
|
||||
verify(mSpiedOneHandedController, never()).startOneHanded();
|
||||
verify(mSpiedOneHandedController, never()).stopOneHanded();
|
||||
verify(mSpiedOneHandedController).notifyUserConfigChanged(anyBoolean());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -408,4 +411,28 @@ public class OneHandedControllerTest extends OneHandedTestCase {
|
||||
|
||||
verify(mSpiedTransitionState).addSListeners(mMockTutorialHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyEventCallbackWithMainExecutor() {
|
||||
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(true);
|
||||
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
|
||||
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
|
||||
when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true);
|
||||
mSpiedOneHandedController.registerEventCallback(mMockEventCallback);
|
||||
mSpiedOneHandedController.onActivatedActionChanged();
|
||||
|
||||
verify(mMockShellMainExecutor).execute(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifyShortcutState_whenUpdateOneHandedEnabled() {
|
||||
when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false);
|
||||
when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE);
|
||||
when(mSpiedTransitionState.isTransitioning()).thenReturn(false);
|
||||
when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true);
|
||||
mSpiedOneHandedController.registerEventCallback(mMockEventCallback);
|
||||
mSpiedOneHandedController.setOneHandedEnabled(true);
|
||||
|
||||
verify(mSpiedOneHandedController).notifyShortcutState(anyInt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,4 +418,18 @@ public class OneHandedDisplayAreaOrganizerTest extends OneHandedTestCase {
|
||||
|
||||
verify(mSpiedDisplayAreaOrganizer, never()).resetWindowsOffset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayArea_notReadyForTransition() {
|
||||
OneHandedDisplayAreaOrganizer testSpiedDisplayAreaOrganizer = spy(
|
||||
new OneHandedDisplayAreaOrganizer(mContext,
|
||||
mDisplayLayout,
|
||||
mMockSettingsUitl,
|
||||
mMockAnimationController,
|
||||
mTutorialHandler,
|
||||
mMockBackgroundOrganizer,
|
||||
mMockShellMainExecutor));
|
||||
|
||||
assertThat(testSpiedDisplayAreaOrganizer.isReady()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.inputmethodservice.InputMethodService;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
@@ -57,6 +58,7 @@ import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
|
||||
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
import com.android.wm.shell.nano.WmShellTraceProto;
|
||||
import com.android.wm.shell.onehanded.OneHanded;
|
||||
import com.android.wm.shell.onehanded.OneHandedEventCallback;
|
||||
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
|
||||
import com.android.wm.shell.onehanded.OneHandedUiEventLogger;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
@@ -253,6 +255,15 @@ public final class WMShell extends SystemUI
|
||||
}
|
||||
});
|
||||
|
||||
oneHanded.registerEventCallback(new OneHandedEventCallback() {
|
||||
@Override
|
||||
public void notifyExpandNotification() {
|
||||
mSysUiMainExecutor.execute(
|
||||
() -> mCommandQueue.handleSystemKey(
|
||||
KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN));
|
||||
}
|
||||
});
|
||||
|
||||
mOneHandedKeyguardCallback = new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onKeyguardBouncerChanged(boolean bouncer) {
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
|
||||
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
|
||||
import com.android.wm.shell.onehanded.OneHanded;
|
||||
import com.android.wm.shell.onehanded.OneHandedEventCallback;
|
||||
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
|
||||
import com.android.wm.shell.pip.Pip;
|
||||
|
||||
@@ -106,6 +107,7 @@ public class WMShellTest extends SysuiTestCase {
|
||||
verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
|
||||
verify(mScreenLifecycle).addObserver(any(ScreenLifecycle.Observer.class));
|
||||
verify(mOneHanded).registerTransitionCallback(any(OneHandedTransitionCallback.class));
|
||||
verify(mOneHanded).registerEventCallback(any(OneHandedEventCallback.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user