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