Merge "Make chart time slot not clickable when accessibility servie is enabled" into sc-dev am: f70cb82b0c
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/14515927 Change-Id: Ief6ab1b26d456036583b4a17be894669575d2907
This commit is contained in:
@@ -24,6 +24,7 @@ import android.graphics.CornerPathEffect;
|
|||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.os.Handler;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.view.HapticFeedbackConstants;
|
||||||
@@ -44,7 +45,8 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
/** A widget component to draw chart graph. */
|
/** A widget component to draw chart graph. */
|
||||||
public class BatteryChartView extends AppCompatImageView implements View.OnClickListener {
|
public class BatteryChartView extends AppCompatImageView implements View.OnClickListener,
|
||||||
|
AccessibilityManager.AccessibilityStateChangeListener {
|
||||||
private static final String TAG = "BatteryChartView";
|
private static final String TAG = "BatteryChartView";
|
||||||
private static final List<String> ACCESSIBILITY_SERVICE_NAMES =
|
private static final List<String> ACCESSIBILITY_SERVICE_NAMES =
|
||||||
Arrays.asList("SwitchAccessService", "TalkBackService", "JustSpeakService");
|
Arrays.asList("SwitchAccessService", "TalkBackService", "JustSpeakService");
|
||||||
@@ -52,6 +54,8 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
|||||||
private static final String[] PERCENTAGES = new String[] {"100%", "50%", "0%"};
|
private static final String[] PERCENTAGES = new String[] {"100%", "50%", "0%"};
|
||||||
private static final int DEFAULT_TRAPEZOID_COUNT = 12;
|
private static final int DEFAULT_TRAPEZOID_COUNT = 12;
|
||||||
private static final int DEFAULT_TIMESTAMP_COUNT = 4;
|
private static final int DEFAULT_TIMESTAMP_COUNT = 4;
|
||||||
|
private static final int DIVIDER_COLOR = Color.parseColor("#CDCCC5");
|
||||||
|
private static final long UPDATE_STATE_DELAYED_TIME = 500L;
|
||||||
|
|
||||||
/** Selects all trapezoid shapes. */
|
/** Selects all trapezoid shapes. */
|
||||||
public static final int SELECTED_INDEX_ALL = -1;
|
public static final int SELECTED_INDEX_ALL = -1;
|
||||||
@@ -74,7 +78,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
|||||||
// Colors for drawing the trapezoid shape and dividers.
|
// Colors for drawing the trapezoid shape and dividers.
|
||||||
private int mTrapezoidColor;
|
private int mTrapezoidColor;
|
||||||
private int mTrapezoidSolidColor;
|
private int mTrapezoidSolidColor;
|
||||||
private final int mDividerColor = Color.parseColor("#CDCCC5");
|
|
||||||
// For drawing the percentage information.
|
// For drawing the percentage information.
|
||||||
private int mTextPadding;
|
private int mTextPadding;
|
||||||
private final Rect mIndent = new Rect();
|
private final Rect mIndent = new Rect();
|
||||||
@@ -85,11 +88,17 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
|||||||
private final Rect[] mTimestampsBounds =
|
private final Rect[] mTimestampsBounds =
|
||||||
new Rect[] {new Rect(), new Rect(), new Rect(), new Rect()};
|
new Rect[] {new Rect(), new Rect(), new Rect(), new Rect()};
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
Handler mHandler = new Handler();
|
||||||
|
@VisibleForTesting
|
||||||
|
final Runnable mUpdateClickableStateRun = () -> updateClickableState();
|
||||||
|
|
||||||
private int[] mLevels;
|
private int[] mLevels;
|
||||||
private Paint mTextPaint;
|
private Paint mTextPaint;
|
||||||
private Paint mDividerPaint;
|
private Paint mDividerPaint;
|
||||||
private Paint mTrapezoidPaint;
|
private Paint mTrapezoidPaint;
|
||||||
private Paint mTrapezoidCurvePaint = null;
|
@VisibleForTesting
|
||||||
|
Paint mTrapezoidCurvePaint = null;
|
||||||
private TrapezoidSlot[] mTrapezoidSlots;
|
private TrapezoidSlot[] mTrapezoidSlots;
|
||||||
// Records the location to calculate selected index.
|
// Records the location to calculate selected index.
|
||||||
private MotionEvent mTouchUpEvent;
|
private MotionEvent mTouchUpEvent;
|
||||||
@@ -257,6 +266,26 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
|||||||
public void onAttachedToWindow() {
|
public void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
updateClickableState();
|
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() {
|
private void updateClickableState() {
|
||||||
@@ -275,6 +304,10 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
|||||||
mTrapezoidCurvePaint.setColor(mTrapezoidSolidColor);
|
mTrapezoidCurvePaint.setColor(mTrapezoidSolidColor);
|
||||||
mTrapezoidCurvePaint.setStyle(Paint.Style.STROKE);
|
mTrapezoidCurvePaint.setStyle(Paint.Style.STROKE);
|
||||||
mTrapezoidCurvePaint.setStrokeWidth(mDividerWidth * 2);
|
mTrapezoidCurvePaint.setStrokeWidth(mDividerWidth * 2);
|
||||||
|
} else if (mIsSlotsClickabled) {
|
||||||
|
mTrapezoidCurvePaint = null;
|
||||||
|
// Sets levels again to force update the click state.
|
||||||
|
setLevels(mLevels);
|
||||||
}
|
}
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
@@ -299,7 +332,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
|||||||
mDividerHeight = resources.getDimensionPixelSize(R.dimen.chartview_divider_height);
|
mDividerHeight = resources.getDimensionPixelSize(R.dimen.chartview_divider_height);
|
||||||
mDividerPaint = new Paint();
|
mDividerPaint = new Paint();
|
||||||
mDividerPaint.setAntiAlias(true);
|
mDividerPaint.setAntiAlias(true);
|
||||||
mDividerPaint.setColor(mDividerColor);
|
mDividerPaint.setColor(DIVIDER_COLOR);
|
||||||
mDividerPaint.setStyle(Paint.Style.STROKE);
|
mDividerPaint.setStyle(Paint.Style.STROKE);
|
||||||
mDividerPaint.setStrokeWidth(mDividerWidth);
|
mDividerPaint.setStrokeWidth(mDividerWidth);
|
||||||
Log.i(TAG, "mDividerWidth:" + mDividerWidth);
|
Log.i(TAG, "mDividerWidth:" + mDividerWidth);
|
||||||
|
@@ -130,6 +130,7 @@ public final class BatteryChartViewTest {
|
|||||||
|
|
||||||
mBatteryChartView.onAttachedToWindow();
|
mBatteryChartView.onAttachedToWindow();
|
||||||
assertThat(mBatteryChartView.isClickable()).isFalse();
|
assertThat(mBatteryChartView.isClickable()).isFalse();
|
||||||
|
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -141,6 +142,7 @@ public final class BatteryChartViewTest {
|
|||||||
|
|
||||||
mBatteryChartView.onAttachedToWindow();
|
mBatteryChartView.onAttachedToWindow();
|
||||||
assertThat(mBatteryChartView.isClickable()).isTrue();
|
assertThat(mBatteryChartView.isClickable()).isTrue();
|
||||||
|
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -155,6 +157,7 @@ public final class BatteryChartViewTest {
|
|||||||
|
|
||||||
mBatteryChartView.onAttachedToWindow();
|
mBatteryChartView.onAttachedToWindow();
|
||||||
assertThat(mBatteryChartView.isClickable()).isTrue();
|
assertThat(mBatteryChartView.isClickable()).isTrue();
|
||||||
|
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -166,5 +169,62 @@ public final class BatteryChartViewTest {
|
|||||||
|
|
||||||
mBatteryChartView.onAttachedToWindow();
|
mBatteryChartView.onAttachedToWindow();
|
||||||
assertThat(mBatteryChartView.isClickable()).isFalse();
|
assertThat(mBatteryChartView.isClickable()).isFalse();
|
||||||
|
assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClickable_restoreFromNonClickableState() {
|
||||||
|
final int[] levels = new int[13];
|
||||||
|
for (int index = 0; index < levels.length; index++) {
|
||||||
|
levels[index] = index + 1;
|
||||||
|
}
|
||||||
|
mBatteryChartView.setTrapezoidCount(12);
|
||||||
|
mBatteryChartView.setLevels(levels);
|
||||||
|
mBatteryChartView.setClickableForce(true);
|
||||||
|
when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext))
|
||||||
|
.thenReturn(true);
|
||||||
|
doReturn(true).when(mockAccessibilityManager).isEnabled();
|
||||||
|
mBatteryChartView.onAttachedToWindow();
|
||||||
|
// Ensures the testing environment is correct.
|
||||||
|
assertThat(mBatteryChartView.isClickable()).isFalse();
|
||||||
|
// Turns off accessibility service.
|
||||||
|
doReturn(false).when(mockAccessibilityManager).isEnabled();
|
||||||
|
|
||||||
|
mBatteryChartView.onAttachedToWindow();
|
||||||
|
|
||||||
|
assertThat(mBatteryChartView.isClickable()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnAttachedToWindow_addAccessibilityStateChangeListener() {
|
||||||
|
mBatteryChartView.onAttachedToWindow();
|
||||||
|
verify(mockAccessibilityManager)
|
||||||
|
.addAccessibilityStateChangeListener(mBatteryChartView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnDetachedFromWindow_removeAccessibilityStateChangeListener() {
|
||||||
|
mBatteryChartView.onAttachedToWindow();
|
||||||
|
mBatteryChartView.mHandler.postDelayed(
|
||||||
|
mBatteryChartView.mUpdateClickableStateRun, 1000);
|
||||||
|
|
||||||
|
mBatteryChartView.onDetachedFromWindow();
|
||||||
|
|
||||||
|
verify(mockAccessibilityManager)
|
||||||
|
.removeAccessibilityStateChangeListener(mBatteryChartView);
|
||||||
|
assertThat(mBatteryChartView.mHandler.hasCallbacks(
|
||||||
|
mBatteryChartView.mUpdateClickableStateRun))
|
||||||
|
.isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnAccessibilityStateChanged_postUpdateStateRunnable() {
|
||||||
|
mBatteryChartView.mHandler = spy(mBatteryChartView.mHandler);
|
||||||
|
mBatteryChartView.onAccessibilityStateChanged(/*enabled=*/ true);
|
||||||
|
|
||||||
|
verify(mBatteryChartView.mHandler)
|
||||||
|
.removeCallbacks(mBatteryChartView.mUpdateClickableStateRun);
|
||||||
|
verify(mBatteryChartView.mHandler)
|
||||||
|
.postDelayed(mBatteryChartView.mUpdateClickableStateRun, 500L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user