BluetoothSummaryUpdaterTest.java revision ac040e3b1fc3488155e5bb337908c491627900bc
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 17package com.android.settings.bluetooth; 18 19import static com.google.common.truth.Truth.assertThat; 20 21import static org.mockito.Matchers.anyString; 22import static org.mockito.Mockito.doAnswer; 23import static org.mockito.Mockito.doCallRealMethod; 24import static org.mockito.Mockito.doReturn; 25import static org.mockito.Mockito.times; 26import static org.mockito.Mockito.verify; 27import static org.mockito.Mockito.when; 28 29import android.bluetooth.BluetoothAdapter; 30import android.bluetooth.BluetoothDevice; 31import android.content.Context; 32import android.util.Log; 33 34import com.android.settings.R; 35import com.android.settings.TestConfig; 36import com.android.settings.testutils.SettingsRobolectricTestRunner; 37import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener; 38import com.android.settingslib.bluetooth.LocalBluetoothAdapter; 39import com.android.settingslib.bluetooth.LocalBluetoothManager; 40 41import org.junit.Before; 42import org.junit.Test; 43import org.junit.runner.RunWith; 44import org.mockito.Answers; 45import org.mockito.Mock; 46import org.mockito.MockitoAnnotations; 47import org.robolectric.RuntimeEnvironment; 48import org.robolectric.annotation.Config; 49 50import java.util.HashSet; 51import java.util.Set; 52 53@RunWith(SettingsRobolectricTestRunner.class) 54@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 55public class BluetoothSummaryUpdaterTest { 56 private static final String DEVICE_NAME = "Nightshade"; 57 private static final String DEVICE_KEYBOARD_NAME = "Bluetooth Keyboard"; 58 59 private Context mContext; 60 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 61 private LocalBluetoothManager mBluetoothManager; 62 @Mock 63 private LocalBluetoothAdapter mBtAdapter; 64 @Mock 65 private BluetoothDevice mConnectedDevice; 66 @Mock 67 private BluetoothDevice mConnectedKeyBoardDevice; 68 @Mock 69 private SummaryListener mListener; 70 71 // Disabled by default 72 private final boolean[] mAdapterEnabled = {false}; 73 // Not connected by default 74 private final int[] mAdapterConnectionState = {BluetoothAdapter.STATE_DISCONNECTED}; 75 // Not connected by default 76 private final boolean[] mDeviceConnected = {false, false}; 77 private final Set<BluetoothDevice> mBondedDevices = new HashSet<>(); 78 private BluetoothSummaryUpdater mSummaryUpdater; 79 80 @Before 81 public void setUp() { 82 MockitoAnnotations.initMocks(this); 83 mContext = RuntimeEnvironment.application.getApplicationContext(); 84 doCallRealMethod().when(mListener).onSummaryChanged(anyString()); 85 // Setup mock adapter 86 when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBtAdapter); 87 doAnswer(invocation -> mAdapterEnabled[0]).when(mBtAdapter).isEnabled(); 88 doAnswer(invocation -> mAdapterConnectionState[0]).when(mBtAdapter).getConnectionState(); 89 mSummaryUpdater = new BluetoothSummaryUpdater(mContext, mListener, mBluetoothManager); 90 // Setup first device 91 doReturn(DEVICE_NAME).when(mConnectedDevice).getName(); 92 doAnswer(invocation -> mDeviceConnected[0]).when(mConnectedDevice).isConnected(); 93 // Setup second device 94 doReturn(DEVICE_KEYBOARD_NAME).when(mConnectedKeyBoardDevice).getName(); 95 doAnswer(invocation -> mDeviceConnected[1]).when(mConnectedKeyBoardDevice) 96 .isConnected(); 97 doReturn(mBondedDevices).when(mBtAdapter).getBondedDevices(); 98 } 99 100 @Test 101 public void register_true_shouldRegisterListener() { 102 mSummaryUpdater.register(true); 103 104 verify(mBluetoothManager.getEventManager()).registerCallback(mSummaryUpdater); 105 } 106 107 @Test 108 public void register_false_shouldUnregisterListener() { 109 mSummaryUpdater.register(false); 110 111 verify(mBluetoothManager.getEventManager()).unregisterCallback(mSummaryUpdater); 112 } 113 114 @Test 115 public void register_true_shouldSendSummaryChange() { 116 mAdapterEnabled[0] = true; 117 mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; 118 mBondedDevices.add(mConnectedDevice); 119 mDeviceConnected[0] = true; 120 121 mSummaryUpdater.register(true); 122 123 verify(mListener).onSummaryChanged( 124 mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME)); 125 } 126 127 @Test 128 public void onBluetoothStateChanged_btDisabled_shouldSendDisabledSummary() { 129 // These states should be ignored 130 mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; 131 mBondedDevices.add(mConnectedDevice); 132 mDeviceConnected[0] = true; 133 134 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF); 135 136 verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled)); 137 } 138 139 @Test 140 public void onBluetoothStateChanged_btEnabled_connected_shouldSendConnectedSummary() { 141 mAdapterEnabled[0] = true; 142 mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; 143 mBondedDevices.add(mConnectedDevice); 144 mDeviceConnected[0] = true; 145 146 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON); 147 148 verify(mListener).onSummaryChanged( 149 mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME)); 150 } 151 152 @Test 153 public void onBluetoothStateChanged_btEnabled_connectedMisMatch_shouldSendNotConnected() { 154 mAdapterEnabled[0] = true; 155 mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; 156 mBondedDevices.add(mConnectedDevice); 157 // State mismatch 158 mDeviceConnected[0] = false; 159 160 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON); 161 162 verify(mListener).onSummaryChanged(mContext.getString(R.string.disconnected)); 163 } 164 165 @Test 166 public void onBluetoothStateChanged_btEnabled_notConnected_shouldSendDisconnectedMessage() { 167 mAdapterEnabled[0] = true; 168 mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED; 169 mBondedDevices.add(mConnectedDevice); 170 // This should be ignored 171 mDeviceConnected[0] = true; 172 173 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_TURNING_ON); 174 175 verify(mListener).onSummaryChanged(mContext.getString(R.string.disconnected)); 176 } 177 178 @Test 179 public void onBluetoothStateChanged_ConnectedDisabledEnabled_shouldSendDisconnectedSummary() { 180 mAdapterEnabled[0] = true; 181 mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED; 182 mBondedDevices.add(mConnectedDevice); 183 mDeviceConnected[0] = false; 184 185 mSummaryUpdater.register(true); 186 verify(mListener).onSummaryChanged(mContext.getString(R.string.disconnected)); 187 188 mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; 189 mDeviceConnected[0] = true; 190 mSummaryUpdater.onConnectionStateChanged(null /* device */, 191 BluetoothAdapter.STATE_CONNECTED); 192 verify(mListener).onSummaryChanged( 193 mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME)); 194 195 mAdapterEnabled[0] = false; 196 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF); 197 verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled)); 198 199 // Turning ON means not enabled 200 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_TURNING_ON); 201 // There should still be only one invocation of disabled message 202 verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled)); 203 204 mAdapterEnabled[0] = true; 205 mDeviceConnected[0] = false; 206 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON); 207 verify(mListener, times(2)).onSummaryChanged(mContext.getString(R.string.disconnected)); 208 verify(mListener, times(4)).onSummaryChanged(anyString()); 209 } 210 211 @Test 212 public void onConnectionStateChanged_connected_shouldSendConnectedMessage() { 213 mAdapterEnabled[0] = true; 214 mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; 215 mBondedDevices.add(mConnectedDevice); 216 mDeviceConnected[0] = true; 217 218 mSummaryUpdater.onConnectionStateChanged(null /* device */, 219 BluetoothAdapter.STATE_CONNECTED); 220 221 verify(mListener).onSummaryChanged( 222 mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME)); 223 } 224 225 @Test 226 public void onConnectionStateChanged_inconsistentState_shouldSendDisconnectedMessage() { 227 mAdapterEnabled[0] = true; 228 mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTED; 229 mBondedDevices.add(mConnectedDevice); 230 mDeviceConnected[0] = false; 231 232 mSummaryUpdater.onConnectionStateChanged(null /* device */, 233 BluetoothAdapter.STATE_CONNECTED); 234 235 verify(mListener).onSummaryChanged(mContext.getString(R.string.disconnected)); 236 } 237 238 @Test 239 public void onConnectionStateChanged_noBondedDevice_shouldSendDisconnectedMessage() { 240 mAdapterEnabled[0] = true; 241 mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTED; 242 243 mSummaryUpdater.onConnectionStateChanged(null /* device */, 244 BluetoothAdapter.STATE_CONNECTED); 245 246 verify(mListener).onSummaryChanged( 247 mContext.getString(R.string.disconnected)); 248 } 249 250 @Test 251 public void onConnectionStateChanged_connecting_shouldSendConnectingMessage() { 252 // No need for bonded devices 253 mAdapterEnabled[0] = true; 254 mAdapterConnectionState[0] = BluetoothAdapter.STATE_CONNECTING; 255 256 mSummaryUpdater.onConnectionStateChanged(null /* device */, 257 BluetoothAdapter.STATE_CONNECTING); 258 259 verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_connecting)); 260 } 261 262 @Test 263 public void onConnectionStateChanged_disconnecting_shouldSendDisconnectingMessage() { 264 // No need for bonded devices 265 mAdapterEnabled[0] = true; 266 mAdapterConnectionState[0] = BluetoothAdapter.STATE_DISCONNECTING; 267 268 mSummaryUpdater.onConnectionStateChanged(null /* device */, 269 BluetoothAdapter.STATE_DISCONNECTING); 270 271 verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disconnecting)); 272 } 273 274 @Test 275 public void getConnectedDeviceSummary_hasConnectedDevice_returnOneDeviceSummary() { 276 mBondedDevices.add(mConnectedDevice); 277 mDeviceConnected[0] = true; 278 final String expectedSummary = mContext.getString(R.string.bluetooth_connected_summary, 279 DEVICE_NAME); 280 281 assertThat(mSummaryUpdater.getConnectedDeviceSummary()).isEqualTo(expectedSummary); 282 } 283 284 @Test 285 public void getConnectedDeviceSummary_multipleDevices_returnMultipleDevicesSummary() { 286 mBondedDevices.add(mConnectedDevice); 287 mBondedDevices.add(mConnectedKeyBoardDevice); 288 mDeviceConnected[0] = true; 289 mDeviceConnected[1] = true; 290 final String expectedSummary = mContext.getString( 291 R.string.bluetooth_connected_multiple_devices_summary); 292 293 assertThat(mSummaryUpdater.getConnectedDeviceSummary()).isEqualTo(expectedSummary); 294 } 295 296 private class SummaryListener implements OnSummaryChangeListener { 297 String summary; 298 299 @Override 300 public void onSummaryChanged(String summary) { 301 this.summary = summary; 302 } 303 } 304 305} 306