1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.bluetooth; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.never; 22 import static org.mockito.Mockito.verify; 23 import static org.mockito.Mockito.when; 24 import static org.robolectric.Shadows.shadowOf; 25 26 import android.bluetooth.BluetoothAdapter; 27 import android.bluetooth.BluetoothDevice; 28 import android.content.Context; 29 import android.graphics.Bitmap; 30 import android.graphics.drawable.Drawable; 31 import android.provider.DeviceConfig; 32 import android.view.LayoutInflater; 33 import android.view.View; 34 import android.widget.ImageView; 35 import android.widget.LinearLayout; 36 import android.widget.TextView; 37 38 import com.android.settings.R; 39 import com.android.settings.core.BasePreferenceController; 40 import com.android.settings.core.SettingsUIDeviceConfig; 41 import com.android.settings.fuelgauge.BatteryMeterView; 42 import com.android.settings.testutils.shadow.ShadowDeviceConfig; 43 import com.android.settings.testutils.shadow.ShadowEntityHeaderController; 44 import com.android.settingslib.bluetooth.BluetoothUtils; 45 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 46 import com.android.settingslib.utils.StringUtil; 47 import com.android.settingslib.widget.LayoutPreference; 48 49 import org.junit.Before; 50 import org.junit.Test; 51 import org.junit.runner.RunWith; 52 import org.mockito.Mock; 53 import org.mockito.MockitoAnnotations; 54 import org.robolectric.RobolectricTestRunner; 55 import org.robolectric.RuntimeEnvironment; 56 import org.robolectric.annotation.Config; 57 58 @RunWith(RobolectricTestRunner.class) 59 @Config(shadows = {ShadowEntityHeaderController.class, ShadowDeviceConfig.class}) 60 public class AdvancedBluetoothDetailsHeaderControllerTest { 61 private static final int BATTERY_LEVEL_MAIN = 30; 62 private static final int BATTERY_LEVEL_LEFT = 25; 63 private static final int BATTERY_LEVEL_RIGHT = 45; 64 private static final int LOW_BATTERY_LEVEL = 15; 65 private static final int CASE_LOW_BATTERY_LEVEL = 19; 66 private static final int LOW_BATTERY_LEVEL_THRESHOLD = 15; 67 private static final int BATTERY_LEVEL_5 = 5; 68 private static final int BATTERY_LEVEL_50 = 50; 69 private static final String ICON_URI = "content://test.provider/icon.png"; 70 private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C"; 71 private static final String DEVICE_SUMMARY = "test summary"; 72 73 private Context mContext; 74 75 @Mock 76 private BluetoothDevice mBluetoothDevice; 77 @Mock 78 private Bitmap mBitmap; 79 @Mock 80 private ImageView mImageView; 81 @Mock 82 private CachedBluetoothDevice mCachedDevice; 83 @Mock 84 private BluetoothAdapter mBluetoothAdapter; 85 private AdvancedBluetoothDetailsHeaderController mController; 86 private LayoutPreference mLayoutPreference; 87 88 @Before setUp()89 public void setUp() { 90 MockitoAnnotations.initMocks(this); 91 92 mContext = RuntimeEnvironment.application; 93 mController = new AdvancedBluetoothDetailsHeaderController(mContext, "pref_Key"); 94 when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice); 95 mController.init(mCachedDevice); 96 mLayoutPreference = new LayoutPreference(mContext, 97 LayoutInflater.from(mContext).inflate(R.layout.advanced_bt_entity_header, null)); 98 mController.mLayoutPreference = mLayoutPreference; 99 mController.mBluetoothAdapter = mBluetoothAdapter; 100 when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice); 101 when(mCachedDevice.getAddress()).thenReturn(MAC_ADDRESS); 102 } 103 104 @Test createBatteryIcon_hasCorrectInfo()105 public void createBatteryIcon_hasCorrectInfo() { 106 final Drawable drawable = mController.createBtBatteryIcon(mContext, BATTERY_LEVEL_MAIN, 107 true /* charging */); 108 assertThat(drawable).isInstanceOf(BatteryMeterView.BatteryMeterDrawable.class); 109 110 final BatteryMeterView.BatteryMeterDrawable iconDrawable = 111 (BatteryMeterView.BatteryMeterDrawable) drawable; 112 assertThat(iconDrawable.getBatteryLevel()).isEqualTo(BATTERY_LEVEL_MAIN); 113 assertThat(iconDrawable.getCharging()).isTrue(); 114 } 115 116 @Test refresh_connectedWatch_behaveAsExpected()117 public void refresh_connectedWatch_behaveAsExpected() { 118 when(mBluetoothDevice.getMetadata( 119 BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn( 120 BluetoothDevice.DEVICE_TYPE_WATCH.getBytes()); 121 when(mBluetoothDevice.getMetadata( 122 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( 123 String.valueOf(false).getBytes()); 124 when(mCachedDevice.isConnected()).thenReturn(true); 125 126 mController.refresh(); 127 128 assertThat(mLayoutPreference.findViewById(R.id.layout_left).getVisibility()).isEqualTo( 129 View.GONE); 130 assertThat(mLayoutPreference.findViewById(R.id.layout_right).getVisibility()).isEqualTo( 131 View.GONE); 132 assertThat(mLayoutPreference.findViewById(R.id.layout_middle).getVisibility()).isEqualTo( 133 View.VISIBLE); 134 // TODO (b/188954766) : clarify settings design 135 } 136 137 @Test refresh_connectedWatch_unknownBatteryLevel_shouldNotShowBatteryLevel()138 public void refresh_connectedWatch_unknownBatteryLevel_shouldNotShowBatteryLevel() { 139 when(mBluetoothDevice.getMetadata( 140 BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn( 141 BluetoothDevice.DEVICE_TYPE_WATCH.getBytes()); 142 when(mBluetoothDevice.getMetadata( 143 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( 144 String.valueOf(false).getBytes()); 145 when(mBluetoothDevice.getMetadata( 146 BluetoothDevice.METADATA_MAIN_BATTERY)).thenReturn( 147 String.valueOf(BluetoothUtils.META_INT_ERROR).getBytes()); 148 when(mBluetoothDevice.getBatteryLevel()).thenReturn(BluetoothDevice.BATTERY_LEVEL_UNKNOWN); 149 when(mCachedDevice.isConnected()).thenReturn(true); 150 151 mController.refresh(); 152 153 assertThat(mLayoutPreference.findViewById(R.id.layout_left).getVisibility()).isEqualTo( 154 View.GONE); 155 assertThat(mLayoutPreference.findViewById(R.id.layout_right).getVisibility()).isEqualTo( 156 View.GONE); 157 assertThat(mLayoutPreference.findViewById(R.id.layout_middle).getVisibility()).isEqualTo( 158 View.VISIBLE); 159 assertThat(mLayoutPreference.findViewById(R.id.layout_middle) 160 .requireViewById(R.id.bt_battery_summary).getVisibility()).isEqualTo(View.GONE); 161 } 162 163 @Test refresh_connectedUntetheredHeadset_behaveAsExpected()164 public void refresh_connectedUntetheredHeadset_behaveAsExpected() { 165 when(mBluetoothDevice.getMetadata( 166 BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn( 167 BluetoothDevice.DEVICE_TYPE_UNTETHERED_HEADSET.getBytes()); 168 when(mBluetoothDevice.getMetadata( 169 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( 170 String.valueOf(false).getBytes()); 171 when(mBluetoothDevice.getMetadata( 172 BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn( 173 String.valueOf(BATTERY_LEVEL_LEFT).getBytes()); 174 when(mBluetoothDevice.getMetadata( 175 BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn( 176 String.valueOf(BATTERY_LEVEL_RIGHT).getBytes()); 177 when(mBluetoothDevice.getMetadata( 178 BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY)).thenReturn( 179 String.valueOf(BATTERY_LEVEL_MAIN).getBytes()); 180 when(mCachedDevice.isConnected()).thenReturn(true); 181 182 mController.refresh(); 183 184 assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_left), BATTERY_LEVEL_LEFT); 185 assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_right), BATTERY_LEVEL_RIGHT); 186 assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_middle), BATTERY_LEVEL_MAIN); 187 } 188 189 @Test refresh_connected_updateCorrectInfo()190 public void refresh_connected_updateCorrectInfo() { 191 when(mBluetoothDevice.getMetadata( 192 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( 193 String.valueOf(true).getBytes()); 194 when(mBluetoothDevice.getMetadata( 195 BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn( 196 String.valueOf(BATTERY_LEVEL_LEFT).getBytes()); 197 when(mBluetoothDevice.getMetadata( 198 BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn( 199 String.valueOf(BATTERY_LEVEL_RIGHT).getBytes()); 200 when(mBluetoothDevice.getMetadata( 201 BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY)).thenReturn( 202 String.valueOf(BATTERY_LEVEL_MAIN).getBytes()); 203 204 when(mCachedDevice.isConnected()).thenReturn(true); 205 mController.refresh(); 206 207 assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_left), BATTERY_LEVEL_LEFT); 208 assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_right), BATTERY_LEVEL_RIGHT); 209 assertBatteryLevel(mLayoutPreference.findViewById(R.id.layout_middle), BATTERY_LEVEL_MAIN); 210 } 211 212 @Test refresh_disconnected_updateCorrectInfo()213 public void refresh_disconnected_updateCorrectInfo() { 214 when(mCachedDevice.isConnected()).thenReturn(false); 215 216 mController.refresh(); 217 218 final LinearLayout layout = mLayoutPreference.findViewById(R.id.layout_middle); 219 220 assertThat(mLayoutPreference.findViewById(R.id.layout_left).getVisibility()).isEqualTo( 221 View.GONE); 222 assertThat(mLayoutPreference.findViewById(R.id.layout_right).getVisibility()).isEqualTo( 223 View.GONE); 224 assertThat(layout.getVisibility()).isEqualTo(View.VISIBLE); 225 assertThat(layout.findViewById(R.id.header_title).getVisibility()).isEqualTo(View.GONE); 226 assertThat(layout.findViewById(R.id.bt_battery_summary).getVisibility()).isEqualTo( 227 View.GONE); 228 assertThat(layout.findViewById(R.id.bt_battery_icon).getVisibility()).isEqualTo(View.GONE); 229 assertThat(layout.findViewById(R.id.header_icon).getVisibility()).isEqualTo(View.VISIBLE); 230 } 231 232 @Test refresh_connectedWatch_checkSummary()233 public void refresh_connectedWatch_checkSummary() { 234 when(mBluetoothDevice.getMetadata( 235 BluetoothDevice.METADATA_DEVICE_TYPE)).thenReturn( 236 BluetoothDevice.DEVICE_TYPE_WATCH.getBytes()); 237 when(mCachedDevice.isConnected()).thenReturn(true); 238 when(mCachedDevice.getConnectionSummary(/* shortSummary= */ true)) 239 .thenReturn(DEVICE_SUMMARY); 240 241 mController.refresh(); 242 243 assertThat(((TextView) (mLayoutPreference.findViewById(R.id.entity_header_summary))) 244 .getText()).isEqualTo(DEVICE_SUMMARY); 245 } 246 247 @Test refresh_withLowBatteryAndUncharged_showAlertIcon()248 public void refresh_withLowBatteryAndUncharged_showAlertIcon() { 249 when(mBluetoothDevice.getMetadata( 250 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn( 251 String.valueOf(true).getBytes()); 252 when(mBluetoothDevice.getMetadata( 253 BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY)).thenReturn( 254 String.valueOf(LOW_BATTERY_LEVEL).getBytes()); 255 when(mBluetoothDevice.getMetadata( 256 BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY)).thenReturn( 257 String.valueOf(LOW_BATTERY_LEVEL).getBytes()); 258 when(mBluetoothDevice.getMetadata( 259 BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY)).thenReturn( 260 String.valueOf(CASE_LOW_BATTERY_LEVEL).getBytes()); 261 when(mBluetoothDevice.getMetadata( 262 BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING)).thenReturn( 263 String.valueOf(false).getBytes()); 264 when(mBluetoothDevice.getMetadata( 265 BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING)).thenReturn( 266 String.valueOf(true).getBytes()); 267 when(mBluetoothDevice.getMetadata( 268 BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING)).thenReturn( 269 String.valueOf(false).getBytes()); 270 when(mCachedDevice.isConnected()).thenReturn(true); 271 272 mController.refresh(); 273 274 assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_left), 275 R.drawable.ic_battery_alert_24dp); 276 assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_right), /* resId= */-1); 277 assertBatteryIcon(mLayoutPreference.findViewById(R.id.layout_middle), 278 R.drawable.ic_battery_alert_24dp); 279 } 280 281 @Test getAvailabilityStatus_untetheredHeadsetWithConfigOn_returnAvailable()282 public void getAvailabilityStatus_untetheredHeadsetWithConfigOn_returnAvailable() { 283 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI, 284 SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true); 285 when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) 286 .thenReturn("true".getBytes()); 287 288 assertThat(mController.getAvailabilityStatus()).isEqualTo( 289 BasePreferenceController.AVAILABLE); 290 } 291 292 @Test getAvailabilityStatus_untetheredHeadsetWithConfigOff_returnUnavailable()293 public void getAvailabilityStatus_untetheredHeadsetWithConfigOff_returnUnavailable() { 294 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI, 295 SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "false", true); 296 when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) 297 .thenReturn("true".getBytes()); 298 299 assertThat(mController.getAvailabilityStatus()).isEqualTo( 300 BasePreferenceController.CONDITIONALLY_UNAVAILABLE); 301 } 302 303 @Test getAvailabilityStatus_notUntetheredHeadsetWithConfigOn_returnUnavailable()304 public void getAvailabilityStatus_notUntetheredHeadsetWithConfigOn_returnUnavailable() { 305 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI, 306 SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true); 307 when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) 308 .thenReturn("false".getBytes()); 309 310 assertThat(mController.getAvailabilityStatus()).isEqualTo( 311 BasePreferenceController.CONDITIONALLY_UNAVAILABLE); 312 } 313 314 @Test getAvailabilityStatus_notUntetheredHeadsetWithConfigOff_returnUnavailable()315 public void getAvailabilityStatus_notUntetheredHeadsetWithConfigOff_returnUnavailable() { 316 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI, 317 SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "false", true); 318 when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) 319 .thenReturn("false".getBytes()); 320 321 assertThat(mController.getAvailabilityStatus()).isEqualTo( 322 BasePreferenceController.CONDITIONALLY_UNAVAILABLE); 323 } 324 325 @Test updateIcon_existInCache_setImageBitmap()326 public void updateIcon_existInCache_setImageBitmap() { 327 mController.mIconCache.put(ICON_URI, mBitmap); 328 329 mController.updateIcon(mImageView, ICON_URI); 330 331 verify(mImageView).setImageBitmap(mBitmap); 332 } 333 334 @Test onStart_isAvailable_registerCallback()335 public void onStart_isAvailable_registerCallback() { 336 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI, 337 SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true); 338 when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) 339 .thenReturn("true".getBytes()); 340 341 mController.onStart(); 342 343 verify(mBluetoothAdapter).addOnMetadataChangedListener(mBluetoothDevice, 344 mContext.getMainExecutor(), mController.mMetadataListener); 345 } 346 347 @Test onStop_isRegisterCallback_unregisterCallback()348 public void onStop_isRegisterCallback_unregisterCallback() { 349 mController.mIsRegisterCallback = true; 350 351 mController.onStop(); 352 353 verify(mBluetoothAdapter).removeOnMetadataChangedListener(mBluetoothDevice, 354 mController.mMetadataListener); 355 } 356 357 @Test onStart_notAvailable_registerCallback()358 public void onStart_notAvailable_registerCallback() { 359 when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) 360 .thenReturn("false".getBytes()); 361 362 mController.onStart(); 363 364 verify(mBluetoothAdapter, never()).addOnMetadataChangedListener(mBluetoothDevice, 365 mContext.getMainExecutor(), mController.mMetadataListener); 366 } 367 368 @Test onStop_notRegisterCallback_unregisterCallback()369 public void onStop_notRegisterCallback_unregisterCallback() { 370 mController.mIsRegisterCallback = false; 371 372 mController.onStop(); 373 374 verify(mBluetoothAdapter, never()).removeOnMetadataChangedListener(mBluetoothDevice, 375 mController.mMetadataListener); 376 } 377 378 @Test onDestroy_recycleBitmap()379 public void onDestroy_recycleBitmap() { 380 mController.mIconCache.put(ICON_URI, mBitmap); 381 382 mController.onDestroy(); 383 384 assertThat(mController.mIconCache).isEmpty(); 385 verify(mBitmap).recycle(); 386 } 387 388 @Test showBatteryPredictionIfNecessary_estimateReadyIsAvailable_showView()389 public void showBatteryPredictionIfNecessary_estimateReadyIsAvailable_showView() { 390 mController.showBatteryPredictionIfNecessary(1, 14218009, 391 mLayoutPreference.findViewById(R.id.layout_left)); 392 mController.showBatteryPredictionIfNecessary(1, 14218009, 393 mLayoutPreference.findViewById(R.id.layout_middle)); 394 mController.showBatteryPredictionIfNecessary(1, 14218009, 395 mLayoutPreference.findViewById(R.id.layout_right)); 396 397 assertBatteryPredictionVisible(mLayoutPreference.findViewById(R.id.layout_left), 398 View.VISIBLE); 399 assertBatteryPredictionVisible(mLayoutPreference.findViewById(R.id.layout_middle), 400 View.VISIBLE); 401 assertBatteryPredictionVisible(mLayoutPreference.findViewById(R.id.layout_right), 402 View.VISIBLE); 403 } 404 405 @Test showBatteryPredictionIfNecessary_estimateReadyIsNotAvailable_notShowView()406 public void showBatteryPredictionIfNecessary_estimateReadyIsNotAvailable_notShowView() { 407 mController.showBatteryPredictionIfNecessary(0, 14218009, 408 mLayoutPreference.findViewById(R.id.layout_left)); 409 mController.showBatteryPredictionIfNecessary(0, 14218009, 410 mLayoutPreference.findViewById(R.id.layout_middle)); 411 mController.showBatteryPredictionIfNecessary(0, 14218009, 412 mLayoutPreference.findViewById(R.id.layout_right)); 413 414 assertBatteryPredictionVisible(mLayoutPreference.findViewById(R.id.layout_left), 415 View.GONE); 416 assertBatteryPredictionVisible(mLayoutPreference.findViewById(R.id.layout_middle), 417 View.GONE); 418 assertBatteryPredictionVisible(mLayoutPreference.findViewById(R.id.layout_right), 419 View.GONE); 420 } 421 422 @Test showBatteryPredictionIfNecessary_estimateReadyIsAvailable_showCorrectValue()423 public void showBatteryPredictionIfNecessary_estimateReadyIsAvailable_showCorrectValue() { 424 final String leftBatteryPrediction = 425 StringUtil.formatElapsedTime(mContext, 12000000, false, false).toString(); 426 final String rightBatteryPrediction = 427 StringUtil.formatElapsedTime(mContext, 1200000, false, false).toString(); 428 429 mController.showBatteryPredictionIfNecessary(1, 12000000, 430 mLayoutPreference.findViewById(R.id.layout_left)); 431 mController.showBatteryPredictionIfNecessary(1, 1200000, 432 mLayoutPreference.findViewById(R.id.layout_right)); 433 434 assertBatteryPrediction(mLayoutPreference.findViewById(R.id.layout_left), 435 leftBatteryPrediction); 436 assertBatteryPrediction(mLayoutPreference.findViewById(R.id.layout_right), 437 rightBatteryPrediction); 438 } 439 assertBatteryPredictionVisible(LinearLayout linearLayout, int visible)440 private void assertBatteryPredictionVisible(LinearLayout linearLayout, int visible) { 441 final TextView textView = linearLayout.findViewById(R.id.bt_battery_prediction); 442 assertThat(textView.getVisibility()).isEqualTo(visible); 443 } 444 assertBatteryPrediction(LinearLayout linearLayout, String prediction)445 private void assertBatteryPrediction(LinearLayout linearLayout, String prediction) { 446 final TextView textView = linearLayout.findViewById(R.id.bt_battery_prediction); 447 assertThat(textView.getText().toString()).isEqualTo(prediction); 448 } 449 assertBatteryLevel(LinearLayout linearLayout, int batteryLevel)450 private void assertBatteryLevel(LinearLayout linearLayout, int batteryLevel) { 451 final TextView textView = linearLayout.findViewById(R.id.bt_battery_summary); 452 assertThat(textView.getText().toString()).isEqualTo( 453 com.android.settings.Utils.formatPercentage(batteryLevel)); 454 } 455 assertBatteryIcon(LinearLayout linearLayout, int resId)456 private void assertBatteryIcon(LinearLayout linearLayout, int resId) { 457 final ImageView imageView = linearLayout.findViewById(R.id.bt_battery_icon); 458 assertThat(shadowOf(imageView.getDrawable()).getCreatedFromResId()) 459 .isEqualTo(resId); 460 } 461 462 } 463