1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 * 15 * 16 */ 17 package com.android.settings.fuelgauge; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.Mockito.doReturn; 24 import static org.mockito.Mockito.spy; 25 import static org.mockito.Mockito.verify; 26 import static org.mockito.Mockito.when; 27 28 import android.accessibilityservice.AccessibilityServiceInfo; 29 import android.content.Context; 30 import android.os.LocaleList; 31 import android.view.accessibility.AccessibilityManager; 32 33 import com.android.settings.testutils.FakeFeatureFactory; 34 35 import org.junit.Before; 36 import org.junit.Test; 37 import org.junit.runner.RunWith; 38 import org.mockito.Mock; 39 import org.mockito.MockitoAnnotations; 40 import org.robolectric.RobolectricTestRunner; 41 import org.robolectric.RuntimeEnvironment; 42 43 import java.util.Arrays; 44 import java.util.ArrayList; 45 import java.util.Locale; 46 47 @RunWith(RobolectricTestRunner.class) 48 public final class BatteryChartViewTest { 49 50 private Context mContext; 51 private BatteryChartView mBatteryChartView; 52 private FakeFeatureFactory mFeatureFactory; 53 private PowerUsageFeatureProvider mPowerUsageFeatureProvider; 54 55 @Mock private AccessibilityServiceInfo mockAccessibilityServiceInfo; 56 @Mock private AccessibilityManager mockAccessibilityManager; 57 58 @Before setUp()59 public void setUp() { 60 MockitoAnnotations.initMocks(this); 61 mFeatureFactory = FakeFeatureFactory.setupForTest(); 62 mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider; 63 mContext = spy(RuntimeEnvironment.application); 64 mContext.getResources().getConfiguration().setLocales( 65 new LocaleList(new Locale("en_US"))); 66 mBatteryChartView = new BatteryChartView(mContext); 67 doReturn(mockAccessibilityManager).when(mContext) 68 .getSystemService(AccessibilityManager.class); 69 doReturn("TalkBackService").when(mockAccessibilityServiceInfo).getId(); 70 doReturn(Arrays.asList(mockAccessibilityServiceInfo)) 71 .when(mockAccessibilityManager) 72 .getEnabledAccessibilityServiceList(anyInt()); 73 } 74 75 @Test testIsAccessibilityEnabled_disable_returnFalse()76 public void testIsAccessibilityEnabled_disable_returnFalse() { 77 doReturn(false).when(mockAccessibilityManager).isEnabled(); 78 assertThat(BatteryChartView.isAccessibilityEnabled(mContext)).isFalse(); 79 } 80 81 @Test testIsAccessibilityEnabled_emptyInfo_returnFalse()82 public void testIsAccessibilityEnabled_emptyInfo_returnFalse() { 83 doReturn(true).when(mockAccessibilityManager).isEnabled(); 84 doReturn(new ArrayList<AccessibilityServiceInfo>()) 85 .when(mockAccessibilityManager) 86 .getEnabledAccessibilityServiceList(anyInt()); 87 88 assertThat(BatteryChartView.isAccessibilityEnabled(mContext)).isFalse(); 89 } 90 91 @Test testIsAccessibilityEnabled_validServiceId_returnTrue()92 public void testIsAccessibilityEnabled_validServiceId_returnTrue() { 93 doReturn(true).when(mockAccessibilityManager).isEnabled(); 94 assertThat(BatteryChartView.isAccessibilityEnabled(mContext)).isTrue(); 95 } 96 97 @Test testSetSelectedIndex_invokesCallback()98 public void testSetSelectedIndex_invokesCallback() { 99 final int selectedIndex[] = new int[1]; 100 final int expectedIndex = 2; 101 mBatteryChartView.mSelectedIndex = 1; 102 mBatteryChartView.setOnSelectListener( 103 trapezoidIndex -> { 104 selectedIndex[0] = trapezoidIndex; 105 }); 106 107 mBatteryChartView.setSelectedIndex(expectedIndex); 108 109 assertThat(mBatteryChartView.mSelectedIndex) 110 .isEqualTo(expectedIndex); 111 assertThat(selectedIndex[0]).isEqualTo(expectedIndex); 112 } 113 114 @Test testSetSelectedIndex_sameIndex_notInvokesCallback()115 public void testSetSelectedIndex_sameIndex_notInvokesCallback() { 116 final int selectedIndex[] = new int[1]; 117 final int expectedIndex = 1; 118 mBatteryChartView.mSelectedIndex = expectedIndex; 119 mBatteryChartView.setOnSelectListener( 120 trapezoidIndex -> { 121 selectedIndex[0] = trapezoidIndex; 122 }); 123 124 mBatteryChartView.setSelectedIndex(expectedIndex); 125 126 assertThat(selectedIndex[0]).isNotEqualTo(expectedIndex); 127 } 128 129 @Test testClickable_isChartGraphSlotsEnabledIsFalse_notClickable()130 public void testClickable_isChartGraphSlotsEnabledIsFalse_notClickable() { 131 mBatteryChartView.setClickableForce(true); 132 when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext)) 133 .thenReturn(false); 134 135 mBatteryChartView.onAttachedToWindow(); 136 assertThat(mBatteryChartView.isClickable()).isFalse(); 137 assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull(); 138 } 139 140 @Test testClickable_accessibilityIsDisabled_clickable()141 public void testClickable_accessibilityIsDisabled_clickable() { 142 mBatteryChartView.setClickableForce(true); 143 when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext)) 144 .thenReturn(true); 145 doReturn(false).when(mockAccessibilityManager).isEnabled(); 146 147 mBatteryChartView.onAttachedToWindow(); 148 assertThat(mBatteryChartView.isClickable()).isTrue(); 149 assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull(); 150 } 151 152 @Test testClickable_accessibilityIsEnabledWithoutValidId_clickable()153 public void testClickable_accessibilityIsEnabledWithoutValidId_clickable() { 154 mBatteryChartView.setClickableForce(true); 155 when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext)) 156 .thenReturn(true); 157 doReturn(true).when(mockAccessibilityManager).isEnabled(); 158 doReturn(new ArrayList<AccessibilityServiceInfo>()) 159 .when(mockAccessibilityManager) 160 .getEnabledAccessibilityServiceList(anyInt()); 161 162 mBatteryChartView.onAttachedToWindow(); 163 assertThat(mBatteryChartView.isClickable()).isTrue(); 164 assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNull(); 165 } 166 167 @Test testClickable_accessibilityIsEnabledWithValidId_notClickable()168 public void testClickable_accessibilityIsEnabledWithValidId_notClickable() { 169 mBatteryChartView.setClickableForce(true); 170 when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext)) 171 .thenReturn(true); 172 doReturn(true).when(mockAccessibilityManager).isEnabled(); 173 174 mBatteryChartView.onAttachedToWindow(); 175 assertThat(mBatteryChartView.isClickable()).isFalse(); 176 assertThat(mBatteryChartView.mTrapezoidCurvePaint).isNotNull(); 177 } 178 179 @Test testClickable_restoreFromNonClickableState()180 public void testClickable_restoreFromNonClickableState() { 181 final int[] levels = new int[13]; 182 for (int index = 0; index < levels.length; index++) { 183 levels[index] = index + 1; 184 } 185 mBatteryChartView.setTrapezoidCount(12); 186 mBatteryChartView.setLevels(levels); 187 mBatteryChartView.setClickableForce(true); 188 when(mPowerUsageFeatureProvider.isChartGraphSlotsEnabled(mContext)) 189 .thenReturn(true); 190 doReturn(true).when(mockAccessibilityManager).isEnabled(); 191 mBatteryChartView.onAttachedToWindow(); 192 // Ensures the testing environment is correct. 193 assertThat(mBatteryChartView.isClickable()).isFalse(); 194 // Turns off accessibility service. 195 doReturn(false).when(mockAccessibilityManager).isEnabled(); 196 197 mBatteryChartView.onAttachedToWindow(); 198 199 assertThat(mBatteryChartView.isClickable()).isTrue(); 200 } 201 202 @Test testOnAttachedToWindow_addAccessibilityStateChangeListener()203 public void testOnAttachedToWindow_addAccessibilityStateChangeListener() { 204 mBatteryChartView.onAttachedToWindow(); 205 verify(mockAccessibilityManager) 206 .addAccessibilityStateChangeListener(mBatteryChartView); 207 } 208 209 @Test testOnDetachedFromWindow_removeAccessibilityStateChangeListener()210 public void testOnDetachedFromWindow_removeAccessibilityStateChangeListener() { 211 mBatteryChartView.onAttachedToWindow(); 212 mBatteryChartView.mHandler.postDelayed( 213 mBatteryChartView.mUpdateClickableStateRun, 1000); 214 215 mBatteryChartView.onDetachedFromWindow(); 216 217 verify(mockAccessibilityManager) 218 .removeAccessibilityStateChangeListener(mBatteryChartView); 219 assertThat(mBatteryChartView.mHandler.hasCallbacks( 220 mBatteryChartView.mUpdateClickableStateRun)) 221 .isFalse(); 222 } 223 224 @Test testOnAccessibilityStateChanged_postUpdateStateRunnable()225 public void testOnAccessibilityStateChanged_postUpdateStateRunnable() { 226 mBatteryChartView.mHandler = spy(mBatteryChartView.mHandler); 227 mBatteryChartView.onAccessibilityStateChanged(/*enabled=*/ true); 228 229 verify(mBatteryChartView.mHandler) 230 .removeCallbacks(mBatteryChartView.mUpdateClickableStateRun); 231 verify(mBatteryChartView.mHandler) 232 .postDelayed(mBatteryChartView.mUpdateClickableStateRun, 500L); 233 } 234 } 235