Update accesibility button to suuport accessibility gesutre
1. Add gesture preference controller for gesture navigation 2. Auto update the preview illustarion when screen reader is on 3. Auto update accessibility button title for system navigation Bug: 190563948 Test: make RunSettingsRoboTests ROBOTEST_FILTER=AccessibilityButtonGesturePreferenceControllerTest ROBOTEST_FILTER=AccessibilityButtonPreviewPreferenceControllerTest ROBOTEST_FILTER=AccessibilityLayerDrawableTest ROBOTEST_FILTER=AccessibilityPreferenceControllerTest ROBOTEST_FILTER=AccessibilityButtonFooterPreferenceControllerTest Change-Id: Ifa98fc029430d86d3143133b3203b239340f2e41
This commit is contained in:
40
res/drawable/accessibility_button_preview_three_finger.xml
Normal file
40
res/drawable/accessibility_button_preview_three_finger.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="125dp"
|
||||
android:height="153dp"
|
||||
android:viewportWidth="125"
|
||||
android:viewportHeight="153">
|
||||
<path
|
||||
android:pathData="M0,0h125v153h-125z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M41.266,134.754L84.047,134.754A1.735,1.735 0,0 1,85.781 136.489L85.781,136.489A1.735,1.735 0,0 1,84.047 138.223L41.266,138.223A1.735,1.735 0,0 1,39.531 136.489L39.531,136.489A1.735,1.735 0,0 1,41.266 134.754z"
|
||||
android:fillColor="#DADCE0"/>
|
||||
<path
|
||||
android:pathData="M48.359,107L54.719,119.721H50.672V131.87C52.385,132.722 53.563,134.49 53.563,136.533C53.563,139.407 51.233,141.737 48.359,141.737C45.486,141.737 43.156,139.407 43.156,136.533C43.156,134.49 44.333,132.722 46.047,131.87V119.721H42L48.359,107Z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M62.703,107L69.063,119.721H65.016V131.87C66.729,132.722 67.906,134.49 67.906,136.533C67.906,139.407 65.577,141.737 62.703,141.737C59.829,141.737 57.5,139.407 57.5,136.533C57.5,134.49 58.677,132.722 60.39,131.87V119.721H56.344L62.703,107Z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M76.891,107L83.25,119.721H79.203V131.87C80.916,132.722 82.094,134.49 82.094,136.533C82.094,139.407 79.764,141.737 76.891,141.737C74.017,141.737 71.688,139.407 71.688,136.533C71.688,134.49 72.865,132.722 74.578,131.87V119.721H70.531L76.891,107Z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
36
res/drawable/accessibility_button_preview_two_finger.xml
Normal file
36
res/drawable/accessibility_button_preview_two_finger.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="125dp"
|
||||
android:height="153dp"
|
||||
android:viewportWidth="125"
|
||||
android:viewportHeight="153">
|
||||
<path
|
||||
android:pathData="M0,0h125v153h-125z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M41.266,134.754L84.047,134.754A1.735,1.735 0,0 1,85.781 136.489L85.781,136.489A1.735,1.735 0,0 1,84.047 138.223L41.266,138.223A1.735,1.735 0,0 1,39.531 136.489L39.531,136.489A1.735,1.735 0,0 1,41.266 134.754z"
|
||||
android:fillColor="#DADCE0"/>
|
||||
<path
|
||||
android:pathData="M52.828,107L59.188,119.721H55.141V131.87C56.854,132.722 58.031,134.49 58.031,136.533C58.031,139.407 55.702,141.737 52.828,141.737C49.954,141.737 47.625,139.407 47.625,136.533C47.625,134.49 48.802,132.722 50.515,131.87V119.721H46.469L52.828,107Z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M70.172,107L76.531,119.721H72.485V131.87C74.198,132.722 75.375,134.49 75.375,136.533C75.375,139.407 73.046,141.737 70.172,141.737C67.298,141.737 64.969,139.407 64.969,136.533C64.969,134.49 66.146,132.722 67.859,131.87V119.721H63.813L70.172,107Z"
|
||||
android:fillColor="#1A73E8"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
@@ -5431,9 +5431,9 @@
|
||||
<!-- Summary text for the accessibility button preference. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_button_summary">Quickly access accessibility features</string>
|
||||
<!-- Description for the accessibility button in gesture navigation. Explain how this page works. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_button_gesture_description">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.\n\nTo use the accessibility button in the navigation bar instead, switch to 2-button navigation or 3-button navigation.</string>
|
||||
<string name="accessibility_button_gesture_description">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 or gesture.</string>
|
||||
<!-- Description for the accessibility button page. Explain how this page works. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_button_description">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.</string>
|
||||
<string name="accessibility_button_description">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.</string>
|
||||
<!-- Title for the button or gesture of the accessibility button. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_button_or_gesture_title">Use button or gesture</string>
|
||||
<!-- Title for the location of the accessibility button. [CHAR LIMIT=35] -->
|
||||
|
@@ -16,8 +16,7 @@
|
||||
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/accessibility_button_title">
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.android.settingslib.widget.LayoutPreference
|
||||
android:key="caption_preview"
|
||||
@@ -37,6 +36,15 @@
|
||||
android:persistent="false"
|
||||
settings:controller="com.android.settings.accessibility.AccessibilityButtonLocationPreferenceController"/>
|
||||
|
||||
<ListPreference
|
||||
android:entries="@array/accessibility_button_gesture_selector_titles"
|
||||
android:entryValues="@array/accessibility_button_gesture_selector_values"
|
||||
android:key="accessibility_button_or_gesture"
|
||||
android:title="@string/accessibility_button_or_gesture_title"
|
||||
android:summary="%s"
|
||||
android:persistent="false"
|
||||
settings:controller="com.android.settings.accessibility.AccessibilityButtonGesturePreferenceController"/>
|
||||
|
||||
<ListPreference
|
||||
android:entries="@array/accessibility_button_size_selector_titles"
|
||||
android:entryValues="@array/accessibility_button_size_selector_values"
|
||||
@@ -61,7 +69,6 @@
|
||||
|
||||
<com.android.settings.accessibility.AccessibilityFooterPreference
|
||||
android:key="accessibility_button_footer"
|
||||
android:title="@string/accessibility_button_description"
|
||||
android:persistent="false"
|
||||
android:selectable="false"
|
||||
settings:searchable="false"
|
||||
|
@@ -25,8 +25,8 @@
|
||||
android:fragment="com.android.settings.accessibility.AccessibilityButtonFragment"
|
||||
android:key="accessibility_button_preference"
|
||||
android:persistent="false"
|
||||
android:title="@string/accessibility_button_title"
|
||||
android:summary="@string/accessibility_button_summary"/>
|
||||
android:summary="@string/accessibility_button_summary"
|
||||
settings:controller="com.android.settings.accessibility.AccessibilityButtonPreferenceController"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="accessibility_shortcut_preference"
|
||||
|
@@ -47,13 +47,12 @@ public class AccessibilityButtonFooterPreferenceController extends
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
// Need to update footerPreference's data before super.displayPreference(), then it will use
|
||||
// data to update related property of footerPreference.
|
||||
if (AccessibilityUtil.isGestureNavigateEnabled(mContext)) {
|
||||
final AccessibilityFooterPreference footerPreference =
|
||||
screen.findPreference(getPreferenceKey());
|
||||
footerPreference.setTitle(
|
||||
mContext.getString(R.string.accessibility_button_gesture_description));
|
||||
}
|
||||
|
||||
final int titleResource = AccessibilityUtil.isGestureNavigateEnabled(mContext)
|
||||
? R.string.accessibility_button_gesture_description
|
||||
: R.string.accessibility_button_description;
|
||||
final AccessibilityFooterPreference footerPreference =
|
||||
screen.findPreference(getPreferenceKey());
|
||||
footerPreference.setTitle(titleResource);
|
||||
super.displayPreference(screen);
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
@@ -29,6 +30,14 @@ public class AccessibilityButtonFragment extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "AccessibilityButtonFragment";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
final int titleResource = AccessibilityUtil.isGestureNavigateEnabled(getPrefContext())
|
||||
? R.string.accessibility_button_gesture_title : R.string.accessibility_button_title;
|
||||
getActivity().setTitle(titleResource);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.accessibility_button_settings;
|
||||
|
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** Preference controller that controls the button or gesture in accessibility button page. */
|
||||
public class AccessibilityButtonGesturePreferenceController extends BasePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private Optional<Integer> mDefaultGesture = Optional.empty();
|
||||
|
||||
public AccessibilityButtonGesturePreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AccessibilityUtil.isGestureNavigateEnabled(mContext)
|
||||
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@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, getDefaultGestureValue());
|
||||
return String.valueOf(mode);
|
||||
}
|
||||
|
||||
private int getDefaultGestureValue() {
|
||||
if (!mDefaultGesture.isPresent()) {
|
||||
final String[] valuesList = mContext.getResources().getStringArray(
|
||||
R.array.accessibility_button_gesture_selector_values);
|
||||
mDefaultGesture = Optional.of(Integer.parseInt(valuesList[0]));
|
||||
}
|
||||
return mDefaultGesture.get();
|
||||
}
|
||||
}
|
@@ -18,7 +18,6 @@ package com.android.settings.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
@@ -28,16 +27,16 @@ import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** Preference controller that controls the preferred location in accessibility button page. */
|
||||
public class AccessibilityButtonLocationPreferenceController extends BasePreferenceController
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private final ArrayMap<String, String> mValueTitleMap = new ArrayMap<>();
|
||||
private int mDefaultLocation;
|
||||
private Optional<Integer> mDefaultLocation = Optional.empty();
|
||||
|
||||
public AccessibilityButtonLocationPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
initValueTitleMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,22 +67,16 @@ public class AccessibilityButtonLocationPreferenceController extends BasePrefere
|
||||
|
||||
private String getCurrentAccessibilityButtonMode() {
|
||||
final int mode = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mDefaultLocation);
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_MODE, getDefaultLocationValue());
|
||||
return String.valueOf(mode);
|
||||
}
|
||||
|
||||
private void initValueTitleMap() {
|
||||
if (mValueTitleMap.size() == 0) {
|
||||
final String[] values = mContext.getResources().getStringArray(
|
||||
private int getDefaultLocationValue() {
|
||||
if (!mDefaultLocation.isPresent()) {
|
||||
final String[] valuesList = 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]);
|
||||
}
|
||||
mDefaultLocation = Optional.of(Integer.parseInt(valuesList[0]));
|
||||
}
|
||||
return mDefaultLocation.get();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
/**
|
||||
* Preference controller for accessibility button preference.
|
||||
*/
|
||||
public class AccessibilityButtonPreferenceController extends BasePreferenceController {
|
||||
|
||||
public AccessibilityButtonPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return AVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
final int titleResource = AccessibilityUtil.isGestureNavigateEnabled(mContext)
|
||||
? R.string.accessibility_button_gesture_title : R.string.accessibility_button_title;
|
||||
final Preference preference = screen.findPreference(getPreferenceKey());
|
||||
preference.setTitle(titleResource);
|
||||
|
||||
}
|
||||
}
|
@@ -23,6 +23,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -46,11 +47,14 @@ public class AccessibilityButtonPreviewPreferenceController extends BasePreferen
|
||||
private final ContentResolver mContentResolver;
|
||||
@VisibleForTesting
|
||||
final ContentObserver mContentObserver;
|
||||
private FloatingMenuLayerDrawable mFloatingMenuPreviewDrawable;
|
||||
private AccessibilityLayerDrawable mAccessibilityPreviewDrawable;
|
||||
|
||||
@VisibleForTesting
|
||||
ImageView mPreview;
|
||||
|
||||
private AccessibilityManager.TouchExplorationStateChangeListener
|
||||
mTouchExplorationStateChangeListener;
|
||||
|
||||
public AccessibilityButtonPreviewPreferenceController(Context context, String preferenceKey) {
|
||||
super(context, preferenceKey);
|
||||
mContentResolver = context.getContentResolver();
|
||||
@@ -60,6 +64,9 @@ public class AccessibilityButtonPreviewPreferenceController extends BasePreferen
|
||||
updatePreviewPreference();
|
||||
}
|
||||
};
|
||||
mTouchExplorationStateChangeListener = isTouchExplorationEnabled -> {
|
||||
updatePreviewPreference();
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,6 +85,9 @@ public class AccessibilityButtonPreviewPreferenceController extends BasePreferen
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
final AccessibilityManager am = mContext.getSystemService(AccessibilityManager.class);
|
||||
am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
|
||||
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_MODE),
|
||||
/* notifyForDescendants= */ false, mContentObserver);
|
||||
@@ -91,6 +101,9 @@ public class AccessibilityButtonPreviewPreferenceController extends BasePreferen
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
final AccessibilityManager am = mContext.getSystemService(AccessibilityManager.class);
|
||||
am.removeTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
|
||||
|
||||
mContentResolver.unregisterContentObserver(mContentObserver);
|
||||
}
|
||||
|
||||
@@ -103,9 +116,14 @@ public class AccessibilityButtonPreviewPreferenceController extends BasePreferen
|
||||
final int floatingMenuIconId = (size == SMALL_SIZE)
|
||||
? R.drawable.accessibility_button_preview_small_floating_menu
|
||||
: R.drawable.accessibility_button_preview_large_floating_menu;
|
||||
|
||||
mPreview.setImageDrawable(getFloatingMenuPreviewDrawable(floatingMenuIconId, opacity));
|
||||
// Only change opacity(alpha) would not invoke redraw view, need to invalidate manually.
|
||||
mPreview.setImageDrawable(getAccessibilityPreviewDrawable(floatingMenuIconId, opacity));
|
||||
mPreview.invalidate();
|
||||
} else if (AccessibilityUtil.isGestureNavigateEnabled(mContext)) {
|
||||
// TODO(b/193081959): Use static illustartion instead.
|
||||
final int resId = AccessibilityUtil.isTouchExploreEnabled(mContext)
|
||||
? R.drawable.accessibility_button_preview_three_finger
|
||||
: R.drawable.accessibility_button_preview_two_finger;
|
||||
mPreview.setImageDrawable(getAccessibilityPreviewDrawable(resId, /* opacity= */ 100));
|
||||
mPreview.invalidate();
|
||||
} else {
|
||||
mPreview.setImageDrawable(
|
||||
@@ -113,14 +131,14 @@ public class AccessibilityButtonPreviewPreferenceController extends BasePreferen
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable getFloatingMenuPreviewDrawable(int resId, int opacity) {
|
||||
if (mFloatingMenuPreviewDrawable == null) {
|
||||
mFloatingMenuPreviewDrawable = FloatingMenuLayerDrawable.createLayerDrawable(
|
||||
private Drawable getAccessibilityPreviewDrawable(int resId, int opacity) {
|
||||
if (mAccessibilityPreviewDrawable == null) {
|
||||
mAccessibilityPreviewDrawable = AccessibilityLayerDrawable.createLayerDrawable(
|
||||
mContext, resId, opacity);
|
||||
} else {
|
||||
mFloatingMenuPreviewDrawable.updateLayerDrawable(mContext, resId, opacity);
|
||||
mAccessibilityPreviewDrawable.updateLayerDrawable(mContext, resId, opacity);
|
||||
}
|
||||
|
||||
return mFloatingMenuPreviewDrawable;
|
||||
return mAccessibilityPreviewDrawable;
|
||||
}
|
||||
}
|
||||
|
@@ -27,10 +27,10 @@ import com.android.settings.R;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/** LayerDrawable that contains device icon as background and floating menu icon as foreground. */
|
||||
public class FloatingMenuLayerDrawable extends LayerDrawable {
|
||||
/** LayerDrawable that contains device icon as background and given icon as foreground. */
|
||||
public class AccessibilityLayerDrawable extends LayerDrawable {
|
||||
|
||||
private FloatingMenuLayerDrawableState mState;
|
||||
private AccessibilityLayerDrawableState mState;
|
||||
|
||||
/**
|
||||
* Creates a new layer drawable with the list of specified layers.
|
||||
@@ -38,23 +38,23 @@ public class FloatingMenuLayerDrawable extends LayerDrawable {
|
||||
* @param layers a list of drawables to use as layers in this new drawable,
|
||||
* must be non-null
|
||||
*/
|
||||
private FloatingMenuLayerDrawable(@NonNull Drawable[] layers) {
|
||||
private AccessibilityLayerDrawable(@NonNull Drawable[] layers) {
|
||||
super(layers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the {@link LayerDrawable} that contains device icon as background and floating menu
|
||||
* icon with given {@code opacity} value as foreground.
|
||||
* Create the {@link LayerDrawable} that contains device icon as background and given menu icon
|
||||
* with given {@code opacity} value as foreground.
|
||||
*
|
||||
* @param context the valid context used to get the icon
|
||||
* @param resId the resource ID of the floating menu icon
|
||||
* @param resId the resource ID of the given icon
|
||||
* @param opacity the opacity to apply to the given icon
|
||||
* @return the drawable that combines the device icon and the floating menu icon
|
||||
* @return the drawable that combines the device icon and the given icon
|
||||
*/
|
||||
public static FloatingMenuLayerDrawable createLayerDrawable(Context context, int resId,
|
||||
public static AccessibilityLayerDrawable createLayerDrawable(Context context, int resId,
|
||||
int opacity) {
|
||||
final Drawable bg = context.getDrawable(R.drawable.accessibility_button_preview_base);
|
||||
final FloatingMenuLayerDrawable basicDrawable = new FloatingMenuLayerDrawable(
|
||||
final AccessibilityLayerDrawable basicDrawable = new AccessibilityLayerDrawable(
|
||||
new Drawable[]{bg, null});
|
||||
|
||||
basicDrawable.updateLayerDrawable(context, resId, opacity);
|
||||
@@ -66,7 +66,7 @@ public class FloatingMenuLayerDrawable extends LayerDrawable {
|
||||
* value at index 1 layer.
|
||||
*
|
||||
* @param context the valid context used to get the icon
|
||||
* @param resId the resource ID of the floating menu icon
|
||||
* @param resId the resource ID of the given icon
|
||||
* @param opacity the opacity to apply to the given icon
|
||||
*/
|
||||
public void updateLayerDrawable(Context context, int resId, int opacity) {
|
||||
@@ -83,18 +83,18 @@ public class FloatingMenuLayerDrawable extends LayerDrawable {
|
||||
|
||||
/** Stores the constant state and data to the given drawable. */
|
||||
private void setConstantState(Context context, int resId, int opacity) {
|
||||
mState = new FloatingMenuLayerDrawableState(context, resId, opacity);
|
||||
mState = new AccessibilityLayerDrawableState(context, resId, opacity);
|
||||
}
|
||||
|
||||
/** {@link ConstantState} to store the data of {@link FloatingMenuLayerDrawable}. */
|
||||
/** {@link ConstantState} to store the data of {@link AccessibilityLayerDrawable}. */
|
||||
@VisibleForTesting
|
||||
static class FloatingMenuLayerDrawableState extends ConstantState {
|
||||
static class AccessibilityLayerDrawableState extends ConstantState {
|
||||
|
||||
private final Context mContext;
|
||||
private final int mResId;
|
||||
private final int mOpacity;
|
||||
|
||||
FloatingMenuLayerDrawableState(Context context, int resId, int opacity) {
|
||||
AccessibilityLayerDrawableState(Context context, int resId, int opacity) {
|
||||
mContext = context;
|
||||
mResId = resId;
|
||||
mOpacity = opacity;
|
||||
@@ -119,7 +119,7 @@ public class FloatingMenuLayerDrawable extends LayerDrawable {
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final FloatingMenuLayerDrawableState that = (FloatingMenuLayerDrawableState) o;
|
||||
final AccessibilityLayerDrawableState that = (AccessibilityLayerDrawableState) o;
|
||||
return mResId == that.mResId
|
||||
&& mOpacity == that.mOpacity
|
||||
&& Objects.equals(mContext, that.mContext);
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
@@ -46,7 +47,6 @@ public class AccessibilityButtonFooterPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
@@ -76,4 +76,15 @@ public class AccessibilityButtonFooterPreferenceControllerTest {
|
||||
assertThat(mPreference.getTitle()).isEqualTo(
|
||||
mContext.getText(R.string.accessibility_button_gesture_description));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_navigationGestureDisabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(
|
||||
mContext.getText(R.string.accessibility_button_description));
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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_GESTURE;
|
||||
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.CONDITIONALLY_UNAVAILABLE;
|
||||
|
||||
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 AccessibilityButtonGesturePreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonGesturePreferenceControllerTest {
|
||||
|
||||
@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 AccessibilityButtonGesturePreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityButtonGesturePreferenceController(mContext,
|
||||
"test_key");
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_navigationGestureEnabled_returnAvailable() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_navigationGestureDisabled_returnConditionallyUnavailable() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_a11yBtnModeGesture_navigationBarValue() {
|
||||
Settings.Secure.putInt(mContentResolver, Settings.Secure.ACCESSIBILITY_BUTTON_MODE,
|
||||
ACCESSIBILITY_BUTTON_MODE_GESTURE);
|
||||
|
||||
mController.updateState(mListPreference);
|
||||
|
||||
final String gestureValue = String.valueOf(ACCESSIBILITY_BUTTON_MODE_GESTURE);
|
||||
assertThat(mListPreference.getValue()).isEqualTo(gestureValue);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
|
||||
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
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 AccessibilityButtonPreferenceController}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityButtonPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Spy
|
||||
private final Resources mResources = mContext.getResources();
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
private Preference mPreference;
|
||||
private AccessibilityButtonPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mController = new AccessibilityButtonPreferenceController(mContext, "test_key");
|
||||
mPreference = new Preference(mContext);
|
||||
mPreference.setKey("test_key");
|
||||
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_navigationGestureEnabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_GESTURAL);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(
|
||||
mContext.getText(R.string.accessibility_button_gesture_title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_navigationGestureDisabled_setCorrectTitle() {
|
||||
when(mResources.getInteger(com.android.internal.R.integer.config_navBarInteractionMode))
|
||||
.thenReturn(NAV_BAR_MODE_2BUTTON);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(
|
||||
mContext.getText(R.string.accessibility_button_title));
|
||||
}
|
||||
}
|
@@ -90,7 +90,7 @@ public class AccessibilityButtonPreviewPreferenceControllerTest {
|
||||
mController.mContentObserver.onChange(false);
|
||||
|
||||
final Drawable smallFloatingMenuWithTenOpacityDrawable =
|
||||
FloatingMenuLayerDrawable.createLayerDrawable(mContext,
|
||||
AccessibilityLayerDrawable.createLayerDrawable(mContext,
|
||||
R.drawable.accessibility_button_preview_small_floating_menu, 10);
|
||||
assertThat(mController.mPreview.getDrawable().getConstantState()).isEqualTo(
|
||||
smallFloatingMenuWithTenOpacityDrawable.getConstantState());
|
||||
|
@@ -30,9 +30,9 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link FloatingMenuLayerDrawable}. */
|
||||
/** Tests for {@link AccessibilityLayerDrawable}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class FloatingMenuLayerDrawableTest {
|
||||
public class AccessibilityLayerDrawableTest {
|
||||
|
||||
private static final int TEST_RES_ID =
|
||||
com.android.internal.R.drawable.ic_accessibility_magnification;
|
||||
@@ -46,8 +46,8 @@ public class FloatingMenuLayerDrawableTest {
|
||||
R.drawable.accessibility_button_preview_base);
|
||||
final Drawable expected2ndDrawable = mContext.getDrawable(TEST_RES_ID);
|
||||
|
||||
final FloatingMenuLayerDrawable actualDrawable =
|
||||
FloatingMenuLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID,
|
||||
final AccessibilityLayerDrawable actualDrawable =
|
||||
AccessibilityLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID,
|
||||
/* opacity= */ 27);
|
||||
|
||||
final Drawable actual1stDrawable = actualDrawable.getDrawable(0);
|
||||
@@ -60,14 +60,14 @@ public class FloatingMenuLayerDrawableTest {
|
||||
|
||||
@Test
|
||||
public void updateLayerDrawable_expectedFloatingMenuLayerDrawableState() {
|
||||
final FloatingMenuLayerDrawable originalDrawable =
|
||||
FloatingMenuLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID, /* opacity= */
|
||||
final AccessibilityLayerDrawable originalDrawable =
|
||||
AccessibilityLayerDrawable.createLayerDrawable(mContext, TEST_RES_ID, /* opacity= */
|
||||
72);
|
||||
|
||||
originalDrawable.updateLayerDrawable(mContext, TEST_RES_ID_2, /* opacity= */ 27);
|
||||
|
||||
assertThat(originalDrawable.getConstantState()).isEqualTo(
|
||||
new FloatingMenuLayerDrawable.FloatingMenuLayerDrawableState(mContext,
|
||||
new AccessibilityLayerDrawable.AccessibilityLayerDrawableState(mContext,
|
||||
TEST_RES_ID_2, /* opacity= */ 27));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user