cc: Make picture pile base thread safe.
[chromium-blink-merge.git] / components / copresence_sockets / copresence_peer.cc
blobbacebcb19546ff049709a8c21f23c0dc4fa218a4
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/copresence_sockets/public/copresence_peer.h"
7 #include <stdint.h>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/format_macros.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/rand_util.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/stringprintf.h"
16 #include "components/copresence_sockets/transports/bluetooth/copresence_socket_bluetooth.h"
17 #include "device/bluetooth/bluetooth_adapter.h"
18 #include "device/bluetooth/bluetooth_adapter_factory.h"
19 #include "device/bluetooth/bluetooth_device.h"
20 #include "device/bluetooth/bluetooth_socket.h"
21 #include "device/bluetooth/bluetooth_uuid.h"
23 namespace {
25 const char kAdapterError[] = "NOADAPTER";
27 device::BluetoothUUID GenerateRandomUuid() {
28 // Random hex string of the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
29 return device::BluetoothUUID(base::StringPrintf(
30 "%08" PRIx64 "-%04" PRIx64 "-%04" PRIx64 "-%04" PRIx64 "-%012" PRIx64,
31 base::RandGenerator(UINT32_MAX),
32 base::RandGenerator(UINT16_MAX),
33 base::RandGenerator(UINT16_MAX),
34 base::RandGenerator(UINT16_MAX),
35 base::RandGenerator(static_cast<uint64>(UINT16_MAX) + UINT32_MAX)));
38 // This class will confirm pairing for a device that is expecting a pairing
39 // confirmation.
40 class DefaultApprovalDelegate
41 : public device::BluetoothDevice::PairingDelegate {
42 public:
43 DefaultApprovalDelegate() {}
44 ~DefaultApprovalDelegate() override {}
46 // device::BluetoothDevice::PairingDelegate overrides:
47 void RequestPinCode(device::BluetoothDevice* device) override {}
48 void RequestPasskey(device::BluetoothDevice* device) override {}
49 void DisplayPinCode(device::BluetoothDevice* device,
50 const std::string& pincode) override {}
51 void DisplayPasskey(device::BluetoothDevice* device,
52 uint32 passkey) override {}
53 void KeysEntered(device::BluetoothDevice* device, uint32 entered) override {}
54 void ConfirmPasskey(device::BluetoothDevice* device,
55 uint32 passkey) override {}
56 void AuthorizePairing(device::BluetoothDevice* device) override {
57 if (device->ExpectingConfirmation())
58 device->ConfirmPairing();
62 } // namespace
64 namespace copresence_sockets {
66 CopresencePeer::CopresencePeer(const CreatePeerCallback& create_callback,
67 const AcceptCallback& accept_callback)
68 : create_callback_(create_callback),
69 accept_callback_(accept_callback),
70 delegate_(nullptr),
71 weak_ptr_factory_(this) {
72 DCHECK(!create_callback.is_null());
73 DCHECK(!accept_callback.is_null());
75 if (!device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
76 create_callback_.Run(std::string());
77 return;
80 device::BluetoothAdapterFactory::GetAdapter(base::Bind(
81 &CopresencePeer::OnGetAdapter, weak_ptr_factory_.GetWeakPtr()));
84 std::string CopresencePeer::GetLocatorData() {
85 if (!adapter_.get())
86 return kAdapterError;
87 // TODO(rkc): Fix the "1." once we have finalized the locator format with
88 // other platforms. http://crbug.com/418616
89 return "1." + adapter_->GetAddress() + "." + service_uuid_.value();
92 CopresencePeer::~CopresencePeer() {
93 server_socket_->Disconnect(base::Bind(&base::DoNothing));
94 server_socket_->Close();
95 if (delegate_)
96 adapter_->RemovePairingDelegate(delegate_.get());
99 // Private methods.
101 void CopresencePeer::OnGetAdapter(
102 scoped_refptr<device::BluetoothAdapter> adapter) {
103 if (!adapter.get() || !adapter->IsPresent() || !adapter->IsPowered()) {
104 create_callback_.Run(std::string());
105 return;
108 adapter_ = adapter;
109 service_uuid_ = GenerateRandomUuid();
111 delegate_ = make_scoped_ptr(new DefaultApprovalDelegate());
112 VLOG(2) << "Creating service with UUID: " << service_uuid_.value();
113 adapter_->AddPairingDelegate(
114 delegate_.get(),
115 device::BluetoothAdapter::PAIRING_DELEGATE_PRIORITY_HIGH);
116 adapter_->CreateRfcommService(
117 service_uuid_,
118 device::BluetoothAdapter::ServiceOptions(),
119 base::Bind(&CopresencePeer::OnCreateService,
120 weak_ptr_factory_.GetWeakPtr()),
121 base::Bind(&CopresencePeer::OnCreateServiceError,
122 weak_ptr_factory_.GetWeakPtr()));
125 void CopresencePeer::OnCreateService(
126 scoped_refptr<device::BluetoothSocket> socket) {
127 if (!socket.get()) {
128 create_callback_.Run(std::string());
129 return;
132 server_socket_ = socket;
133 create_callback_.Run(GetLocatorData());
134 server_socket_->Accept(
135 base::Bind(&CopresencePeer::OnAccept, weak_ptr_factory_.GetWeakPtr()),
136 base::Bind(&CopresencePeer::OnAcceptError,
137 weak_ptr_factory_.GetWeakPtr()));
140 void CopresencePeer::OnCreateServiceError(const std::string& message) {
141 LOG(WARNING) << "Couldn't create Bluetooth service: " << message;
142 create_callback_.Run(std::string());
145 void CopresencePeer::OnAccept(const device::BluetoothDevice* device,
146 scoped_refptr<device::BluetoothSocket> socket) {
147 if (!socket.get())
148 return;
149 accept_callback_.Run(make_scoped_ptr(new CopresenceSocketBluetooth(socket)));
152 void CopresencePeer::OnAcceptError(const std::string& message) {
153 LOG(WARNING) << "Couldn't accept Bluetooth connection: " << message;
156 } // namespace copresence_sockets