From 03dbb40d2baa8797f600fdd8139e5e87a241a732 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Fri, 12 Feb 2021 00:49:51 +0800 Subject: [PATCH 01/10] Setup basic layout and resources for the accessibility button settings page cherry picked from commit 93ef33655c53ccefd782b51f9743eee3fc0abb62 Bug: 173940869 Test: atest AccessibilityButtonFragmentTest Change-Id: I3f1d8b161d1baadeead36f49f18f00a91fd40b4c Merged-In: I3f1d8b161d1baadeead36f49f18f00a91fd40b4c --- res/values/arrays.xml | 32 +++++++++++ res/values/strings.xml | 20 +++++++ res/xml/accessibility_button_settings.xml | 57 +++++++++++++++++++ res/xml/accessibility_shortcuts_settings.xml | 7 +++ .../AccessibilityButtonFragment.java | 55 ++++++++++++++++++ .../AccessibilityButtonFragmentTest.java | 50 ++++++++++++++++ 6 files changed, 221 insertions(+) create mode 100644 res/xml/accessibility_button_settings.xml create mode 100644 src/com/android/settings/accessibility/AccessibilityButtonFragment.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 183dd1e579d..2d03c11227e 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -966,6 +966,38 @@ -1 + + + Floating over other apps + Navigation bar + + + + + + + 1 + + 0 + + + + + Small + Large + Half Circle + + + + + + 0 + + 1 + + 2 + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 91867dc9e3d..a9f860acbad 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5164,6 +5164,26 @@ Shortcut from lock screen Allow feature shortcut to turn on from the lock screen. Hold both volume keys for a few seconds. + + Accessibility button + + Quickly access accessibility features + + Quickly access accessibility features from any screen. \n\nTo get started, go to accessibility settings and select a feature. Tap on the shortcut and select the accessibility button. + + Location + + Size + + Fade when not in use + + Fades after a few seconds so it\u2019s easier to see your screen + + Transparency when not in use + + Transparent + + Non-transparent High contrast text diff --git a/res/xml/accessibility_button_settings.xml b/res/xml/accessibility_button_settings.xml new file mode 100644 index 00000000000..7bb534f3fbb --- /dev/null +++ b/res/xml/accessibility_button_settings.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/xml/accessibility_shortcuts_settings.xml b/res/xml/accessibility_shortcuts_settings.xml index 35314e708bb..465f96d74df 100644 --- a/res/xml/accessibility_shortcuts_settings.xml +++ b/res/xml/accessibility_shortcuts_settings.xml @@ -21,6 +21,13 @@ android:persistent="false" android:title="@string/accessibility_shortcuts_settings_title"> + + niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + final List keys = + XmlTestUtils.getKeysFromPreferenceXml(mContext, + R.xml.accessibility_button_settings); + + assertThat(keys).containsAtLeastElementsIn(niks); + } +} From 2dc32f63f81fdffea0b7a7bf001b480c0eda1384 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Wed, 17 Feb 2021 17:07:43 +0800 Subject: [PATCH 02/10] Add the preference controller to control accessibility button location preference cherry picked from commit 123464429dbe0e677a4cb9118e436444bd575061 Bug: 173940869 Test: atest AccessibilityButtonLocationPreferenceControllerTest Change-Id: I49a23b2eb4e07e79afcefc5a148c23b06396ec1c Merged-In: I49a23b2eb4e07e79afcefc5a148c23b06396ec1c --- res/xml/accessibility_button_settings.xml | 3 +- ...ityButtonLocationPreferenceController.java | 89 +++++++++++++++ ...uttonLocationPreferenceControllerTest.java | 106 ++++++++++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceControllerTest.java diff --git a/res/xml/accessibility_button_settings.xml b/res/xml/accessibility_button_settings.xml index 7bb534f3fbb..2fa2e0d0938 100644 --- a/res/xml/accessibility_button_settings.xml +++ b/res/xml/accessibility_button_settings.xml @@ -25,7 +25,8 @@ android:key="accessibility_button_location" android:title="@string/accessibility_button_location_title" android:summary="%s" - android:persistent="false"/> + android:persistent="false" + settings:controller="com.android.settings.accessibility.AccessibilityButtonLocationPreferenceController"/> mValueTitleMap = new ArrayMap<>(); + private int mDefaultLocation; + + public AccessibilityButtonLocationPreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + initValueTitleMap(); + } + + @Override + public int getAvailabilityStatus() { + return AccessibilityUtil.isGestureNavigateEnabled(mContext) + ? DISABLED_DEPENDENT_SETTING : AVAILABLE; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final ListPreference listPreference = (ListPreference) preference; + final Integer value = Ints.tryParse((String) newValue); + if (value != null) { + Settings.Secure.putInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_BUTTON_MODE, value); + updateState(listPreference); + } + return true; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + final ListPreference listPreference = (ListPreference) preference; + + listPreference.setValue(getCurrentAccessibilityButtonMode()); + } + + private String getCurrentAccessibilityButtonMode() { + final int mode = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mDefaultLocation); + return String.valueOf(mode); + } + + private void initValueTitleMap() { + if (mValueTitleMap.size() == 0) { + final String[] values = mContext.getResources().getStringArray( + R.array.accessibility_button_location_selector_values); + final String[] titles = mContext.getResources().getStringArray( + R.array.accessibility_button_location_selector_titles); + final int mapSize = values.length; + + mDefaultLocation = Integer.parseInt(values[0]); + for (int i = 0; i < mapSize; i++) { + mValueTitleMap.put(values[i], titles[i]); + } + } + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceControllerTest.java new file mode 100644 index 00000000000..a67038a6b2d --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonLocationPreferenceControllerTest.java @@ -0,0 +1,106 @@ +/* + * 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.settings.accessibility; + +import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; +import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; +import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; +import android.provider.Settings; + +import androidx.preference.ListPreference; +import androidx.test.core.app.ApplicationProvider; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; + +/** Tests for {@link AccessibilityButtonLocationPreferenceController}. */ +@RunWith(RobolectricTestRunner.class) +public class AccessibilityButtonLocationPreferenceControllerTest { + + @Rule + public final MockitoRule mockito = MockitoJUnit.rule(); + + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Spy + private final Resources mResources = mContext.getResources(); + private final ContentResolver mContentResolver = mContext.getContentResolver(); + private final ListPreference mListPreference = new ListPreference(mContext); + private AccessibilityButtonLocationPreferenceController mController; + + + @Before + public void setUp() { + mController = new AccessibilityButtonLocationPreferenceController(mContext, + "test_key"); + when(mContext.getResources()).thenReturn(mResources); + } + + @Test + public void getAvailabilityStatus_navigationGestureEnabled_returnDisabledDependentSetting() { + when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode)) + .thenReturn(NAV_BAR_MODE_GESTURAL); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_navigationGestureDisabled_returnAvailable() { + when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode)) + .thenReturn(NAV_BAR_MODE_2BUTTON); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void updateState_a11yBtnModeNavigationBar_navigationBarValue() { + Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE, + ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR); + + mController.updateState(mListPreference); + + final String navigationBarValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR); + assertThat(mListPreference.getValue()).isEqualTo(navigationBarValue); + } + + @Test + public void onPreferenceChange_a11yBtnModeFloatingMenu_floatingMenuValue() { + final String floatingMenuValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU); + + mController.onPreferenceChange(mListPreference, floatingMenuValue); + + assertThat(mListPreference.getValue()).isEqualTo(floatingMenuValue); + } +} From 0377025554e748c2b30cde923d38e1bc728ca565 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Thu, 18 Feb 2021 00:49:43 +0800 Subject: [PATCH 03/10] Add the preference controller to control accessibility button size preference cherry picked from commit 04955b96aea80194ae979912f87eac1e1ec6a9d3 Bug: 173940869 Test: atest FloatingMenuSizePreferenceControllerTest Change-Id: Ic206a940abde90641442df37a634c8cb3a345597 Merged-In: Ic206a940abde90641442df37a634c8cb3a345597 --- res/xml/accessibility_button_settings.xml | 3 +- .../accessibility/AccessibilityUtil.java | 8 + .../FloatingMenuSizePreferenceController.java | 199 ++++++++++++++++++ ...atingMenuSizePreferenceControllerTest.java | 145 +++++++++++++ 4 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/FloatingMenuSizePreferenceControllerTest.java diff --git a/res/xml/accessibility_button_settings.xml b/res/xml/accessibility_button_settings.xml index 2fa2e0d0938..e348b77ffb0 100644 --- a/res/xml/accessibility_button_settings.xml +++ b/res/xml/accessibility_button_settings.xml @@ -34,7 +34,8 @@ android:key="accessibility_button_size" android:title="@string/accessibility_button_size_title" android:summary="%s" - android:persistent="false"/> + android:persistent="false" + settings:controller="com.android.settings.accessibility.FloatingMenuSizePreferenceController"/> mValueTitleMap = new ArrayMap<>(); + private int mDefaultSize; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + Size.SMALL, + Size.LARGE, + Size.EDGE + }) + @VisibleForTesting + @interface Size { + int SMALL = 0; + int LARGE = 1; + int EDGE = 2; + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + EdgeMode.FULL_CIRCLE, + EdgeMode.HALF_CIRCLE, + }) + @VisibleForTesting + @interface EdgeMode { + int FULL_CIRCLE = 0; + int HALF_CIRCLE = 1; + } + + public FloatingMenuSizePreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + mContentResolver = context.getContentResolver(); + mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { + @Override + public void onChange(boolean selfChange) { + updateAvailabilityStatus(); + } + }; + + initValueTitleMap(); + } + + @Override + public int getAvailabilityStatus() { + return AccessibilityUtil.isFloatingMenuEnabled(mContext) + ? AVAILABLE : DISABLED_DEPENDENT_SETTING; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final ListPreference listPreference = (ListPreference) preference; + final Integer value = Ints.tryParse((String) newValue); + if (value != null) { + writeToFloatingMenuSettings(value); + updateState(listPreference); + } + return true; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + final ListPreference listPreference = (ListPreference) preference; + + listPreference.setValue(getCurrentAccessibilityButtonSize()); + } + + @Override + public void onResume() { + mContentResolver.registerContentObserver( + Settings.Secure.getUriFor( + Settings.Secure.ACCESSIBILITY_BUTTON_MODE), /* notifyForDescendants= */ + false, mContentObserver); + + } + + @Override + public void onPause() { + mContentResolver.unregisterContentObserver(mContentObserver); + } + + private void updateAvailabilityStatus() { + mPreference.setEnabled(AccessibilityUtil.isFloatingMenuEnabled(mContext)); + } + + private void initValueTitleMap() { + if (mValueTitleMap.size() == 0) { + final String[] values = mContext.getResources().getStringArray( + R.array.accessibility_button_size_selector_values); + final String[] titles = mContext.getResources().getStringArray( + R.array.accessibility_button_size_selector_titles); + final int mapSize = values.length; + + mDefaultSize = Integer.parseInt(values[0]); + for (int i = 0; i < mapSize; i++) { + mValueTitleMap.put(values[i], titles[i]); + } + } + } + + private void writeToFloatingMenuSettings(@Size int sizeValue) { + if (sizeValue == Size.EDGE) { + putAccessibilityFloatingMenuSize(Size.SMALL); + putAccessibilityFloatingMenuIconType(EdgeMode.HALF_CIRCLE); + } else { + putAccessibilityFloatingMenuSize(sizeValue); + putAccessibilityFloatingMenuIconType(EdgeMode.FULL_CIRCLE); + } + } + + private String getCurrentAccessibilityButtonSize() { + final @EdgeMode int iconType = getAccessibilityFloatingMenuIconType(EdgeMode.FULL_CIRCLE); + final @Size int btnSize = getAccessibilityFloatingMenuSize(mDefaultSize); + + return (iconType == EdgeMode.HALF_CIRCLE) + ? String.valueOf(Size.EDGE) : String.valueOf(btnSize); + } + + @Size + private int getAccessibilityFloatingMenuSize(@Size int defaultValue) { + return Settings.Secure.getInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, defaultValue); + } + + private void putAccessibilityFloatingMenuSize(@Size int value) { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, value); + } + + @EdgeMode + private int getAccessibilityFloatingMenuIconType(@EdgeMode int defaultValue) { + return Settings.Secure.getInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, defaultValue); + } + + private void putAccessibilityFloatingMenuIconType(@EdgeMode int value) { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, value); + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/FloatingMenuSizePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/FloatingMenuSizePreferenceControllerTest.java new file mode 100644 index 00000000000..70257ca6931 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/FloatingMenuSizePreferenceControllerTest.java @@ -0,0 +1,145 @@ +/* + * 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.settings.accessibility; + +import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; +import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.provider.Settings; + +import androidx.preference.ListPreference; +import androidx.test.core.app.ApplicationProvider; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; + +/** Tests for {@link FloatingMenuSizePreferenceController}. */ +@RunWith(RobolectricTestRunner.class) +public class FloatingMenuSizePreferenceControllerTest { + + @Rule + public MockitoRule mocks = MockitoJUnit.rule(); + + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + private ContentResolver mContentResolver; + private final ListPreference mListPreference = new ListPreference(mContext); + private FloatingMenuSizePreferenceController mController; + + @Before + public void setUp() { + when(mContext.getContentResolver()).thenReturn(mContentResolver); + mController = new FloatingMenuSizePreferenceController(mContext, "test_key"); + } + + @Test + public void getAvailabilityStatus_a11yBtnModeFloatingMenu_returnAvailable() { + Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE, + ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void getAvailabilityStatus_a11yBtnModeNavigationBar_returnDisabledDependentSetting() { + Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE, + ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); + } + + @Test + public void updateState_floatingMenuLargeSizeAndFullCircle_largeSizeValue() { + Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, + FloatingMenuSizePreferenceController.Size.LARGE); + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, + FloatingMenuSizePreferenceController.EdgeMode.FULL_CIRCLE); + + mController.updateState(mListPreference); + + final String largeSize = String.valueOf(FloatingMenuSizePreferenceController.Size.LARGE); + assertThat(mListPreference.getValue()).isEqualTo(largeSize); + } + + @Test + public void updateState_floatingMenuHalfCircle_edgeSizeValue() { + Settings.Secure.putInt(mContentResolver, + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, + FloatingMenuSizePreferenceController.EdgeMode.HALF_CIRCLE); + + mController.updateState(mListPreference); + + final String edgeSize = String.valueOf(FloatingMenuSizePreferenceController.Size.EDGE); + assertThat(mListPreference.getValue()).isEqualTo(edgeSize); + } + + @Test + public void onPreferenceChange_floatingMenuEdgeSize_edgeSizeValue() { + final String edgeSize = String.valueOf( + FloatingMenuSizePreferenceController.Size.EDGE); + + mController.onPreferenceChange(mListPreference, edgeSize); + + assertThat(mListPreference.getValue()).isEqualTo(edgeSize); + } + + @Test + public void onChange_a11yBtnModeChangeToNavigationBar_preferenceDisabled() { + mController.mPreference = mListPreference; + Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE, + ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR); + + mController.mContentObserver.onChange(false); + + assertThat(mController.mPreference.isEnabled()).isFalse(); + } + + @Test + public void onResume_registerSpecificContentObserver() { + mController.onResume(); + + verify(mContentResolver).registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE), false, + mController.mContentObserver); + } + + @Test + public void onPause_unregisterContentObserver() { + mController.onPause(); + + verify(mContentResolver).unregisterContentObserver(mController.mContentObserver); + } +} From c72fe39597381b6d1969096a98e4078ec8f982b3 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Thu, 18 Feb 2021 03:29:26 +0800 Subject: [PATCH 04/10] Add the preference controller to control accessibility button opacity preference cherry picked from commit c497c7aabeb004b5d1ace57a9cfe164f9ecfa597 Bug: 173940869 Test: atest FloatingMenuOpacityPreferenceControllerTest Change-Id: I1fbe3157c93fef4611c3b9b13569c9b339e2898a Merged-In: I1fbe3157c93fef4611c3b9b13569c9b339e2898a --- res/xml/accessibility_button_settings.xml | 3 +- ...oatingMenuOpacityPreferenceController.java | 142 ++++++++++++++++++ ...ngMenuOpacityPreferenceControllerTest.java | 137 +++++++++++++++++ 3 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 src/com/android/settings/accessibility/FloatingMenuOpacityPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/FloatingMenuOpacityPreferenceControllerTest.java diff --git a/res/xml/accessibility_button_settings.xml b/res/xml/accessibility_button_settings.xml index e348b77ffb0..8d4631afbba 100644 --- a/res/xml/accessibility_button_settings.xml +++ b/res/xml/accessibility_button_settings.xml @@ -47,7 +47,8 @@ android:key="accessibility_button_opacity" android:title="@string/accessibility_button_opacity_title" android:selectable="true" - android:persistent="false"/> + android:persistent="false" + settings:controller="com.android.settings.accessibility.FloatingMenuOpacityPreferenceController"/> maxValue) ? DEFAULT_OPACITY : value; + } +} + diff --git a/tests/robotests/src/com/android/settings/accessibility/FloatingMenuOpacityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/FloatingMenuOpacityPreferenceControllerTest.java new file mode 100644 index 00000000000..98ad00a8fda --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/FloatingMenuOpacityPreferenceControllerTest.java @@ -0,0 +1,137 @@ +/* + * 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.settings.accessibility; + +import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; +import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR; + +import static com.android.settings.accessibility.FloatingMenuOpacityPreferenceController.DEFAULT_OPACITY; +import static com.android.settings.accessibility.FloatingMenuOpacityPreferenceController.PRECISION; +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.provider.Settings; + +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.widget.SeekBarPreference; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.RobolectricTestRunner; + +/** Tests for {@link FloatingMenuOpacityPreferenceController}. */ +@RunWith(RobolectricTestRunner.class) +public class FloatingMenuOpacityPreferenceControllerTest { + + @Rule + public MockitoRule mocks = MockitoJUnit.rule(); + + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + private ContentResolver mContentResolver; + private FloatingMenuOpacityPreferenceController mController; + + @Before + public void setUp() { + when(mContext.getContentResolver()).thenReturn(mContentResolver); + mController = new FloatingMenuOpacityPreferenceController(mContext, "test_key"); + } + + @Test + public void getAvailabilityStatus_a11yBtnModeFloatingMenu_returnAvailable() { + Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE, + ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void getAvailabilityStatus_a11yBtnModeNavigationBar_returnDisabledDependentSetting() { + Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE, + ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); + } + + @Test + public void onChange_a11yBtnModeChangeToNavigationBar_preferenceDisabled() { + mController.mPreference = new SeekBarPreference(mContext); + Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE, + ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR); + + mController.mContentObserver.onChange(false); + + assertThat(mController.mPreference.isEnabled()).isFalse(); + } + + @Test + public void getSliderPosition_putNormalOpacityValue_expectedValue() { + Settings.Secure.putFloat(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.35f); + + assertThat(mController.getSliderPosition()).isEqualTo(35); + } + + @Test + public void getSliderPosition_putOutOfBoundOpacityValue_defaultValue() { + Settings.Secure.putFloat(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, 0.01f); + + final int defaultValue = Math.round(DEFAULT_OPACITY * PRECISION); + assertThat(mController.getSliderPosition()).isEqualTo(defaultValue); + } + + @Test + public void setSliderPosition_expectedValue() { + mController.setSliderPosition(27); + + final float value = Settings.Secure.getFloat(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY, -1); + assertThat(value).isEqualTo(0.27f); + } + + @Test + public void onResume_registerSpecificContentObserver() { + mController.onResume(); + + verify(mContentResolver).registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE), false, + mController.mContentObserver); + } + + @Test + public void onPause_unregisterContentObserver() { + mController.onPause(); + + verify(mContentResolver).unregisterContentObserver(mController.mContentObserver); + } +} From eb2411db9d396e8c502787b6984cee69df45108f Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Thu, 18 Feb 2021 04:01:01 +0800 Subject: [PATCH 05/10] Add the preference controller to control accessibility button preview preference * Create FloatingMenuLayerDrawable class to handle the preview layer drawable cherry picked from commit 603014760fb6ceb4a66c805ebeef07918fba6652 Bug: 173940869 Test: atest AccessibilityButtonPreviewPreferenceControllerTest FloatingMenuLayerDrawableTest Change-Id: Ia3d030547b377e87c505b2310f559f7f3876ecd5 Merged-In: Ia3d030547b377e87c505b2310f559f7f3876ecd5 --- .../accessibility_button_navigation.xml | 70 +++++++++ .../accessibility_button_preview_base.xml | 45 ++++++ ...ity_button_preview_large_floating_menu.xml | 41 ++++++ ...ity_button_preview_small_floating_menu.xml | 41 ++++++ res/layout/accessibility_button_preview.xml | 33 +++++ res/values/dimens.xml | 2 + res/xml/accessibility_button_settings.xml | 9 ++ ...lityButtonPreviewPreferenceController.java | 126 +++++++++++++++++ .../FloatingMenuLayerDrawable.java | 133 ++++++++++++++++++ ...ButtonPreviewPreferenceControllerTest.java | 120 ++++++++++++++++ .../FloatingMenuLayerDrawableTest.java | 73 ++++++++++ 11 files changed, 693 insertions(+) create mode 100644 res/drawable/accessibility_button_navigation.xml create mode 100644 res/drawable/accessibility_button_preview_base.xml create mode 100644 res/drawable/accessibility_button_preview_large_floating_menu.xml create mode 100644 res/drawable/accessibility_button_preview_small_floating_menu.xml create mode 100644 res/layout/accessibility_button_preview.xml create mode 100644 src/com/android/settings/accessibility/AccessibilityButtonPreviewPreferenceController.java create mode 100644 src/com/android/settings/accessibility/FloatingMenuLayerDrawable.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreviewPreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/FloatingMenuLayerDrawableTest.java diff --git a/res/drawable/accessibility_button_navigation.xml b/res/drawable/accessibility_button_navigation.xml new file mode 100644 index 00000000000..30273fb4e1f --- /dev/null +++ b/res/drawable/accessibility_button_navigation.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/accessibility_button_preview_base.xml b/res/drawable/accessibility_button_preview_base.xml new file mode 100644 index 00000000000..0712b9508b1 --- /dev/null +++ b/res/drawable/accessibility_button_preview_base.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/accessibility_button_preview_large_floating_menu.xml b/res/drawable/accessibility_button_preview_large_floating_menu.xml new file mode 100644 index 00000000000..e003dc7322c --- /dev/null +++ b/res/drawable/accessibility_button_preview_large_floating_menu.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/accessibility_button_preview_small_floating_menu.xml b/res/drawable/accessibility_button_preview_small_floating_menu.xml new file mode 100644 index 00000000000..3ff8e4b25f4 --- /dev/null +++ b/res/drawable/accessibility_button_preview_small_floating_menu.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/accessibility_button_preview.xml b/res/layout/accessibility_button_preview.xml new file mode 100644 index 00000000000..07cb0ffb8ab --- /dev/null +++ b/res/layout/accessibility_button_preview.xml @@ -0,0 +1,33 @@ + + + + + + + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 4fef726d599..dbf21fc8626 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -57,6 +57,8 @@ 320dp + 200dp + 4dp diff --git a/res/xml/accessibility_button_settings.xml b/res/xml/accessibility_button_settings.xml index 8d4631afbba..fc91dcaeef6 100644 --- a/res/xml/accessibility_button_settings.xml +++ b/res/xml/accessibility_button_settings.xml @@ -19,6 +19,15 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:title="@string/accessibility_button_title"> + + Date: Fri, 19 Feb 2021 16:44:57 +0800 Subject: [PATCH 06/10] Add the preference controller to control accessibility button fade preference * Opacity preference will be disabled when fade is disabled cherry picked from commit f9fdedaafe90ecaa9bcfbef7a0d7054eecd23803 Bug: 173940869 Test: atest AccessibilityButtonFadePreferenceControllerTest AccessibilityButtonOactiyPreferenceControllerTest Change-Id: I1efd9760aa0287899cddd10ddd9a88a81ccc39ba Merged-In: I1efd9760aa0287899cddd10ddd9a88a81ccc39ba --- res/xml/accessibility_button_settings.xml | 3 +- .../FloatingMenuFadePreferenceController.java | 116 ++++++++++++++++ ...oatingMenuOpacityPreferenceController.java | 12 +- ...atingMenuFadePreferenceControllerTest.java | 131 ++++++++++++++++++ ...ngMenuOpacityPreferenceControllerTest.java | 4 + 5 files changed, 263 insertions(+), 3 deletions(-) create mode 100644 src/com/android/settings/accessibility/FloatingMenuFadePreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/accessibility/FloatingMenuFadePreferenceControllerTest.java diff --git a/res/xml/accessibility_button_settings.xml b/res/xml/accessibility_button_settings.xml index fc91dcaeef6..5e81616bffc 100644 --- a/res/xml/accessibility_button_settings.xml +++ b/res/xml/accessibility_button_settings.xml @@ -50,7 +50,8 @@ android:key="accessibility_button_fade" android:title="@string/accessibility_button_fade_title" android:summary="@string/accessibility_button_fade_summary" - android:persistent="false"/> + android:persistent="false" + settings:controller="com.android.settings.accessibility.FloatingMenuFadePreferenceController"/> Date: Thu, 11 Mar 2021 21:44:56 +0800 Subject: [PATCH 07/10] Update the dialog content for accessibility floating menu Accessibility gesture is replaced by accessibility floating menu, related content in edit shortcut dialog and tutorial dialog are updated in this changelist. cherry picked from commit 5fe2cdcf8751f50ea21d23a17abd619d7a16cf25 Bug: 173990914 Test: manual test Change-Id: Ie529fa8a1f8ee87ca1ec5611b35675cdfd762165 Merged-In: Ie529fa8a1f8ee87ca1ec5611b35675cdfd762165 --- ...bility_shortcut_type_software_floating.xml | 68 +++++++++++++++++++ res/values/strings.xml | 4 ++ .../AccessibilityEditDialogUtils.java | 56 +++++++-------- ...ccessibilityGestureNavigationTutorial.java | 42 +++--------- .../ToggleFeaturePreferenceFragment.java | 16 ++--- ...ScreenMagnificationPreferenceFragment.java | 20 +++--- 6 files changed, 124 insertions(+), 82 deletions(-) create mode 100644 res/drawable/accessibility_shortcut_type_software_floating.xml diff --git a/res/drawable/accessibility_shortcut_type_software_floating.xml b/res/drawable/accessibility_shortcut_type_software_floating.xml new file mode 100644 index 00000000000..958201515f1 --- /dev/null +++ b/res/drawable/accessibility_shortcut_type_software_floating.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index a9f860acbad..e9fe090b2f6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5106,6 +5106,8 @@ Use new accessibility gesture To use this feature, tap the accessibility button %s on the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button. + + To use this feature, tap the accessibility button on your screen. To use this feature, press & hold both volume keys. @@ -5136,6 +5138,8 @@ Swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. Swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. + + Customize accessibility button Hold volume keys diff --git a/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java b/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java index f349a125085..6b31988ecff 100644 --- a/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java +++ b/src/com/android/settings/accessibility/AccessibilityEditDialogUtils.java @@ -17,6 +17,7 @@ package com.android.settings.accessibility; import android.app.Dialog; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; import android.content.res.TypedArray; @@ -24,6 +25,7 @@ import android.graphics.drawable.Drawable; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; +import android.text.method.LinkMovementMethod; import android.text.style.ImageSpan; import android.view.LayoutInflater; import android.view.View; @@ -40,6 +42,8 @@ import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; import com.android.settings.R; +import com.android.settings.core.SubSettingLauncher; +import com.android.settings.utils.AnnotationSpan; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -253,6 +257,8 @@ public class AccessibilityEditDialogUtils { summary.setVisibility(View.GONE); } else { summary.setText(summaryText); + summary.setMovementMethod(LinkMovementMethod.getInstance()); + summary.setFocusable(false); } final ImageView image = view.findViewById(R.id.image); image.setImageResource(imageResId); @@ -260,10 +266,13 @@ public class AccessibilityEditDialogUtils { private static void initSoftwareShortcut(Context context, View view) { final View dialogView = view.findViewById(R.id.software_shortcut); + final CharSequence title = context.getText( + R.string.accessibility_shortcut_edit_dialog_title_software); final TextView summary = dialogView.findViewById(R.id.summary); final int lineHeight = summary.getLineHeight(); - setupShortcutWidget(dialogView, retrieveTitle(context), - retrieveSummary(context, lineHeight), retrieveImageResId(context)); + + setupShortcutWidget(dialogView, title, retrieveSummary(context, lineHeight), + retrieveImageResId(context)); } private static void initHardwareShortcut(Context context, View view) { @@ -297,35 +306,28 @@ public class AccessibilityEditDialogUtils { }); } - private static CharSequence retrieveTitle(Context context) { - int resId = R.string.accessibility_shortcut_edit_dialog_title_software; - if (AccessibilityUtil.isGestureNavigateEnabled(context)) { - resId = AccessibilityUtil.isTouchExploreEnabled(context) - ? R.string.accessibility_shortcut_edit_dialog_title_software_gesture_talkback - : R.string.accessibility_shortcut_edit_dialog_title_software_gesture; - } - return context.getText(resId); - } - private static CharSequence retrieveSummary(Context context, int lineHeight) { - if (AccessibilityUtil.isGestureNavigateEnabled(context)) { - final int resId = AccessibilityUtil.isTouchExploreEnabled(context) - ? R.string.accessibility_shortcut_edit_dialog_summary_software_gesture_talkback - : R.string.accessibility_shortcut_edit_dialog_summary_software_gesture; - return context.getText(resId); - } - return getSummaryStringWithIcon(context, lineHeight); + return AccessibilityUtil.isFloatingMenuEnabled(context) + ? getSummaryStringWithLink(context) : getSummaryStringWithIcon(context, lineHeight); } private static int retrieveImageResId(Context context) { - // TODO(b/142531156): Use vector drawable instead of temporal png file to avoid distorted. - int resId = R.drawable.accessibility_shortcut_type_software; - if (AccessibilityUtil.isGestureNavigateEnabled(context)) { - resId = AccessibilityUtil.isTouchExploreEnabled(context) - ? R.drawable.accessibility_shortcut_type_software_gesture_talkback - : R.drawable.accessibility_shortcut_type_software_gesture; - } - return resId; + return AccessibilityUtil.isFloatingMenuEnabled(context) + ? R.drawable.accessibility_shortcut_type_software_floating + : R.drawable.accessibility_shortcut_type_software; + } + + private static CharSequence getSummaryStringWithLink(Context context) { + final View.OnClickListener linkListener = v -> new SubSettingLauncher(context) + .setDestination(AccessibilityButtonFragment.class.getName()) + .setSourceMetricsCategory( + SettingsEnums.SWITCH_SHORTCUT_DIALOG_ACCESSIBILITY_BUTTON_SETTINGS) + .launch(); + final AnnotationSpan.LinkInfo linkInfo = new AnnotationSpan.LinkInfo( + AnnotationSpan.LinkInfo.DEFAULT_ANNOTATION, linkListener); + + return AnnotationSpan.linkify(context.getText( + R.string.accessibility_shortcut_edit_dialog_summary_software_floating), linkInfo); } private static SpannableString getSummaryStringWithIcon(Context context, int lineHeight) { diff --git a/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java b/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java index 482822e4f66..5ea5462c0c8 100644 --- a/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java +++ b/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java @@ -333,7 +333,8 @@ public final class AccessibilityGestureNavigationTutorial { } private static TutorialPage createSoftwareTutorialPage(@NonNull Context context) { - final CharSequence title = getSoftwareTitle(context); + final CharSequence title = context.getText( + R.string.accessibility_tutorial_dialog_title_button); final ImageView image = createSoftwareImage(context); final CharSequence instruction = getSoftwareInstruction(context); final ImageView indicatorIcon = @@ -390,44 +391,19 @@ public final class AccessibilityGestureNavigationTutorial { return tutorialPages; } - private static CharSequence getSoftwareTitle(Context context) { - final boolean isGestureNavigationEnabled = - AccessibilityUtil.isGestureNavigateEnabled(context); - final int resId = isGestureNavigationEnabled - ? R.string.accessibility_tutorial_dialog_title_gesture - : R.string.accessibility_tutorial_dialog_title_button; - - return context.getText(resId); - } - private static ImageView createSoftwareImage(Context context) { - int resId = R.drawable.accessibility_shortcut_type_software; - if (AccessibilityUtil.isGestureNavigateEnabled(context)) { - resId = AccessibilityUtil.isTouchExploreEnabled(context) - ? R.drawable.accessibility_shortcut_type_software_gesture_talkback - : R.drawable.accessibility_shortcut_type_software_gesture; - } + final int resId = AccessibilityUtil.isFloatingMenuEnabled(context) + ? R.drawable.accessibility_shortcut_type_software_floating + : R.drawable.accessibility_shortcut_type_software; return createImageView(context, resId); } private static CharSequence getSoftwareInstruction(Context context) { - final boolean isGestureNavigateEnabled = - AccessibilityUtil.isGestureNavigateEnabled(context); - final boolean isTouchExploreEnabled = AccessibilityUtil.isTouchExploreEnabled(context); - int resId = R.string.accessibility_tutorial_dialog_message_button; - if (isGestureNavigateEnabled) { - resId = isTouchExploreEnabled - ? R.string.accessibility_tutorial_dialog_message_gesture_talkback - : R.string.accessibility_tutorial_dialog_message_gesture; - } - - CharSequence text = context.getText(resId); - if (resId == R.string.accessibility_tutorial_dialog_message_button) { - text = getSoftwareInstructionWithIcon(context, text); - } - - return text; + return AccessibilityUtil.isFloatingMenuEnabled(context) + ? context.getText(R.string.accessibility_tutorial_dialog_message_floating_button) + : getSoftwareInstructionWithIcon(context, + context.getText(R.string.accessibility_tutorial_dialog_message_button)); } private static CharSequence getSoftwareInstructionWithIcon(Context context, CharSequence text) { diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index ec22a28aeef..cf9c08b73fd 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -608,19 +608,15 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context, mComponentName.flattenToString(), UserShortcutType.SOFTWARE); - int resId = R.string.accessibility_shortcut_edit_summary_software; - if (AccessibilityUtil.isGestureNavigateEnabled(context)) { - resId = AccessibilityUtil.isTouchExploreEnabled(context) - ? R.string.accessibility_shortcut_edit_dialog_title_software_gesture_talkback - : R.string.accessibility_shortcut_edit_dialog_title_software_gesture; - } - final CharSequence softwareTitle = context.getText(resId); - List list = new ArrayList<>(); - if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { + final List list = new ArrayList<>(); + final CharSequence softwareTitle = context.getText( + R.string.accessibility_shortcut_edit_summary_software); + + if (hasShortcutType(shortcutTypes, UserShortcutType.SOFTWARE)) { list.add(softwareTitle); } - if ((shortcutTypes & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE) { + if (hasShortcutType(shortcutTypes, UserShortcutType.HARDWARE)) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_hardware_keyword); list.add(hardwareTitle); diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index dde5be17d74..738d284bda0 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -226,27 +226,23 @@ public class ToggleScreenMagnificationPreferenceFragment extends return context.getText(R.string.switch_off_text); } - final int shortcutType = PreferredShortcuts.retrieveUserShortcutType(context, + final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context, MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.SOFTWARE); - int resId = R.string.accessibility_shortcut_edit_summary_software; - if (AccessibilityUtil.isGestureNavigateEnabled(context)) { - resId = AccessibilityUtil.isTouchExploreEnabled(context) - ? R.string.accessibility_shortcut_edit_dialog_title_software_gesture_talkback - : R.string.accessibility_shortcut_edit_dialog_title_software_gesture; - } - final CharSequence softwareTitle = context.getText(resId); - List list = new ArrayList<>(); - if ((shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { + final List list = new ArrayList<>(); + final CharSequence softwareTitle = context.getText( + R.string.accessibility_shortcut_edit_summary_software); + + if (hasShortcutType(shortcutTypes, UserShortcutType.SOFTWARE)) { list.add(softwareTitle); } - if ((shortcutType & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE) { + if (hasShortcutType(shortcutTypes, UserShortcutType.HARDWARE)) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_hardware_keyword); list.add(hardwareTitle); } - if ((shortcutType & UserShortcutType.TRIPLETAP) == UserShortcutType.TRIPLETAP) { + if (hasShortcutType(shortcutTypes, UserShortcutType.TRIPLETAP)) { final CharSequence tripleTapTitle = context.getText( R.string.accessibility_shortcut_triple_tap_keyword); list.add(tripleTapTitle); From e2c69bcd7b90a77c13e8938932117fd53793a386 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Thu, 11 Mar 2021 22:27:26 +0800 Subject: [PATCH 08/10] Remove the accessibility gesture tutorial dialog in system navigation Accessibility gesture is replaced by the accessibility floating menu, remove the accessibility gesture tutorial dialog when choosing to use gesture navigation mode. cherry picked from commit 1a0e2b1be52849a0c91dcc1a907910592ddc3f0d Bug: 173990914 Test: manual test Change-Id: Iae5297747594fcc73fc9bc14537c8fdecb86b660 Merged-In: Iae5297747594fcc73fc9bc14537c8fdecb86b660 --- .../SystemNavigationGestureSettings.java | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java index 14fe6a664be..388d87ae9a9 100644 --- a/src/com/android/settings/gestures/SystemNavigationGestureSettings.java +++ b/src/com/android/settings/gestures/SystemNavigationGestureSettings.java @@ -30,15 +30,12 @@ import android.content.om.OverlayInfo; import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; -import android.text.TextUtils; import android.util.FeatureFlagUtils; -import android.view.accessibility.AccessibilityManager; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceScreen; import com.android.settings.R; -import com.android.settings.SettingsTutorialDialogWrapperActivity; import com.android.settings.core.FeatureFlags; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.overlay.FeatureFactory; @@ -188,12 +185,7 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i protected boolean setDefaultKey(String key) { setCurrentSystemNavigationMode(mOverlayManager, key); setIllustrationVideo(mVideoPreference, key); - if (TextUtils.equals(KEY_SYSTEM_NAV_GESTURAL, key) && ( - isAnyServiceSupportAccessibilityButton() || isNavBarMagnificationEnabled())) { - Intent intent = new Intent(getActivity(), SettingsTutorialDialogWrapperActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - } + return true; } @@ -267,18 +259,6 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i } } - private boolean isAnyServiceSupportAccessibilityButton() { - final AccessibilityManager ams = getContext().getSystemService(AccessibilityManager.class); - final List targets = ams.getAccessibilityShortcutTargets( - AccessibilityManager.ACCESSIBILITY_BUTTON); - return !targets.isEmpty(); - } - - private boolean isNavBarMagnificationEnabled() { - return Settings.Secure.getInt(getContext().getContentResolver(), - Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, 0) == 1; - } - public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.system_navigation_gesture_settings) { From 799ead4d4146ae8651e22c1a6cc1261f9cac82f1 Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Thu, 11 Mar 2021 22:37:34 +0800 Subject: [PATCH 09/10] Update the vector drawable for accessibility button preview preference cherry picked from commit 96121b3f0d7e48f08f9373f56d158300d03dd4cd Bug: 173940869 Test: manual test Change-Id: Id24d1550e7c640a7fdbd752e3571296a7e6567d6 Merged-In: Id24d1550e7c640a7fdbd752e3571296a7e6567d6 --- .../accessibility_button_navigation.xml | 89 +++++++++---------- .../accessibility_button_preview_base.xml | 39 ++++---- 2 files changed, 61 insertions(+), 67 deletions(-) diff --git a/res/drawable/accessibility_button_navigation.xml b/res/drawable/accessibility_button_navigation.xml index 30273fb4e1f..82e3c70174f 100644 --- a/res/drawable/accessibility_button_navigation.xml +++ b/res/drawable/accessibility_button_navigation.xml @@ -19,52 +19,49 @@ android:height="153dp" android:viewportWidth="125" android:viewportHeight="153"> + + + + + + - - - - - - - - - - - - - - + android:pathData="M12.4,-61L112.6,-61A5.4,5.4 0,0 1,118 -55.6L118,140.6A5.4,5.4 0,0 1,112.6 146L12.4,146A5.4,5.4 0,0 1,7 140.6L7,-55.6A5.4,5.4 0,0 1,12.4 -61z"/> + - \ No newline at end of file + + + + + + + diff --git a/res/drawable/accessibility_button_preview_base.xml b/res/drawable/accessibility_button_preview_base.xml index 0712b9508b1..9e3ec598586 100644 --- a/res/drawable/accessibility_button_preview_base.xml +++ b/res/drawable/accessibility_button_preview_base.xml @@ -19,27 +19,24 @@ android:height="153dp" android:viewportWidth="125" android:viewportHeight="153"> + + + + + + - - - - - - - - - + android:pathData="M12.4,-61L112.6,-61A5.4,5.4 0,0 1,118 -55.6L118,140.6A5.4,5.4 0,0 1,112.6 146L12.4,146A5.4,5.4 0,0 1,7 140.6L7,-55.6A5.4,5.4 0,0 1,12.4 -61z"/> + - \ No newline at end of file + + From 9a5925c471ffb801923d4bd0e20daa9311fdc09b Mon Sep 17 00:00:00 2001 From: jasonwshsu Date: Thu, 11 Mar 2021 23:08:02 +0800 Subject: [PATCH 10/10] Remove half circle option in size selector Half circle accessibility floating menu mode changed to be triggered from gesture. cherry picked from commit c2057ae257514987270fbf7f1f69fc958ea88881 Bug: 173940869 Test: atest FloatingMenuSizePreferenceControllerTest Change-Id: I123baaf3684d5cbb0a33fc2383da72aa022876c0 Merged-In: I123baaf3684d5cbb0a33fc2383da72aa022876c0 --- res/values/arrays.xml | 3 -- .../FloatingMenuSizePreferenceController.java | 46 +------------------ ...atingMenuSizePreferenceControllerTest.java | 25 ---------- 3 files changed, 2 insertions(+), 72 deletions(-) diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 2d03c11227e..2057c50626f 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -985,7 +985,6 @@ Small Large - Half Circle @@ -994,8 +993,6 @@ 0 1 - - 2 diff --git a/src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java b/src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java index b4fa495f071..2f0f833772e 100644 --- a/src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java +++ b/src/com/android/settings/accessibility/FloatingMenuSizePreferenceController.java @@ -59,24 +59,11 @@ public class FloatingMenuSizePreferenceController extends BasePreferenceControll @IntDef({ Size.SMALL, Size.LARGE, - Size.EDGE }) @VisibleForTesting @interface Size { int SMALL = 0; int LARGE = 1; - int EDGE = 2; - } - - @Retention(RetentionPolicy.SOURCE) - @IntDef({ - EdgeMode.FULL_CIRCLE, - EdgeMode.HALF_CIRCLE, - }) - @VisibleForTesting - @interface EdgeMode { - int FULL_CIRCLE = 0; - int HALF_CIRCLE = 1; } public FloatingMenuSizePreferenceController(Context context, String preferenceKey) { @@ -110,7 +97,7 @@ public class FloatingMenuSizePreferenceController extends BasePreferenceControll final ListPreference listPreference = (ListPreference) preference; final Integer value = Ints.tryParse((String) newValue); if (value != null) { - writeToFloatingMenuSettings(value); + putAccessibilityFloatingMenuSize(value); updateState(listPreference); } return true; @@ -121,7 +108,7 @@ public class FloatingMenuSizePreferenceController extends BasePreferenceControll super.updateState(preference); final ListPreference listPreference = (ListPreference) preference; - listPreference.setValue(getCurrentAccessibilityButtonSize()); + listPreference.setValue(String.valueOf(getAccessibilityFloatingMenuSize(mDefaultSize))); } @Override @@ -157,24 +144,6 @@ public class FloatingMenuSizePreferenceController extends BasePreferenceControll } } - private void writeToFloatingMenuSettings(@Size int sizeValue) { - if (sizeValue == Size.EDGE) { - putAccessibilityFloatingMenuSize(Size.SMALL); - putAccessibilityFloatingMenuIconType(EdgeMode.HALF_CIRCLE); - } else { - putAccessibilityFloatingMenuSize(sizeValue); - putAccessibilityFloatingMenuIconType(EdgeMode.FULL_CIRCLE); - } - } - - private String getCurrentAccessibilityButtonSize() { - final @EdgeMode int iconType = getAccessibilityFloatingMenuIconType(EdgeMode.FULL_CIRCLE); - final @Size int btnSize = getAccessibilityFloatingMenuSize(mDefaultSize); - - return (iconType == EdgeMode.HALF_CIRCLE) - ? String.valueOf(Size.EDGE) : String.valueOf(btnSize); - } - @Size private int getAccessibilityFloatingMenuSize(@Size int defaultValue) { return Settings.Secure.getInt(mContentResolver, @@ -185,15 +154,4 @@ public class FloatingMenuSizePreferenceController extends BasePreferenceControll Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, value); } - - @EdgeMode - private int getAccessibilityFloatingMenuIconType(@EdgeMode int defaultValue) { - return Settings.Secure.getInt(mContentResolver, - Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, defaultValue); - } - - private void putAccessibilityFloatingMenuIconType(@EdgeMode int value) { - Settings.Secure.putInt(mContentResolver, - Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, value); - } } diff --git a/tests/robotests/src/com/android/settings/accessibility/FloatingMenuSizePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/FloatingMenuSizePreferenceControllerTest.java index 70257ca6931..4d7d98d7aff 100644 --- a/tests/robotests/src/com/android/settings/accessibility/FloatingMenuSizePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/FloatingMenuSizePreferenceControllerTest.java @@ -84,9 +84,6 @@ public class FloatingMenuSizePreferenceControllerTest { public void updateState_floatingMenuLargeSizeAndFullCircle_largeSizeValue() { Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, FloatingMenuSizePreferenceController.Size.LARGE); - Settings.Secure.putInt(mContentResolver, - Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, - FloatingMenuSizePreferenceController.EdgeMode.FULL_CIRCLE); mController.updateState(mListPreference); @@ -94,28 +91,6 @@ public class FloatingMenuSizePreferenceControllerTest { assertThat(mListPreference.getValue()).isEqualTo(largeSize); } - @Test - public void updateState_floatingMenuHalfCircle_edgeSizeValue() { - Settings.Secure.putInt(mContentResolver, - Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, - FloatingMenuSizePreferenceController.EdgeMode.HALF_CIRCLE); - - mController.updateState(mListPreference); - - final String edgeSize = String.valueOf(FloatingMenuSizePreferenceController.Size.EDGE); - assertThat(mListPreference.getValue()).isEqualTo(edgeSize); - } - - @Test - public void onPreferenceChange_floatingMenuEdgeSize_edgeSizeValue() { - final String edgeSize = String.valueOf( - FloatingMenuSizePreferenceController.Size.EDGE); - - mController.onPreferenceChange(mListPreference, edgeSize); - - assertThat(mListPreference.getValue()).isEqualTo(edgeSize); - } - @Test public void onChange_a11yBtnModeChangeToNavigationBar_preferenceDisabled() { mController.mPreference = mListPreference;