1 /* 2 * Copyright (C) 2017 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.ArgumentMatchers.any; 22 import static org.mockito.Mockito.inOrder; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.when; 25 26 import android.bluetooth.BluetoothDevice; 27 import android.graphics.drawable.Drawable; 28 29 import com.android.settings.R; 30 import com.android.settings.core.SettingsUIDeviceConfig; 31 import com.android.settings.testutils.FakeFeatureFactory; 32 import com.android.settings.testutils.shadow.ShadowDeviceConfig; 33 import com.android.settings.testutils.shadow.ShadowEntityHeaderController; 34 import com.android.settings.widget.EntityHeaderController; 35 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; 36 import com.android.settingslib.bluetooth.LocalBluetoothManager; 37 import com.android.settingslib.widget.LayoutPreference; 38 39 import org.junit.After; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 import org.mockito.Answers; 43 import org.mockito.InOrder; 44 import org.mockito.Mock; 45 import org.robolectric.RobolectricTestRunner; 46 import org.robolectric.annotation.Config; 47 48 @RunWith(RobolectricTestRunner.class) 49 @Config(shadows = {ShadowEntityHeaderController.class, ShadowDeviceConfig.class}) 50 public class BluetoothDetailsHeaderControllerTest extends BluetoothDetailsControllerTestBase { 51 52 private BluetoothDetailsHeaderController mController; 53 private LayoutPreference mPreference; 54 55 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 56 private EntityHeaderController mHeaderController; 57 @Mock 58 private LocalBluetoothManager mBluetoothManager; 59 @Mock 60 private CachedBluetoothDeviceManager mCachedDeviceManager; 61 @Mock 62 private BluetoothDevice mBluetoothDevice; 63 64 @Override setUp()65 public void setUp() { 66 super.setUp(); 67 FakeFeatureFactory.setupForTest(); 68 ShadowEntityHeaderController.setUseMock(mHeaderController); 69 when(mBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager); 70 when(mCachedDeviceManager.getSubDeviceSummary(mCachedDevice)).thenReturn("abc"); 71 mController = 72 new BluetoothDetailsHeaderController(mContext, mFragment, mCachedDevice, mLifecycle, 73 mBluetoothManager); 74 mPreference = new LayoutPreference(mContext, R.layout.settings_entity_header); 75 mPreference.setKey(mController.getPreferenceKey()); 76 mScreen.addPreference(mPreference); 77 setupDevice(mDeviceConfig); 78 when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice); 79 } 80 81 @After tearDown()82 public void tearDown() { 83 ShadowEntityHeaderController.reset(); 84 } 85 86 /** 87 * Test to verify the current test context object works so that we are not checking null 88 * against null 89 */ 90 @Test testContextMock()91 public void testContextMock() { 92 assertThat(mContext.getString(R.string.bluetooth_connected)).isNotNull(); 93 } 94 95 @Test header()96 public void header() { 97 showScreen(mController); 98 99 verify(mHeaderController).setLabel(mDeviceConfig.getName()); 100 verify(mHeaderController).setIcon(any(Drawable.class)); 101 verify(mHeaderController).setIconContentDescription(any(String.class)); 102 verify(mHeaderController).setSummary(any(String.class)); 103 verify(mHeaderController).setSecondSummary(any(String.class)); 104 verify(mHeaderController).done(mActivity, true); 105 } 106 107 @Test connectionStatusChangesWhileScreenOpen()108 public void connectionStatusChangesWhileScreenOpen() { 109 InOrder inOrder = inOrder(mHeaderController); 110 when(mCachedDevice.getConnectionSummary()) 111 .thenReturn(mContext.getString(R.string.bluetooth_connected)); 112 showScreen(mController); 113 inOrder.verify(mHeaderController) 114 .setSummary(mContext.getString(R.string.bluetooth_connected)); 115 116 when(mCachedDevice.getConnectionSummary()).thenReturn(null); 117 mController.onDeviceAttributesChanged(); 118 inOrder.verify(mHeaderController).setSummary((CharSequence) null); 119 120 when(mCachedDevice.getConnectionSummary()) 121 .thenReturn(mContext.getString(R.string.bluetooth_connecting)); 122 mController.onDeviceAttributesChanged(); 123 inOrder.verify(mHeaderController) 124 .setSummary(mContext.getString(R.string.bluetooth_connecting)); 125 } 126 127 @Test isAvailable_untetheredHeadsetWithConfigOn_returnFalse()128 public void isAvailable_untetheredHeadsetWithConfigOn_returnFalse() { 129 android.provider.DeviceConfig.setProperty( 130 android.provider.DeviceConfig.NAMESPACE_SETTINGS_UI, 131 SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true); 132 when(mBluetoothDevice.getMetadata( 133 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn("true".getBytes()); 134 135 assertThat(mController.isAvailable()).isFalse(); 136 } 137 138 @Test isAvailable_untetheredHeadsetWithConfigOff_returnTrue()139 public void isAvailable_untetheredHeadsetWithConfigOff_returnTrue() { 140 android.provider.DeviceConfig.setProperty( 141 android.provider.DeviceConfig.NAMESPACE_SETTINGS_UI, 142 SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "false", true); 143 when(mBluetoothDevice.getMetadata( 144 BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn("true".getBytes()); 145 146 assertThat(mController.isAvailable()).isTrue(); 147 } 148 } 149