Merge "Update accesibility button to suuport accessibility gesutre" into sc-v2-dev

This commit is contained in:
TreeHugger Robot
2021-07-22 18:54:00 +00:00
committed by Android (Google) Code Review
17 changed files with 505 additions and 64 deletions

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);