Moving src/webrtc into src/.

In order to eliminate the WebRTC Subtree mirror in Chromium, 
WebRTC is moving the content of the src/webrtc directory up
to the src/ directory.

NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
TBR=tommi@webrtc.org

Bug: chromium:611808
Change-Id: Iac59c5b51b950f174119565bac87955a7994bc38
Reviewed-on: https://webrtc-review.googlesource.com/1560
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Henrik Kjellander <kjellander@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#19845}
This commit is contained in:
Mirko Bonadei
2017-09-15 06:15:48 +02:00
committed by Commit Bot
parent 6674846b4a
commit bb547203bf
4576 changed files with 1092 additions and 1196 deletions

View File

@ -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);
}
}

View File

@ -0,0 +1,155 @@
/*
* 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.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.isNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
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.ShadowLog;
import org.webrtc.IceCandidate;
import org.webrtc.SessionDescription;
/**
* Test for DirectRTCClient. Test is very simple and only tests the overall sanity of the class
* behaviour.
*/
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class DirectRTCClientTest {
private static final String ROOM_URL = "";
private static final boolean LOOPBACK = false;
private static final String DUMMY_SDP_MID = "sdpMid";
private static final String DUMMY_SDP = "sdp";
public static final int SERVER_WAIT = 100;
public static final int NETWORK_TIMEOUT = 1000;
private DirectRTCClient client;
private DirectRTCClient server;
AppRTCClient.SignalingEvents clientEvents;
AppRTCClient.SignalingEvents serverEvents;
@Before
public void setUp() {
ShadowLog.stream = System.out;
clientEvents = mock(AppRTCClient.SignalingEvents.class);
serverEvents = mock(AppRTCClient.SignalingEvents.class);
client = new DirectRTCClient(clientEvents);
server = new DirectRTCClient(serverEvents);
}
@Test
public void testValidIpPattern() {
// Strings that should match the pattern.
// clang-format off
final String[] ipAddresses = new String[] {
"0.0.0.0",
"127.0.0.1",
"192.168.0.1",
"0.0.0.0:8888",
"127.0.0.1:8888",
"192.168.0.1:8888",
"::",
"::1",
"2001:0db8:85a3:0000:0000:8a2e:0370:7946",
"[::]",
"[::1]",
"[2001:0db8:85a3:0000:0000:8a2e:0370:7946]",
"[::]:8888",
"[::1]:8888",
"[2001:0db8:85a3:0000:0000:8a2e:0370:7946]:8888"
};
// clang-format on
for (String ip : ipAddresses) {
assertTrue(ip + " didn't match IP_PATTERN even though it should.",
DirectRTCClient.IP_PATTERN.matcher(ip).matches());
}
}
@Test
public void testInvalidIpPattern() {
// Strings that shouldn't match the pattern.
// clang-format off
final String[] invalidIpAddresses = new String[] {
"Hello, World!",
"aaaa",
"1111",
"[hello world]",
"hello:world"
};
// clang-format on
for (String invalidIp : invalidIpAddresses) {
assertFalse(invalidIp + " matched IP_PATTERN even though it shouldn't.",
DirectRTCClient.IP_PATTERN.matcher(invalidIp).matches());
}
}
// TODO(sakal): Replace isNotNull(class) with isNotNull() once Java 8 is used.
@SuppressWarnings("deprecation")
@Test
public void testDirectRTCClient() {
server.connectToRoom(new AppRTCClient.RoomConnectionParameters(ROOM_URL, "0.0.0.0", LOOPBACK));
try {
Thread.sleep(SERVER_WAIT);
} catch (InterruptedException e) {
fail(e.getMessage());
}
client.connectToRoom(
new AppRTCClient.RoomConnectionParameters(ROOM_URL, "127.0.0.1", LOOPBACK));
verify(serverEvents, timeout(NETWORK_TIMEOUT))
.onConnectedToRoom(any(AppRTCClient.SignalingParameters.class));
SessionDescription offerSdp = new SessionDescription(SessionDescription.Type.OFFER, DUMMY_SDP);
server.sendOfferSdp(offerSdp);
verify(clientEvents, timeout(NETWORK_TIMEOUT))
.onConnectedToRoom(any(AppRTCClient.SignalingParameters.class));
SessionDescription answerSdp =
new SessionDescription(SessionDescription.Type.ANSWER, DUMMY_SDP);
client.sendAnswerSdp(answerSdp);
verify(serverEvents, timeout(NETWORK_TIMEOUT))
.onRemoteDescription(isNotNull(SessionDescription.class));
IceCandidate candidate = new IceCandidate(DUMMY_SDP_MID, 0, DUMMY_SDP);
server.sendLocalIceCandidate(candidate);
verify(clientEvents, timeout(NETWORK_TIMEOUT))
.onRemoteIceCandidate(isNotNull(IceCandidate.class));
client.sendLocalIceCandidate(candidate);
verify(serverEvents, timeout(NETWORK_TIMEOUT))
.onRemoteIceCandidate(isNotNull(IceCandidate.class));
client.disconnectFromRoom();
verify(clientEvents, timeout(NETWORK_TIMEOUT)).onChannelClose();
verify(serverEvents, timeout(NETWORK_TIMEOUT)).onChannelClose();
verifyNoMoreInteractions(clientEvents);
verifyNoMoreInteractions(serverEvents);
}
}

View File

@ -0,0 +1,203 @@
/*
* 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.fail;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.testing.local.LocalRobolectricTestRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLog;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class TCPChannelClientTest {
private static final int PORT = 8888;
/**
* How long we wait before trying to connect to the server. Chosen quite arbitrarily and
* could be made smaller if need be.
*/
private static final int SERVER_WAIT = 10;
private static final int CONNECT_TIMEOUT = 100;
private static final int SEND_TIMEOUT = 100;
private static final int DISCONNECT_TIMEOUT = 100;
private static final int TERMINATION_TIMEOUT = 1000;
private static final String TEST_MESSAGE_SERVER = "Hello, Server!";
private static final String TEST_MESSAGE_CLIENT = "Hello, Client!";
@Mock TCPChannelClient.TCPChannelEvents serverEvents;
@Mock TCPChannelClient.TCPChannelEvents clientEvents;
private ExecutorService executor;
private TCPChannelClient server;
private TCPChannelClient client;
@Before
public void setUp() {
ShadowLog.stream = System.out;
MockitoAnnotations.initMocks(this);
executor = Executors.newSingleThreadExecutor();
}
@After
public void tearDown() {
verifyNoMoreEvents();
executeAndWait(new Runnable() {
@Override
public void run() {
client.disconnect();
server.disconnect();
}
});
// Stop the executor thread
executor.shutdown();
try {
executor.awaitTermination(TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
}
}
@Test
public void testConnectIPv4() {
setUpIPv4Server();
try {
Thread.sleep(SERVER_WAIT);
} catch (InterruptedException e) {
fail(e.getMessage());
}
setUpIPv4Client();
verify(serverEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(true);
verify(clientEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(false);
}
// @Test
// Disabled because it fails when IPv6 is not supported on the bot.
// TODO(ehmaldonado): Enable when bugs.webrtc.org/6437 is fixed.
@DisabledTest
public void testConnectIPv6() {
setUpIPv6Server();
try {
Thread.sleep(SERVER_WAIT);
} catch (InterruptedException e) {
fail(e.getMessage());
}
setUpIPv6Client();
verify(serverEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(true);
verify(clientEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(false);
}
@Test
public void testSendData() {
testConnectIPv4();
executeAndWait(new Runnable() {
@Override
public void run() {
client.send(TEST_MESSAGE_SERVER);
server.send(TEST_MESSAGE_CLIENT);
}
});
verify(serverEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_SERVER);
verify(clientEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_CLIENT);
}
@Test
public void testDisconnectServer() {
testConnectIPv4();
executeAndWait(new Runnable() {
@Override
public void run() {
server.disconnect();
}
});
verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
}
@Test
public void testDisconnectClient() {
testConnectIPv4();
executeAndWait(new Runnable() {
@Override
public void run() {
client.disconnect();
}
});
verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose();
}
private void setUpIPv4Server() {
setUpServer("0.0.0.0", PORT);
}
private void setUpIPv4Client() {
setUpClient("127.0.0.1", PORT);
}
private void setUpIPv6Server() {
setUpServer("::", PORT);
}
private void setUpIPv6Client() {
setUpClient("::1", PORT);
}
private void setUpServer(String ip, int port) {
server = new TCPChannelClient(executor, serverEvents, ip, port);
}
private void setUpClient(String ip, int port) {
client = new TCPChannelClient(executor, clientEvents, ip, port);
}
/**
* Verifies no more server or client events have been issued
*/
private void verifyNoMoreEvents() {
verifyNoMoreInteractions(serverEvents);
verifyNoMoreInteractions(clientEvents);
}
/**
* Queues runnable to be run and waits for it to be executed by the executor thread
*/
public void executeAndWait(Runnable runnable) {
try {
executor.submit(runnable).get();
} catch (Exception e) {
fail(e.getMessage());
}
}
}