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 android.bluetooth.BluetoothAdapter; 22 import android.bluetooth.BluetoothDevice; 23 import android.content.Context; 24 25 import com.android.settings.R; 26 import com.android.settings.SettingsRobolectricTestRunner; 27 import com.android.settings.TestConfig; 28 import com.android.settings.widget.SummaryUpdater.OnSummaryChangeListener; 29 import com.android.settingslib.bluetooth.CachedBluetoothDevice; 30 import com.android.settingslib.bluetooth.LocalBluetoothManager; 31 import com.android.settingslib.bluetooth.LocalBluetoothAdapter; 32 33 import org.junit.Before; 34 import org.junit.Test; 35 import org.junit.runner.RunWith; 36 import org.mockito.Answers; 37 import org.mockito.Mock; 38 import org.mockito.MockitoAnnotations; 39 import org.robolectric.RuntimeEnvironment; 40 import org.robolectric.annotation.Config; 41 42 import java.util.ArrayList; 43 import java.util.HashSet; 44 import java.util.List; 45 import java.util.Set; 46 47 import static org.mockito.Mockito.doReturn; 48 import static org.mockito.Mockito.mock; 49 import static org.mockito.Mockito.spy; 50 import static org.mockito.Mockito.verify; 51 import static org.mockito.Mockito.when; 52 53 @RunWith(SettingsRobolectricTestRunner.class) 54 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 55 public 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 private BluetoothSummaryUpdater mSummaryUpdater; 72 73 @Before setUp()74 public void setUp() { 75 MockitoAnnotations.initMocks(this); 76 when(mBluetoothManager.getBluetoothAdapter()).thenReturn(mBtAdapter); 77 when(mBtAdapter.isEnabled()).thenReturn(true); 78 when(mBtAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_CONNECTED); 79 mContext = RuntimeEnvironment.application.getApplicationContext(); 80 mSummaryUpdater = new BluetoothSummaryUpdater(mContext, mListener, mBluetoothManager); 81 } 82 83 @Test register_true_shouldRegisterListener()84 public void register_true_shouldRegisterListener() { 85 mSummaryUpdater.register(true); 86 87 verify(mBluetoothManager.getEventManager()).registerCallback(mSummaryUpdater); 88 } 89 90 @Test register_false_shouldUnregisterListener()91 public void register_false_shouldUnregisterListener() { 92 mSummaryUpdater.register(false); 93 94 verify(mBluetoothManager.getEventManager()).unregisterCallback(mSummaryUpdater); 95 } 96 97 @Test register_true_shouldSendSummaryChange()98 public void register_true_shouldSendSummaryChange() { 99 prepareConnectedDevice(false); 100 101 mSummaryUpdater.register(true); 102 103 verify(mListener).onSummaryChanged( 104 mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME)); 105 } 106 107 @Test onBluetoothStateChanged_btDisabled_shouldSendDisabledSummary()108 public void onBluetoothStateChanged_btDisabled_shouldSendDisabledSummary() { 109 mSummaryUpdater.register(true); 110 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_OFF); 111 112 verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disabled)); 113 } 114 115 @Test onBluetoothStateChanged_btEnabled_connected_shouldSendConnectedSummary()116 public void onBluetoothStateChanged_btEnabled_connected_shouldSendConnectedSummary() { 117 prepareConnectedDevice(false); 118 119 mSummaryUpdater.register(true); 120 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_ON); 121 122 verify(mListener).onSummaryChanged( 123 mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME)); 124 } 125 126 @Test onBluetoothStateChanged_btEnabled_notConnected_shouldSendDisconnectedMessage()127 public void onBluetoothStateChanged_btEnabled_notConnected_shouldSendDisconnectedMessage() { 128 when(mBtAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_DISCONNECTED); 129 mSummaryUpdater.register(true); 130 mSummaryUpdater.onBluetoothStateChanged(BluetoothAdapter.STATE_TURNING_ON); 131 132 verify(mListener).onSummaryChanged( 133 mContext.getString(R.string.disconnected)); 134 } 135 136 @Test onConnectionStateChanged_connected_shouldSendConnectedMessage()137 public void onConnectionStateChanged_connected_shouldSendConnectedMessage() { 138 final List<CachedBluetoothDevice> devices = new ArrayList<>(); 139 devices.add(mock(CachedBluetoothDevice.class)); 140 when(devices.get(0).isConnected()).thenReturn(true); 141 when(mBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()) 142 .thenReturn(devices); 143 when(mBtAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_DISCONNECTED); 144 prepareConnectedDevice(false); 145 146 mSummaryUpdater.register(true); 147 148 when(mBtAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_CONNECTED); 149 mSummaryUpdater.onConnectionStateChanged(null /* device */, 150 BluetoothAdapter.STATE_CONNECTED); 151 152 verify(mListener).onSummaryChanged( 153 mContext.getString(R.string.bluetooth_connected_summary, DEVICE_NAME)); 154 } 155 156 @Test onConnectionStateChanged_inconsistentState_shouldSendDisconnectedMessage()157 public void onConnectionStateChanged_inconsistentState_shouldSendDisconnectedMessage() { 158 mSummaryUpdater.register(true); 159 mSummaryUpdater.onConnectionStateChanged(null /* device */, 160 BluetoothAdapter.STATE_CONNECTED); 161 162 verify(mListener).onSummaryChanged( 163 mContext.getString(R.string.disconnected)); 164 } 165 166 @Test onConnectionStateChanged_connecting_shouldSendConnectingMessage()167 public void onConnectionStateChanged_connecting_shouldSendConnectingMessage() { 168 mSummaryUpdater.register(true); 169 when(mBtAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_CONNECTING); 170 mSummaryUpdater.onConnectionStateChanged(null /* device */, 171 BluetoothAdapter.STATE_CONNECTING); 172 173 verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_connecting)); 174 } 175 176 @Test onConnectionStateChanged_disconnecting_shouldSendDisconnectingMessage()177 public void onConnectionStateChanged_disconnecting_shouldSendDisconnectingMessage() { 178 mSummaryUpdater.register(true); 179 when(mBtAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_DISCONNECTING); 180 mSummaryUpdater.onConnectionStateChanged(null /* device */, 181 BluetoothAdapter.STATE_DISCONNECTING); 182 183 verify(mListener).onSummaryChanged(mContext.getString(R.string.bluetooth_disconnecting)); 184 } 185 186 @Test getConnectedDeviceSummary_hasConnectedDevice_returnOneDeviceSummary()187 public void getConnectedDeviceSummary_hasConnectedDevice_returnOneDeviceSummary() { 188 prepareConnectedDevice(false); 189 final String expectedSummary = mContext.getString(R.string.bluetooth_connected_summary, 190 DEVICE_NAME); 191 192 assertThat(mSummaryUpdater.getConnectedDeviceSummary()).isEqualTo(expectedSummary); 193 } 194 195 @Test getConnectedDeviceSummary_multipleDevices_returnMultipleDevicesSummary()196 public void getConnectedDeviceSummary_multipleDevices_returnMultipleDevicesSummary() { 197 prepareConnectedDevice(true); 198 final String expectedSummary = mContext.getString( 199 R.string.bluetooth_connected_multiple_devices_summary); 200 201 assertThat(mSummaryUpdater.getConnectedDeviceSummary()).isEqualTo(expectedSummary); 202 } 203 prepareConnectedDevice(boolean multipleDevices)204 private void prepareConnectedDevice(boolean multipleDevices) { 205 final Set<BluetoothDevice> devices = new HashSet<>(); 206 doReturn(DEVICE_NAME).when(mConnectedDevice).getName(); 207 doReturn(true).when(mConnectedDevice).isConnected(); 208 devices.add(mConnectedDevice); 209 if (multipleDevices) { 210 // Add one more device if we need to test multiple devices 211 doReturn(DEVICE_KEYBOARD_NAME).when(mConnectedKeyBoardDevice).getName(); 212 doReturn(true).when(mConnectedKeyBoardDevice).isConnected(); 213 devices.add(mConnectedKeyBoardDevice); 214 } 215 216 doReturn(devices).when(mBtAdapter).getBondedDevices(); 217 } 218 219 private class SummaryListener implements OnSummaryChangeListener { 220 String summary; 221 222 @Override onSummaryChanged(String summary)223 public void onSummaryChanged(String summary) { 224 this.summary = summary; 225 } 226 } 227 228 } 229