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 package com.android.settings.bluetooth; 17 18 import static com.google.common.truth.Truth.assertThat; 19 20 import static org.mockito.ArgumentMatchers.any; 21 import static org.mockito.Mockito.doReturn; 22 import static org.mockito.Mockito.never; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.when; 25 26 import android.bluetooth.BluetoothAdapter; 27 import android.bluetooth.BluetoothDevice; 28 import android.content.Context; 29 import android.content.Intent; 30 31 import androidx.preference.Preference; 32 33 import com.android.settings.SettingsActivity; 34 import com.android.settings.connecteddevice.DevicePreferenceCallback; 35 import com.android.settings.dashboard.DashboardFragment; 36 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; 37 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 38 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; 39 import com.android.settingslib.bluetooth.LocalBluetoothManager; 40 41 import org.junit.Before; 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 import org.mockito.ArgumentCaptor; 45 import org.mockito.Mock; 46 import org.mockito.MockitoAnnotations; 47 import org.robolectric.RobolectricTestRunner; 48 import org.robolectric.RuntimeEnvironment; 49 import org.robolectric.annotation.Config; 50 import org.robolectric.shadow.api.Shadow; 51 52 import java.util.ArrayList; 53 import java.util.List; 54 55 @RunWith(RobolectricTestRunner.class) 56 @Config(shadows = {ShadowBluetoothAdapter.class}) 57 public class BluetoothDeviceUpdaterTest { 58 59 private static final String MAC_ADDRESS = "04:52:C7:0B:D8:3C"; 60 private static final String SUB_MAC_ADDRESS = "05:52:C7:0B:D8:3C"; 61 62 @Mock 63 private DashboardFragment mDashboardFragment; 64 @Mock 65 private DevicePreferenceCallback mDevicePreferenceCallback; 66 @Mock 67 private CachedBluetoothDevice mCachedBluetoothDevice; 68 @Mock 69 private CachedBluetoothDevice mSubCachedBluetoothDevice; 70 @Mock 71 private BluetoothDevice mBluetoothDevice; 72 @Mock 73 private BluetoothDevice mSubBluetoothDevice; 74 @Mock 75 private SettingsActivity mSettingsActivity; 76 @Mock 77 private LocalBluetoothManager mLocalManager; 78 @Mock 79 private CachedBluetoothDeviceManager mCachedDeviceManager; 80 81 private Context mContext; 82 private BluetoothDeviceUpdater mBluetoothDeviceUpdater; 83 private BluetoothDevicePreference mPreference; 84 private ShadowBluetoothAdapter mShadowBluetoothAdapter; 85 private List<CachedBluetoothDevice> mCachedDevices = new ArrayList<>(); 86 87 @Before setUp()88 public void setUp() { 89 MockitoAnnotations.initMocks(this); 90 91 mContext = RuntimeEnvironment.application; 92 mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter()); 93 mCachedDevices.add(mCachedBluetoothDevice); 94 doReturn(mContext).when(mDashboardFragment).getContext(); 95 when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); 96 when(mSubCachedBluetoothDevice.getDevice()).thenReturn(mSubBluetoothDevice); 97 when(mLocalManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager); 98 when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices); 99 when(mCachedBluetoothDevice.getAddress()).thenReturn(MAC_ADDRESS); 100 when(mSubBluetoothDevice.getAddress()).thenReturn(SUB_MAC_ADDRESS); 101 102 mPreference = new BluetoothDevicePreference(mContext, mCachedBluetoothDevice, 103 false, BluetoothDevicePreference.SortType.TYPE_DEFAULT); 104 mBluetoothDeviceUpdater = 105 new BluetoothDeviceUpdater(mContext, mDashboardFragment, mDevicePreferenceCallback, 106 mLocalManager) { 107 @Override 108 public boolean isFilterMatched(CachedBluetoothDevice cachedBluetoothDevice) { 109 return true; 110 } 111 112 @Override 113 protected String getPreferenceKey() { 114 return "test_bt"; 115 } 116 }; 117 mBluetoothDeviceUpdater.setPrefContext(mContext); 118 } 119 120 @Test testAddPreference_deviceExist_doNothing()121 public void testAddPreference_deviceExist_doNothing() { 122 mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference); 123 124 mBluetoothDeviceUpdater.addPreference(mCachedBluetoothDevice); 125 126 verify(mDevicePreferenceCallback, never()).onDeviceAdded(any(Preference.class)); 127 } 128 129 @Test testAddPreference_deviceNotExist_addPreference()130 public void testAddPreference_deviceNotExist_addPreference() { 131 mBluetoothDeviceUpdater.addPreference(mCachedBluetoothDevice); 132 133 final Preference preference = mBluetoothDeviceUpdater.mPreferenceMap.get(mBluetoothDevice); 134 assertThat(preference).isNotNull(); 135 verify(mDevicePreferenceCallback).onDeviceAdded(preference); 136 } 137 138 @Test testRemovePreference_deviceExist_removePreference()139 public void testRemovePreference_deviceExist_removePreference() { 140 mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference); 141 142 mBluetoothDeviceUpdater.removePreference(mCachedBluetoothDevice); 143 144 verify(mDevicePreferenceCallback).onDeviceRemoved(mPreference); 145 assertThat(mBluetoothDeviceUpdater.mPreferenceMap.containsKey(mBluetoothDevice)).isFalse(); 146 } 147 148 @Test testOnDeviceDeleted_deviceExists_removePreference()149 public void testOnDeviceDeleted_deviceExists_removePreference() { 150 mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference); 151 152 mBluetoothDeviceUpdater.onDeviceDeleted(mCachedBluetoothDevice); 153 154 verify(mDevicePreferenceCallback).onDeviceRemoved(mPreference); 155 assertThat(mBluetoothDeviceUpdater.mPreferenceMap.containsKey(mBluetoothDevice)).isFalse(); 156 } 157 158 @Test testRemovePreference_deviceNotExist_doNothing()159 public void testRemovePreference_deviceNotExist_doNothing() { 160 mBluetoothDeviceUpdater.removePreference(mCachedBluetoothDevice); 161 162 verify(mDevicePreferenceCallback, never()).onDeviceRemoved(any(Preference.class)); 163 } 164 165 @Test testRemovePreference_subDeviceExist_removePreference()166 public void testRemovePreference_subDeviceExist_removePreference() { 167 when(mCachedBluetoothDevice.getSubDevice()).thenReturn(mSubCachedBluetoothDevice); 168 mBluetoothDeviceUpdater.mPreferenceMap.put(mSubBluetoothDevice, mPreference); 169 170 assertThat(mBluetoothDeviceUpdater.mPreferenceMap. 171 containsKey(mSubBluetoothDevice)).isTrue(); 172 mBluetoothDeviceUpdater.removePreference(mCachedBluetoothDevice); 173 174 verify(mDevicePreferenceCallback).onDeviceRemoved(mPreference); 175 assertThat(mBluetoothDeviceUpdater.mPreferenceMap. 176 containsKey(mSubBluetoothDevice)).isFalse(); 177 } 178 179 @Test testDeviceProfilesListener_click_startBluetoothDeviceDetailPage()180 public void testDeviceProfilesListener_click_startBluetoothDeviceDetailPage() { 181 doReturn(mSettingsActivity).when(mDashboardFragment).getContext(); 182 183 final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 184 mBluetoothDeviceUpdater.mDeviceProfilesListener.onGearClick(mPreference); 185 186 verify(mSettingsActivity).startActivity(intentCaptor.capture()); 187 assertThat(intentCaptor.getValue().getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)) 188 .isEqualTo(BluetoothDeviceDetailsFragment.class.getName()); 189 } 190 191 @Test isDeviceConnected_deviceConnected()192 public void isDeviceConnected_deviceConnected() { 193 doReturn(BluetoothDevice.BOND_BONDED).when(mBluetoothDevice).getBondState(); 194 doReturn(true).when(mBluetoothDevice).isConnected(); 195 196 assertThat(mBluetoothDeviceUpdater.isDeviceConnected(mCachedBluetoothDevice)).isTrue(); 197 } 198 199 @Test isDeviceConnected_deviceNotConnected()200 public void isDeviceConnected_deviceNotConnected() { 201 doReturn(BluetoothDevice.BOND_BONDED).when(mBluetoothDevice).getBondState(); 202 doReturn(false).when(mBluetoothDevice).isConnected(); 203 204 assertThat(mBluetoothDeviceUpdater.isDeviceConnected(mCachedBluetoothDevice)).isFalse(); 205 } 206 207 @Test registerCallback_localBluetoothManagerNull_shouldNotCrash()208 public void registerCallback_localBluetoothManagerNull_shouldNotCrash() { 209 mBluetoothDeviceUpdater.mLocalManager = null; 210 211 // Shouldn't crash 212 mBluetoothDeviceUpdater.registerCallback(); 213 } 214 215 @Test unregisterCallback_localBluetoothManagerNull_shouldNotCrash()216 public void unregisterCallback_localBluetoothManagerNull_shouldNotCrash() { 217 mBluetoothDeviceUpdater.mLocalManager = null; 218 219 // Shouldn't crash 220 mBluetoothDeviceUpdater.unregisterCallback(); 221 } 222 223 @Test forceUpdate_bluetoothDisabled_removeAllDevicesFromPreference()224 public void forceUpdate_bluetoothDisabled_removeAllDevicesFromPreference() { 225 mShadowBluetoothAdapter.setEnabled(false); 226 mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference); 227 228 mBluetoothDeviceUpdater.forceUpdate(); 229 230 verify(mDevicePreferenceCallback).onDeviceRemoved(mPreference); 231 assertThat(mBluetoothDeviceUpdater.mPreferenceMap).isEmpty(); 232 } 233 234 @Test forceUpdate_bluetoothEnabled_addPreference()235 public void forceUpdate_bluetoothEnabled_addPreference() { 236 mShadowBluetoothAdapter.setEnabled(true); 237 mBluetoothDeviceUpdater.forceUpdate(); 238 239 verify(mDevicePreferenceCallback).onDeviceAdded(any(Preference.class)); 240 } 241 242 @Test onBluetoothStateChanged_bluetoothStateIsOn_forceUpdate()243 public void onBluetoothStateChanged_bluetoothStateIsOn_forceUpdate() { 244 mShadowBluetoothAdapter.setEnabled(true); 245 mBluetoothDeviceUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON); 246 247 verify(mDevicePreferenceCallback).onDeviceAdded(any(Preference.class)); 248 } 249 250 @Test onBluetoothStateChanged_bluetoothStateIsOff_removeAllDevicesFromPreference()251 public void onBluetoothStateChanged_bluetoothStateIsOff_removeAllDevicesFromPreference() { 252 mBluetoothDeviceUpdater.mPreferenceMap.put(mBluetoothDevice, mPreference); 253 254 mBluetoothDeviceUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF); 255 256 verify(mDevicePreferenceCallback).onDeviceRemoved(mPreference); 257 assertThat(mBluetoothDeviceUpdater.mPreferenceMap.containsKey(mBluetoothDevice)).isFalse(); 258 } 259 } 260