Support accessibility for battery chart (1)
Remove the logic of disabling clickable when accessability is on in battery chartview.
Bug: 242989585
Test: manual
Change-Id: I92ce0ff5aac5220d686d600dbdf1d5738fe2c385
Merged-In: I92ce0ff5aac5220d686d600dbdf1d5738fe2c385
diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
index b51eacb..fc6daf7 100644
--- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
+++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java
@@ -20,7 +20,6 @@
import static java.lang.Math.round;
import static java.util.Objects.requireNonNull;
-import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
@@ -29,13 +28,11 @@
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
-import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
-import android.view.accessibility.AccessibilityManager;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -43,20 +40,15 @@
import androidx.appcompat.widget.AppCompatImageView;
import com.android.settings.R;
-import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.Utils;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Locale;
/** A widget component to draw chart graph. */
-public class BatteryChartView extends AppCompatImageView implements View.OnClickListener,
- AccessibilityManager.AccessibilityStateChangeListener {
+public class BatteryChartView extends AppCompatImageView implements View.OnClickListener {
private static final String TAG = "BatteryChartView";
- private static final List<String> ACCESSIBILITY_SERVICE_NAMES =
- Arrays.asList("SwitchAccessService", "TalkBackService", "JustSpeakService");
private static final int DIVIDER_COLOR = Color.parseColor("#CDCCC5");
private static final long UPDATE_STATE_DELAYED_TIME = 500L;
@@ -67,48 +59,31 @@
void onSelect(int trapezoidIndex);
}
- private BatteryChartViewModel mViewModel;
+ private final String[] mPercentages = getPercentages();
+ private final Rect mIndent = new Rect();
+ private final Rect[] mPercentageBounds = new Rect[]{new Rect(), new Rect(), new Rect()};
+ private final List<Rect> mAxisLabelsBounds = new ArrayList<>();
+ private BatteryChartViewModel mViewModel;
+ private int mHoveredIndex = BatteryChartViewModel.SELECTED_INDEX_INVALID;
private int mDividerWidth;
private int mDividerHeight;
private float mTrapezoidVOffset;
private float mTrapezoidHOffset;
- private boolean mIsSlotsClickabled;
- private String[] mPercentages = getPercentages();
-
- @VisibleForTesting
- int mHoveredIndex = BatteryChartViewModel.SELECTED_INDEX_INVALID;
-
- // Colors for drawing the trapezoid shape and dividers.
private int mTrapezoidColor;
private int mTrapezoidSolidColor;
private int mTrapezoidHoverColor;
- // For drawing the percentage information.
private int mTextPadding;
- private final Rect mIndent = new Rect();
- private final Rect[] mPercentageBounds =
- new Rect[]{new Rect(), new Rect(), new Rect()};
- // For drawing the axis label information.
- private final List<Rect> mAxisLabelsBounds = new ArrayList<>();
-
-
- @VisibleForTesting
- Handler mHandler = new Handler();
- @VisibleForTesting
- final Runnable mUpdateClickableStateRun = () -> updateClickableState();
-
- private Paint mTextPaint;
private Paint mDividerPaint;
private Paint mTrapezoidPaint;
+ private Paint mTextPaint;
+ private BatteryChartView.OnSelectListener mOnSelectListener;
@VisibleForTesting
- Paint mTrapezoidCurvePaint = null;
- @VisibleForTesting
TrapezoidSlot[] mTrapezoidSlots;
// Records the location to calculate selected index.
@VisibleForTesting
float mTouchUpEventX = Float.MIN_VALUE;
- private BatteryChartView.OnSelectListener mOnSelectListener;
public BatteryChartView(Context context) {
super(context, null);
@@ -261,66 +236,6 @@
view.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);
}
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
- updateClickableState();
- mContext.getSystemService(AccessibilityManager.class)
- .addAccessibilityStateChangeListener(/*listener=*/ this);
- }
-
- @Override
- public void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mContext.getSystemService(AccessibilityManager.class)
- .removeAccessibilityStateChangeListener(/*listener=*/ this);
- mHandler.removeCallbacks(mUpdateClickableStateRun);
- }
-
- @Override
- public void onAccessibilityStateChanged(boolean enabled) {
- Log.d(TAG, "onAccessibilityStateChanged:" + enabled);
- mHandler.removeCallbacks(mUpdateClickableStateRun);
- // We should delay it a while since accessibility manager will spend
- // some times to bind with new enabled accessibility services.
- mHandler.postDelayed(
- mUpdateClickableStateRun, UPDATE_STATE_DELAYED_TIME);
- }
-
- private void updateClickableState() {
- final Context context = mContext;
- mIsSlotsClickabled =
- FeatureFactory.getFactory(context)
- .getPowerUsageFeatureProvider(context)
- .isChartGraphSlotsEnabled(context)
- && !isAccessibilityEnabled(context);
- Log.d(TAG, "isChartGraphSlotsEnabled:" + mIsSlotsClickabled);
- setClickable(isClickable());
- // Initializes the trapezoid curve paint for non-clickable case.
- if (!mIsSlotsClickabled && mTrapezoidCurvePaint == null) {
- mTrapezoidCurvePaint = new Paint();
- mTrapezoidCurvePaint.setAntiAlias(true);
- mTrapezoidCurvePaint.setColor(mTrapezoidSolidColor);
- mTrapezoidCurvePaint.setStyle(Paint.Style.STROKE);
- mTrapezoidCurvePaint.setStrokeWidth(mDividerWidth * 2);
- } else if (mIsSlotsClickabled) {
- mTrapezoidCurvePaint = null;
- // Sets view model again to force update the click state.
- setViewModel(mViewModel);
- }
- invalidate();
- }
-
- @Override
- public void setClickable(boolean clickable) {
- super.setClickable(mIsSlotsClickabled && clickable);
- }
-
- @VisibleForTesting
- void setClickableForce(boolean clickable) {
- super.setClickable(clickable);
- }
-
private void initializeTrapezoidSlots(int count) {
mTrapezoidSlots = new TrapezoidSlot[count];
for (int index = 0; index < mTrapezoidSlots.length; index++) {
@@ -545,19 +460,14 @@
for (int index = 0; index < mTrapezoidSlots.length; index++) {
// Not draws the trapezoid for corner or not initialization cases.
if (!isValidToDraw(mViewModel, index)) {
- if (mTrapezoidCurvePaint != null && trapezoidCurvePath != null) {
- canvas.drawPath(trapezoidCurvePath, mTrapezoidCurvePaint);
- trapezoidCurvePath = null;
- }
continue;
}
// Configures the trapezoid paint color.
- final int trapezoidColor = mIsSlotsClickabled && (mViewModel.selectedIndex() == index
+ final int trapezoidColor = (mViewModel.selectedIndex() == index
|| mViewModel.selectedIndex() == BatteryChartViewModel.SELECTED_INDEX_ALL)
? mTrapezoidSolidColor : mTrapezoidColor;
- final boolean isHoverState =
- mIsSlotsClickabled && mHoveredIndex == index
- && isValidToDraw(mViewModel, mHoveredIndex);
+ final boolean isHoverState = mHoveredIndex == index && isValidToDraw(mViewModel,
+ mHoveredIndex);
mTrapezoidPaint.setColor(isHoverState ? mTrapezoidHoverColor : trapezoidColor);
final float leftTop = round(
@@ -574,22 +484,6 @@
trapezoidPath.lineTo(mTrapezoidSlots[index].mLeft, leftTop);
// Draws the trapezoid shape into canvas.
canvas.drawPath(trapezoidPath, mTrapezoidPaint);
-
- // Generates path for non-clickable trapezoid curve.
- if (mTrapezoidCurvePaint != null) {
- if (trapezoidCurvePath == null) {
- trapezoidCurvePath = new Path();
- trapezoidCurvePath.moveTo(mTrapezoidSlots[index].mLeft, leftTop);
- } else {
- trapezoidCurvePath.lineTo(mTrapezoidSlots[index].mLeft, leftTop);
- }
- trapezoidCurvePath.lineTo(mTrapezoidSlots[index].mRight, rightTop);
- }
- }
- // Draws the trapezoid curve for non-clickable case.
- if (mTrapezoidCurvePaint != null && trapezoidCurvePath != null) {
- canvas.drawPath(trapezoidCurvePath, mTrapezoidCurvePaint);
- trapezoidCurvePath = null;
}
}
@@ -645,29 +539,6 @@
formatPercentage(/*percentage=*/ 0, /*round=*/ true)};
}
- @VisibleForTesting
- static boolean isAccessibilityEnabled(Context context) {
- final AccessibilityManager accessibilityManager =
- context.getSystemService(AccessibilityManager.class);
- if (!accessibilityManager.isEnabled()) {
- return false;
- }
- final List<AccessibilityServiceInfo> serviceInfoList =
- accessibilityManager.getEnabledAccessibilityServiceList(
- AccessibilityServiceInfo.FEEDBACK_SPOKEN
- | AccessibilityServiceInfo.FEEDBACK_GENERIC);
- for (AccessibilityServiceInfo info : serviceInfoList) {
- for (String serviceName : ACCESSIBILITY_SERVICE_NAMES) {
- final String serviceId = info.getId();
- if (serviceId != null && serviceId.contains(serviceName)) {
- Log.d(TAG, "acccessibilityEnabled:" + serviceId);
- return true;
- }
- }
- }
- return false;
- }
-
// A container class for each trapezoid left and right location.
@VisibleForTesting
static final class TrapezoidSlot {
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewTest.java
index 8a43087..7e423e0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewTest.java
@@ -17,17 +17,11 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.Context;
import android.os.LocaleList;
import android.view.View;
-import android.view.accessibility.AccessibilityManager;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -40,8 +34,6 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Locale;
@@ -54,10 +46,6 @@
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
@Mock
- private AccessibilityServiceInfo mMockAccessibilityServiceInfo;
- @Mock
- private AccessibilityManager mMockAccessibilityManager;
- @Mock
private View mMockView;
@Before
@@ -69,34 +57,6 @@
mContext.getResources().getConfiguration().setLocales(
new LocaleList(new Locale("en_US")));
mBatteryChartView = new BatteryChartView(mContext);
- doReturn(mMockAccessibilityManager).when(mContext)
- .getSystemService(AccessibilityManager.class);
- doReturn("TalkBackService").when(mMockAccessibilityServiceInfo).getId();
- doReturn(Arrays.asList(mMockAccessibilityServiceInfo))
- .when(mMockAccessibilityManager)
- .getEnabledAccessibilityServiceList(anyInt());
- }
-
- @Test
- public void isAccessibilityEnabled_disable_returnFalse() {
- doReturn(false).when(mMockAccessibilityManager).isEnabled();
- assertThat(BatteryChartView.isAccessibilityEnabled(mContext)).isFalse();
- }
-
- @Test
- public void isAccessibilityEnabled_emptyInfo_returnFalse() {
- doReturn(true).when(mMockAccessibilityManager).isEnabled();
- doReturn(new ArrayList<AccessibilityServiceInfo>())
- .when(mMockAccessibilityManager)
- .getEnabledAccessibilityServiceList(anyInt());
-
- assertThat(BatteryChartView.isAccessibilityEnabled(mContext)).isFalse();
- }
-
- @Test
- public void isAccessibilityEnabled_validServiceId_returnTrue() {
- doReturn(true).when(mMockAccessibilityManager).isEnabled();
- assertThat(BatteryChartView.isAccessibilityEnabled(mContext)).isTrue();
}
@Test
@@ -130,116 +90,4 @@
mBatteryChartView.onClick(mMockView);
assertThat(selectedIndex[0]).isEqualTo(BatteryChartViewModel.SELECTED_INDEX_ALL);
}
-
- @Test
- public void clickable_isChartGraphSlotsEnabledIsFalse_notClickable() {
- mBatteryChartView.setClickableForce(true);
- when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
- .thenReturn(false);
-
- mBatteryChartView.onAttachedToWindow();
-
- assertThat(mBatteryChartView.isClickable()).isFalse();
- assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
- }
-
- @Test
- public void clickable_accessibilityIsDisabled_clickable() {
- mBatteryChartView.setClickableForce(true);
- when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
- .thenReturn(true);
- doReturn(false).when(mMockAccessibilityManager).isEnabled();
-
- mBatteryChartView.onAttachedToWindow();
-
- assertThat(mBatteryChartView.isClickable()).isTrue();
- assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
- }
-
- @Test
- public void clickable_accessibilityIsEnabledWithoutValidId_clickable() {
- mBatteryChartView.setClickableForce(true);
- when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
- .thenReturn(true);
- doReturn(true).when(mMockAccessibilityManager).isEnabled();
- doReturn(new ArrayList<AccessibilityServiceInfo>())
- .when(mMockAccessibilityManager)
- .getEnabledAccessibilityServiceList(anyInt());
-
- mBatteryChartView.onAttachedToWindow();
-
- assertThat(mBatteryChartView.isClickable()).isTrue();
- assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
- }
-
- @Test
- public void clickable_accessibilityIsEnabledWithValidId_notClickable() {
- mBatteryChartView.setClickableForce(true);
- when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
- .thenReturn(true);
- doReturn(true).when(mMockAccessibilityManager).isEnabled();
-
- mBatteryChartView.onAttachedToWindow();
-
- assertThat(mBatteryChartView.isClickable()).isFalse();
- assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
- }
-
- @Test
- public void clickable_restoreFromNonClickableState() {
- final List<Integer> levels = new ArrayList<Integer>();
- final List<String> texts = new ArrayList<String>();
- for (int index = 0; index < 13; index++) {
- levels.add(index + 1);
- texts.add("");
- }
- mBatteryChartView.setViewModel(new BatteryChartViewModel(levels, texts,
- BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS));
- mBatteryChartView.setClickableForce(true);
- when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
- .thenReturn(true);
- doReturn(true).when(mMockAccessibilityManager).isEnabled();
- mBatteryChartView.onAttachedToWindow();
- // Ensures the testing environment is correct.
- assertThat(mBatteryChartView.isClickable()).isFalse();
- // Turns off accessibility service.
- doReturn(false).when(mMockAccessibilityManager).isEnabled();
-
- mBatteryChartView.onAttachedToWindow();
-
- assertThat(mBatteryChartView.isClickable()).isTrue();
- }
-
- @Test
- public void onAttachedToWindow_addAccessibilityStateChangeListener() {
- mBatteryChartView.onAttachedToWindow();
- verify(mMockAccessibilityManager)
- .addAccessibilityStateChangeListener(mBatteryChartView);
- }
-
- @Test
- public void onDetachedFromWindow_removeAccessibilityStateChangeListener() {
- mBatteryChartView.onAttachedToWindow();
- mBatteryChartView.mHandler.postDelayed(
- mBatteryChartView.mUpdateClickableStateRun, 1000);
-
- mBatteryChartView.onDetachedFromWindow();
-
- verify(mMockAccessibilityManager)
- .removeAccessibilityStateChangeListener(mBatteryChartView);
- assertThat(mBatteryChartView.mHandler.hasCallbacks(
- mBatteryChartView.mUpdateClickableStateRun))
- .isFalse();
- }
-
- @Test
- public void onAccessibilityStateChanged_postUpdateStateRunnable() {
- mBatteryChartView.mHandler = spy(mBatteryChartView.mHandler);
- mBatteryChartView.onAccessibilityStateChanged(/*enabled=*/ true);
-
- verify(mBatteryChartView.mHandler)
- .removeCallbacks(mBatteryChartView.mUpdateClickableStateRun);
- verify(mBatteryChartView.mHandler)
- .postDelayed(mBatteryChartView.mUpdateClickableStateRun, 500L);
- }
}