Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Unified Diff: webrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java

Issue 2501983002: Adds basic Bluetooth support to AppRTCMobile (Closed)
Patch Set: Final comments from magjed@ Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java
diff --git a/webrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java b/webrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d077f37e7067dcf102a4b677ab8ec516816217e
--- /dev/null
+++ b/webrtc/examples/androidjunit/src/org/appspot/apprtc/BluetoothManagerTest.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+package org.appspot.apprtc;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.util.Log;
+import java.util.LinkedList;
+import java.util.List;
+import org.appspot.apprtc.AppRTCBluetoothManager.State;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowLog;
+
+/**
+ * Verifies basic behavior of the AppRTCBluetoothManager class.
+ * Note that the test object uses an AppRTCAudioManager (injected in ctor),
+ * but a mocked version is used instead. Hence, the parts "driven" by the AppRTC
+ * audio manager are not included in this test.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class BluetoothManagerTest {
+ private static final String TAG = "BluetoothManagerTest";
+ private static final String BLUETOOTH_TEST_DEVICE_NAME = "BluetoothTestDevice";
+
+ private BroadcastReceiver bluetoothHeadsetStateReceiver;
+ private BluetoothProfile.ServiceListener bluetoothServiceListener;
+ private BluetoothHeadset mockedBluetoothHeadset;
+ private BluetoothDevice mockedBluetoothDevice;
+ private List<BluetoothDevice> mockedBluetoothDeviceList;
+ private AppRTCBluetoothManager bluetoothManager;
+ private AppRTCAudioManager mockedAppRtcAudioManager;
+ private AudioManager mockedAudioManager;
+ private Context context;
+
+ @Before
+ public void setUp() {
+ ShadowLog.stream = System.out;
+ context = ShadowApplication.getInstance().getApplicationContext();
+ mockedAppRtcAudioManager = mock(AppRTCAudioManager.class);
+ mockedAudioManager = mock(AudioManager.class);
+ mockedBluetoothHeadset = mock(BluetoothHeadset.class);
+ mockedBluetoothDevice = mock(BluetoothDevice.class);
+ mockedBluetoothDeviceList = new LinkedList<BluetoothDevice>();
+
+ // Simulate that bluetooth SCO audio is available by default.
+ when(mockedAudioManager.isBluetoothScoAvailableOffCall()).thenReturn(true);
+
+ // Create the test object and override protected methods for this test.
+ bluetoothManager = new AppRTCBluetoothManager(context, mockedAppRtcAudioManager) {
+ @Override
+ protected AudioManager getAudioManager(Context context) {
+ Log.d(TAG, "getAudioManager");
+ return mockedAudioManager;
+ }
+
+ @Override
+ protected void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ Log.d(TAG, "registerReceiver");
+ if (filter.hasAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
+ && filter.hasAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
+ // Gives access to the real broadcast receiver so the test can use it.
+ bluetoothHeadsetStateReceiver = receiver;
+ }
+ }
+
+ @Override
+ protected void unregisterReceiver(BroadcastReceiver receiver) {
+ Log.d(TAG, "unregisterReceiver");
+ if (receiver == bluetoothHeadsetStateReceiver) {
+ bluetoothHeadsetStateReceiver = null;
+ }
+ }
+
+ @Override
+ protected boolean getBluetoothProfileProxy(
+ Context context, BluetoothProfile.ServiceListener listener, int profile) {
+ Log.d(TAG, "getBluetoothProfileProxy");
+ if (profile == BluetoothProfile.HEADSET) {
+ // Allows the test to access the real Bluetooth service listener object.
+ bluetoothServiceListener = listener;
+ }
+ return true;
+ }
+
+ @Override
+ protected boolean hasPermission(Context context, String permission) {
+ Log.d(TAG, "hasPermission(" + permission + ")");
+ // Ensure that the client asks for Bluetooth permission.
+ return (permission == android.Manifest.permission.BLUETOOTH);
+ }
+
+ @Override
+ protected void logBluetoothAdapterInfo(BluetoothAdapter localAdapter) {
+ // Do nothing in tests. No need to mock BluetoothAdapter.
+ }
+ };
+ }
+
+ // Verify that Bluetooth service listener for headset profile is properly initialized.
+ @Test
+ public void testBluetoothServiceListenerInitialized() {
+ bluetoothManager.start();
+ assertNotNull(bluetoothServiceListener);
+ verify(mockedAppRtcAudioManager, never()).updateAudioDeviceState();
+ }
+
+ // Verify that broadcast receivers for Bluetooth SCO audio state and Bluetooth headset state
+ // are properly registered and unregistered.
+ @Test
+ public void testBluetoothBroadcastReceiversAreRegistered() {
+ bluetoothManager.start();
+ assertNotNull(bluetoothHeadsetStateReceiver);
+ bluetoothManager.stop();
+ assertNull(bluetoothHeadsetStateReceiver);
+ }
+
+ // Verify that the Bluetooth manager starts and stops with correct states.
+ @Test
+ public void testBluetoothDefaultStartStopStates() {
+ bluetoothManager.start();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
+ bluetoothManager.stop();
+ assertEquals(bluetoothManager.getState(), State.UNINITIALIZED);
+ }
+
+ // Verify correct state after receiving BluetoothServiceListener.onServiceConnected()
+ // when no BT device is enabled.
+ @Test
+ public void testBluetoothServiceListenerConnectedWithNoHeadset() {
+ bluetoothManager.start();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
+ simulateBluetoothServiceConnectedWithNoConnectedHeadset();
+ verify(mockedAppRtcAudioManager, times(1)).updateAudioDeviceState();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
+ }
+
+ // Verify correct state after receiving BluetoothServiceListener.onServiceConnected()
+ // when one emulated (test) BT device is enabled. Android does not support more than
+ // one connected BT headset.
+ @Test
+ public void testBluetoothServiceListenerConnectedWithHeadset() {
+ bluetoothManager.start();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
+ simulateBluetoothServiceConnectedWithConnectedHeadset();
+ verify(mockedAppRtcAudioManager, times(1)).updateAudioDeviceState();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_AVAILABLE);
+ }
+
+ // Verify correct state after receiving BluetoothProfile.ServiceListener.onServiceDisconnected().
+ @Test
+ public void testBluetoothServiceListenerDisconnected() {
+ bluetoothManager.start();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
+ simulateBluetoothServiceDisconnected();
+ verify(mockedAppRtcAudioManager, times(1)).updateAudioDeviceState();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
+ }
+
+ // Verify correct state after BluetoothServiceListener.onServiceConnected() and
+ // the intent indicating that the headset is actually connected. Both these callbacks
+ // results in calls to updateAudioDeviceState() on the AppRTC audio manager.
+ // No BT SCO is enabled here to keep the test limited.
+ @Test
+ public void testBluetoothHeadsetConnected() {
+ bluetoothManager.start();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
+ simulateBluetoothServiceConnectedWithConnectedHeadset();
+ simulateBluetoothHeadsetConnected();
+ verify(mockedAppRtcAudioManager, times(2)).updateAudioDeviceState();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_AVAILABLE);
+ }
+
+ // Verify correct state sequence for a case when a BT headset is available,
+ // followed by BT SCO audio being enabled and then stopped.
+ @Test
+ public void testBluetoothScoAudioStartAndStop() {
+ bluetoothManager.start();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_UNAVAILABLE);
+ simulateBluetoothServiceConnectedWithConnectedHeadset();
+ assertEquals(bluetoothManager.getState(), State.HEADSET_AVAILABLE);
+ bluetoothManager.startScoAudio();
+ assertEquals(bluetoothManager.getState(), State.SCO_CONNECTING);
+ simulateBluetoothScoConnectionConnected();
+ assertEquals(bluetoothManager.getState(), State.SCO_CONNECTED);
+ bluetoothManager.stopScoAudio();
+ simulateBluetoothScoConnectionDisconnected();
+ assertEquals(bluetoothManager.getState(), State.SCO_DISCONNECTING);
+ bluetoothManager.stop();
+ assertEquals(bluetoothManager.getState(), State.UNINITIALIZED);
+ verify(mockedAppRtcAudioManager, times(3)).updateAudioDeviceState();
+ }
+
+ /**
+ * Private helper methods.
+ */
+ private void simulateBluetoothServiceConnectedWithNoConnectedHeadset() {
+ mockedBluetoothDeviceList.clear();
+ when(mockedBluetoothHeadset.getConnectedDevices()).thenReturn(mockedBluetoothDeviceList);
+ bluetoothServiceListener.onServiceConnected(BluetoothProfile.HEADSET, mockedBluetoothHeadset);
+ // In real life, the AppRTC audio manager makes this call.
+ bluetoothManager.updateDevice();
+ }
+
+ private void simulateBluetoothServiceConnectedWithConnectedHeadset() {
+ mockedBluetoothDeviceList.clear();
+ mockedBluetoothDeviceList.add(mockedBluetoothDevice);
+ when(mockedBluetoothHeadset.getConnectedDevices()).thenReturn(mockedBluetoothDeviceList);
+ when(mockedBluetoothDevice.getName()).thenReturn(BLUETOOTH_TEST_DEVICE_NAME);
+ bluetoothServiceListener.onServiceConnected(BluetoothProfile.HEADSET, mockedBluetoothHeadset);
+ // In real life, the AppRTC audio manager makes this call.
+ bluetoothManager.updateDevice();
+ }
+
+ private void simulateBluetoothServiceDisconnected() {
+ bluetoothServiceListener.onServiceDisconnected(BluetoothProfile.HEADSET);
+ }
+
+ private void simulateBluetoothHeadsetConnected() {
+ Intent intent = new Intent();
+ intent.setAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+ intent.putExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_CONNECTED);
+ bluetoothHeadsetStateReceiver.onReceive(context, intent);
+ }
+
+ private void simulateBluetoothScoConnectionConnected() {
+ Intent intent = new Intent();
+ intent.setAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+ intent.putExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_CONNECTED);
+ bluetoothHeadsetStateReceiver.onReceive(context, intent);
+ }
+
+ private void simulateBluetoothScoConnectionDisconnected() {
+ Intent intent = new Intent();
+ intent.setAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+ intent.putExtra(BluetoothHeadset.EXTRA_STATE, BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
+ bluetoothHeadsetStateReceiver.onReceive(context, intent);
+ }
+}
« no previous file with comments | « webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698