Loading src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java +12 −141 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import static com.android.settings.Utils.formatPercentage; 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; Loading @@ -29,13 +28,11 @@ import android.graphics.CornerPathEffect; 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; Loading @@ -43,20 +40,15 @@ import androidx.annotation.VisibleForTesting; 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; Loading @@ -67,48 +59,31 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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); Loading Loading @@ -261,66 +236,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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++) { Loading Loading @@ -545,19 +460,14 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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( Loading @@ -574,22 +484,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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; } } Loading Loading @@ -645,29 +539,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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 { Loading tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewTest.java +0 −152 Original line number Diff line number Diff line Loading @@ -17,17 +17,11 @@ package com.android.settings.fuelgauge.batteryusage; 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; Loading @@ -40,8 +34,6 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Locale; Loading @@ -53,10 +45,6 @@ public final class BatteryChartViewTest { private FakeFeatureFactory mFeatureFactory; private PowerUsageFeatureProvider mPowerUsageFeatureProvider; @Mock private AccessibilityServiceInfo mMockAccessibilityServiceInfo; @Mock private AccessibilityManager mMockAccessibilityManager; @Mock private View mMockView; Loading @@ -69,34 +57,6 @@ public final class BatteryChartViewTest { 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 Loading Loading @@ -130,116 +90,4 @@ public final class BatteryChartViewTest { 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); } } Loading
src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java +12 −141 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import static com.android.settings.Utils.formatPercentage; 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; Loading @@ -29,13 +28,11 @@ import android.graphics.CornerPathEffect; 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; Loading @@ -43,20 +40,15 @@ import androidx.annotation.VisibleForTesting; 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; Loading @@ -67,48 +59,31 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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); Loading Loading @@ -261,66 +236,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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++) { Loading Loading @@ -545,19 +460,14 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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( Loading @@ -574,22 +484,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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; } } Loading Loading @@ -645,29 +539,6 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick 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 { Loading
tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryChartViewTest.java +0 −152 Original line number Diff line number Diff line Loading @@ -17,17 +17,11 @@ package com.android.settings.fuelgauge.batteryusage; 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; Loading @@ -40,8 +34,6 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Locale; Loading @@ -53,10 +45,6 @@ public final class BatteryChartViewTest { private FakeFeatureFactory mFeatureFactory; private PowerUsageFeatureProvider mPowerUsageFeatureProvider; @Mock private AccessibilityServiceInfo mMockAccessibilityServiceInfo; @Mock private AccessibilityManager mMockAccessibilityManager; @Mock private View mMockView; Loading @@ -69,34 +57,6 @@ public final class BatteryChartViewTest { 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 Loading Loading @@ -130,116 +90,4 @@ public final class BatteryChartViewTest { 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); } }