11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/proximity_auth/bluetooth_connection.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/message_loop/message_loop.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/numerics/safe_conversions.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/run_loop.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/proximity_auth/remote_device.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/proximity_auth/wire_message.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/bluetooth/bluetooth_adapter_factory.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/bluetooth/bluetooth_uuid.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/bluetooth/test/mock_bluetooth_adapter.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/bluetooth/test/mock_bluetooth_device.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/bluetooth/test/mock_bluetooth_socket.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/io_buffer.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gmock/include/gmock/gmock.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gtest/include/gtest/gtest.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::_;
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::AnyNumber;
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::NiceMock;
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::Ref;
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::Return;
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::SaveArg;
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing testing::StrictMock;
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace proximity_auth {
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kDeviceName[] = "Device name";
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kOtherDeviceName[] = "Other device name";
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kBluetoothAddress[] = "11:22:33:44:55:66";
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kOtherBluetoothAddress[] = "AA:BB:CC:DD:EE:FF";
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kSerializedMessage[] = "Yarrr, this be a serialized message. Yarr!";
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kSerializedMessageLength = strlen(kSerializedMessage);
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kUuid[] = "DEADBEEF-CAFE-FEED-FOOD-D15EA5EBEEF";
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst RemoteDevice kRemoteDevice = {kDeviceName, kBluetoothAddress};
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kReceiveBufferSize = 6;
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kReceiveBufferContents[] = "bytes";
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Create a buffer for testing received data.
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_refptr<net::IOBuffer> CreateReceiveBuffer() {
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kReceiveBufferSize);
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  memcpy(buffer->data(), kReceiveBufferContents, kReceiveBufferSize);
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return buffer;
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MockBluetoothConnection : public BluetoothConnection {
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MockBluetoothConnection()
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : BluetoothConnection(kRemoteDevice, device::BluetoothUUID(kUuid)) {}
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Bluetooth dependencies.
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef device::BluetoothDevice::ConnectToServiceCallback
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ConnectToServiceCallback;
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  typedef device::BluetoothDevice::ConnectToServiceErrorCallback
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ConnectToServiceErrorCallback;
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD4(ConnectToService,
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               void(device::BluetoothDevice* device,
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    const device::BluetoothUUID& uuid,
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    const ConnectToServiceCallback& callback,
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    const ConnectToServiceErrorCallback& error_callback));
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Calls back into the parent Connection class.
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD1(SetStatusProxy, void(Status status));
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD1(OnBytesReceived, void(const std::string& bytes));
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD2(OnDidSendMessage,
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               void(const WireMessage& message, bool success));
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void SetStatus(Status status) OVERRIDE {
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SetStatusProxy(status);
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    BluetoothConnection::SetStatus(status);
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using BluetoothConnection::status;
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using BluetoothConnection::Connect;
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using BluetoothConnection::DeviceRemoved;
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  using BluetoothConnection::Disconnect;
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(MockBluetoothConnection);
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TestWireMessage : public WireMessage {
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestWireMessage() : WireMessage("permit id", "payload") {}
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual ~TestWireMessage() {}
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string Serialize() const OVERRIDE { return kSerializedMessage; }
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(TestWireMessage);
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ProximityAuthBluetoothConnectionTest : public testing::Test {
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ProximityAuthBluetoothConnectionTest()
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : adapter_(new device::MockBluetoothAdapter),
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        device_(adapter_.get(), 0, kDeviceName, kBluetoothAddress, true, true),
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        socket_(new StrictMock<device::MockBluetoothSocket>),
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        uuid_(kUuid) {
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothAdapterFactory::SetAdapterForTesting(adapter_);
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Suppress uninteresting Gmock call warnings.
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*adapter_, GetDevice(_)).Times(AnyNumber());
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Transition the connection into an in-progress state.
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void BeginConnecting(MockBluetoothConnection* connection) {
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(Connection::DISCONNECTED, connection->status());
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS));
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*adapter_, AddObserver(connection));
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*connection, ConnectToService(&device_, uuid_, _, _));
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    connection->Connect();
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(Connection::IN_PROGRESS, connection->status());
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Transition the connection into a connected state.
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Saves the success and error callbacks passed into OnReceive(), which can be
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // accessed via receive_callback() and receive_success_callback().
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void Connect(MockBluetoothConnection* connection) {
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(Connection::DISCONNECTED, connection->status());
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device::BluetoothDevice::ConnectToServiceCallback callback;
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*connection, SetStatusProxy(Connection::IN_PROGRESS));
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*adapter_, AddObserver(connection));
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*connection, ConnectToService(_, _, _, _))
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .WillOnce(SaveArg<2>(&callback));
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    connection->Connect();
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_FALSE(callback.is_null());
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*connection, SetStatusProxy(Connection::CONNECTED));
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(*socket_, Receive(_, _, _))
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .WillOnce(DoAll(SaveArg<1>(&receive_callback_),
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        SaveArg<2>(&receive_error_callback_)));
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    callback.Run(socket_);
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(Connection::CONNECTED, connection->status());
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothSocket::ReceiveCompletionCallback* receive_callback() {
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return &receive_callback_;
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothSocket::ReceiveErrorCompletionCallback*
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  receive_error_callback() {
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return &receive_error_callback_;
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected:
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Mocks used for verifying interactions with the Bluetooth subsystem.
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<device::MockBluetoothAdapter> adapter_;
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NiceMock<device::MockBluetoothDevice> device_;
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<StrictMock<device::MockBluetoothSocket>> socket_;
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothUUID uuid_;
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::MessageLoop message_loop_;
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothSocket::ReceiveCompletionCallback receive_callback_;
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothSocket::ReceiveErrorCompletionCallback
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      receive_error_callback_;
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasInProgress) {
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create an in-progress connection.
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginConnecting(&connection);
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A second call to Connect() should be ignored.
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Connect();
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The connection cleans up after itself upon destruction.
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionWasConnected) {
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a connected connection.
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // A second call to Connect() should be ignored.
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Connect();
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The connection disconnects and unregisters as an observer upon destruction.
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest, Connect_NoBluetoothAdapter) {
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Some platforms do not support Bluetooth. This test is only meaningful on
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // those platforms.
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  adapter_ = NULL;
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable())
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Connect();
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest, Connect_DeviceMissing) {
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ON_CALL(*adapter_, GetDevice(_))
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      .WillByDefault(Return(static_cast<device::BluetoothDevice*>(NULL)));
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Connect();
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Connect_DeviceRemovedWhileConnecting) {
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create an in-progress connection.
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginConnecting(&connection);
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Remove the device while the connection is in-progress. This should cause
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the connection to disconnect.
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.DeviceRemoved(adapter_.get(), &device_);
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Connect_OtherDeviceRemovedWhileConnecting) {
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create an in-progress connection.
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginConnecting(&connection);
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Remove a device other than the one that is being connected to. This should
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // not have any effect on the connection.
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  NiceMock<device::MockBluetoothDevice> other_device(
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      adapter_.get(), 0, kOtherDeviceName, kOtherBluetoothAddress, true, true);
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.DeviceRemoved(adapter_.get(), &other_device);
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The connection removes itself as an observer when it is destroyed.
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionFails) {
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothDevice::ConnectToServiceErrorCallback error_callback;
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, AddObserver(&connection));
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _))
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      .WillOnce(SaveArg<3>(&error_callback));
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Connect();
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(error_callback.is_null());
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  error_callback.Run("super descriptive error message");
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest, Connect_ConnectionSucceeds) {
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The connection disconnects and unregisters as an observer upon destruction.
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Connect_ConnectionSucceeds_ThenDeviceRemoved) {
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.DeviceRemoved(adapter_.get(), &device_);
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Connect_ConnectionSucceeds_ReceiveData) {
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(receive_callback() && !receive_callback()->is_null());
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Receive some data. Once complete, the connection should re-register to be
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // ready receive more data.
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer();
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      connection,
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize)));
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Receive(_, _, _));
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  receive_callback()->Run(kReceiveBufferSize, buffer);
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::RunLoop run_loop;
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  run_loop.RunUntilIdle();
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The connection disconnects and unregisters as an observer upon destruction.
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Connect_ConnectionSucceeds_ReceiveDataAfterReceiveError) {
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(receive_error_callback() && !receive_error_callback()->is_null());
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Simulate an error while receiving data. The connection should re-register
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // to be ready receive more data despite the error.
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothSocket::ReceiveCompletionCallback receive_callback;
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Receive(_, _, _))
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      .WillOnce(SaveArg<1>(&receive_callback));
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  receive_error_callback()->Run(device::BluetoothSocket::kSystemError,
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                "The system is down. They're taking over!");
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::RunLoop run_loop;
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  run_loop.RunUntilIdle();
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(receive_callback.is_null());
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Receive some data.
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<net::IOBuffer> buffer = CreateReceiveBuffer();
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      connection,
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      OnBytesReceived(std::string(kReceiveBufferContents, kReceiveBufferSize)));
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Receive(_, _, _));
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  receive_callback.Run(kReceiveBufferSize, buffer);
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::RunLoop run_loop2;
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  run_loop2.RunUntilIdle();
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The connection disconnects and unregisters as an observer upon destruction.
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Disconnect_ConnectionWasAlreadyDisconnected) {
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Disconnect();
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Disconnect_ConnectionWasInProgress) {
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create an in-progress connection.
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginConnecting(&connection);
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Disconnect();
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Disconnect_ConnectionWasConnected) {
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a connected connection.
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Disconnect();
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       Connect_ThenDisconnectWhileInProgress_ThenBackingConnectionSucceeds) {
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothDevice::ConnectToServiceCallback callback;
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ON_CALL(*adapter_, GetDevice(_)).WillByDefault(Return(&device_));
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::IN_PROGRESS));
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, AddObserver(&connection));
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, ConnectToService(&device_, uuid_, _, _))
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      .WillOnce(SaveArg<2>(&callback));
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Connect();
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(callback.is_null());
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.Disconnect();
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(_)).Times(0);
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Receive(_, _, _)).Times(0);
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callback.Run(socket_);
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest,
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       SendMessage_SendsExpectedDataOverTheWire) {
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a connected connection.
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<net::IOBuffer> buffer;
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Send(_, kSerializedMessageLength, _, _))
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      .WillOnce(SaveArg<0>(&buffer));
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.SendMessage(wire_message.PassAs<WireMessage>());
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(buffer.get());
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(kSerializedMessage,
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            std::string(buffer->data(), kSerializedMessageLength));
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The connection disconnects and unregisters as an observer upon destruction.
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Success) {
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a connected connection.
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Ownership will be transfered below, so grab a reference here.
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestWireMessage* expected_wire_message = wire_message.get();
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothSocket::SendCompletionCallback callback;
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<2>(&callback));
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.SendMessage(wire_message.PassAs<WireMessage>());
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(callback.is_null());
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), true));
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callback.Run(kSerializedMessageLength);
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The connection disconnects and unregisters as an observer upon destruction.
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(ProximityAuthBluetoothConnectionTest, SendMessage_Failure) {
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Create a connected connection.
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StrictMock<MockBluetoothConnection> connection;
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Connect(&connection);
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<TestWireMessage> wire_message(new TestWireMessage);
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Ownership will be transfered below, so grab a reference here.
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestWireMessage* expected_wire_message = wire_message.get();
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device::BluetoothSocket::ErrorCompletionCallback error_callback;
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Send(_, _, _, _)).WillOnce(SaveArg<3>(&error_callback));
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection.SendMessage(wire_message.PassAs<WireMessage>());
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(error_callback.is_null());
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, OnDidSendMessage(Ref(*expected_wire_message), false));
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(connection, SetStatusProxy(Connection::DISCONNECTED));
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*socket_, Disconnect(_));
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(*adapter_, RemoveObserver(&connection));
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  error_callback.Run("The most helpful of error messages");
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace proximity_auth
463