Handle the phone get booted case to show accessibility floating menu
* AccessibilityManager might not ready when the phone just got booted.
Cherry picked from commit bf0ab7163d
Bug: 173940864
Test: atest AccessibilityFloatingMenuControllerTest
Change-Id: I0339597cd53ca5daade427fef257bfddb3b86bd8
Merged-In: I0339597cd53ca5daade427fef257bfddb3b86bd8
This commit is contained in:
@@ -20,6 +20,7 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATIN
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.annotation.MainThread;
|
||||
|
||||
@@ -36,9 +37,11 @@ import javax.inject.Inject;
|
||||
@SysUISingleton
|
||||
public class AccessibilityFloatingMenuController implements
|
||||
AccessibilityButtonModeObserver.ModeChangedListener,
|
||||
AccessibilityButtonTargetsObserver.TargetsChangedListener {
|
||||
AccessibilityButtonTargetsObserver.TargetsChangedListener,
|
||||
AccessibilityManager.AccessibilityStateChangeListener {
|
||||
|
||||
private final Context mContext;
|
||||
private final AccessibilityManager mAccessibilityManager;
|
||||
private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
|
||||
private final AccessibilityButtonTargetsObserver mAccessibilityButtonTargetsObserver;
|
||||
|
||||
@@ -54,13 +57,21 @@ public class AccessibilityFloatingMenuController implements
|
||||
mContext = context;
|
||||
mAccessibilityButtonTargetsObserver = accessibilityButtonTargetsObserver;
|
||||
mAccessibilityButtonModeObserver = accessibilityButtonModeObserver;
|
||||
mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
|
||||
|
||||
mAccessibilityButtonModeObserver.addListener(this);
|
||||
mAccessibilityButtonTargetsObserver.addListener(this);
|
||||
mBtnMode = mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode();
|
||||
mBtnTargets = mAccessibilityButtonTargetsObserver.getCurrentAccessibilityButtonTargets();
|
||||
|
||||
handleFloatingMenuVisibility(mBtnMode, mBtnTargets);
|
||||
// Accessibility floating menu widget needs accessibility service to work, but system
|
||||
// accessibility might be unavailable during the phone get booted, hence it needs to wait
|
||||
// for accessibility manager callback to work.
|
||||
mAccessibilityManager.addAccessibilityStateChangeListener(this);
|
||||
if (mAccessibilityManager.isEnabled()) {
|
||||
handleFloatingMenuVisibility(mBtnMode, mBtnTargets);
|
||||
mAccessibilityManager.removeAccessibilityStateChangeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,6 +97,23 @@ public class AccessibilityFloatingMenuController implements
|
||||
handleFloatingMenuVisibility(mBtnMode, mBtnTargets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles visibility of the accessibility floating menu when system accessibility state
|
||||
* changes.
|
||||
* If system accessibility become available onAccessibilityStateChanged(true), then we don't
|
||||
* need to listen to this listener anymore.
|
||||
*
|
||||
* @param enabled Whether accessibility is enabled.
|
||||
*/
|
||||
@Override
|
||||
public void onAccessibilityStateChanged(boolean enabled) {
|
||||
if (enabled) {
|
||||
handleFloatingMenuVisibility(mBtnMode, mBtnTargets);
|
||||
}
|
||||
|
||||
mAccessibilityManager.removeAccessibilityStateChangeListener(this);
|
||||
}
|
||||
|
||||
private void handleFloatingMenuVisibility(@AccessibilityButtonMode int mode, String targets) {
|
||||
if (shouldShowFloatingMenu(mode, targets)) {
|
||||
showFloatingMenu();
|
||||
|
||||
@@ -24,10 +24,12 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.provider.Settings;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
@@ -36,8 +38,12 @@ import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
|
||||
import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
/** Test for {@link AccessibilityFloatingMenuController}. */
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@@ -47,9 +53,14 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
|
||||
|
||||
private static final String TEST_A11Y_BTN_TARGETS = "Magnification";
|
||||
|
||||
@Rule
|
||||
public MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
private AccessibilityFloatingMenuController mController;
|
||||
private AccessibilityButtonTargetsObserver mTargetsObserver;
|
||||
private AccessibilityButtonModeObserver mModeObserver;
|
||||
@Mock
|
||||
private AccessibilityManager mMockA11yManager;
|
||||
|
||||
@Test
|
||||
public void initController_registerListeners() {
|
||||
@@ -59,6 +70,37 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
|
||||
any(AccessibilityButtonTargetsObserver.TargetsChangedListener.class));
|
||||
verify(mModeObserver).addListener(
|
||||
any(AccessibilityButtonModeObserver.ModeChangedListener.class));
|
||||
verify(mMockA11yManager).addAccessibilityStateChangeListener(any(
|
||||
AccessibilityManager.AccessibilityStateChangeListener.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initController_accessibilityManagerEnabled_showWidget() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS);
|
||||
when(mMockA11yManager.isEnabled()).thenReturn(true);
|
||||
|
||||
mController = setUpController();
|
||||
|
||||
assertThat(mController.mFloatingMenu).isNotNull();
|
||||
verify(mMockA11yManager).removeAccessibilityStateChangeListener(mController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initController_accessibilityManagerDisabledThenCallbackToEnabled_showWidget() {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU);
|
||||
Settings.Secure.putString(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, TEST_A11Y_BTN_TARGETS);
|
||||
when(mMockA11yManager.isEnabled()).thenReturn(false);
|
||||
|
||||
mController = setUpController();
|
||||
mController.onAccessibilityStateChanged(true);
|
||||
|
||||
assertThat(mController.mFloatingMenu).isNotNull();
|
||||
verify(mMockA11yManager).removeAccessibilityStateChangeListener(mController);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -154,7 +196,9 @@ public class AccessibilityFloatingMenuControllerTest extends SysuiTestCase {
|
||||
private AccessibilityFloatingMenuController setUpController() {
|
||||
mTargetsObserver = spy(Dependency.get(AccessibilityButtonTargetsObserver.class));
|
||||
mModeObserver = spy(Dependency.get(AccessibilityButtonModeObserver.class));
|
||||
mContext.addMockSystemService(AccessibilityManager.class, mMockA11yManager);
|
||||
|
||||
return new AccessibilityFloatingMenuController(mContext, mTargetsObserver, mModeObserver);
|
||||
return new AccessibilityFloatingMenuController(mContext, mTargetsObserver,
|
||||
mModeObserver);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user