Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / extensions / browser / api / bluetooth_socket / bluetooth_api_socket.cc
blobfff135ce510d6fc498dde5e48150e3754297f859
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 "extensions/browser/api/bluetooth_socket/bluetooth_api_socket.h"
7 #include "base/lazy_instance.h"
8 #include "device/bluetooth/bluetooth_socket.h"
9 #include "net/base/io_buffer.h"
11 namespace {
13 const char kSocketNotConnectedError[] = "Socket not connected";
14 const char kSocketNotListeningError[] = "Socket not listening";
16 } // namespace
18 namespace extensions {
20 // static
21 static base::LazyInstance<
22 BrowserContextKeyedAPIFactory<ApiResourceManager<BluetoothApiSocket> > >
23 g_server_factory = LAZY_INSTANCE_INITIALIZER;
25 // static
26 template <>
27 BrowserContextKeyedAPIFactory<ApiResourceManager<BluetoothApiSocket> >*
28 ApiResourceManager<BluetoothApiSocket>::GetFactoryInstance() {
29 return g_server_factory.Pointer();
32 BluetoothApiSocket::BluetoothApiSocket(const std::string& owner_extension_id)
33 : ApiResource(owner_extension_id),
34 persistent_(false),
35 buffer_size_(0),
36 paused_(false),
37 connected_(false) {
38 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
41 BluetoothApiSocket::BluetoothApiSocket(
42 const std::string& owner_extension_id,
43 scoped_refptr<device::BluetoothSocket> socket,
44 const std::string& device_address,
45 const device::BluetoothUUID& uuid)
46 : ApiResource(owner_extension_id),
47 socket_(socket),
48 device_address_(device_address),
49 uuid_(uuid),
50 persistent_(false),
51 buffer_size_(0),
52 paused_(true),
53 connected_(true) {
54 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
57 BluetoothApiSocket::~BluetoothApiSocket() {
58 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
59 if (socket_.get())
60 socket_->Close();
63 void BluetoothApiSocket::AdoptConnectedSocket(
64 scoped_refptr<device::BluetoothSocket> socket,
65 const std::string& device_address,
66 const device::BluetoothUUID& uuid) {
67 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
69 if (socket_.get())
70 socket_->Close();
72 socket_ = socket;
73 device_address_ = device_address;
74 uuid_ = uuid;
75 connected_ = true;
78 void BluetoothApiSocket::AdoptListeningSocket(
79 scoped_refptr<device::BluetoothSocket> socket,
80 const device::BluetoothUUID& uuid) {
81 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
83 if (socket_.get())
84 socket_->Close();
86 socket_ = socket;
87 device_address_ = "";
88 uuid_ = uuid;
89 connected_ = false;
92 void BluetoothApiSocket::Disconnect(const base::Closure& callback) {
93 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
95 if (!socket_.get()) {
96 callback.Run();
97 return;
100 connected_ = false;
101 socket_->Disconnect(callback);
104 bool BluetoothApiSocket::IsPersistent() const {
105 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
106 return persistent_;
109 void BluetoothApiSocket::Receive(
110 int count,
111 const ReceiveCompletionCallback& success_callback,
112 const ErrorCompletionCallback& error_callback) {
113 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
115 if (!socket_.get() || !IsConnected()) {
116 error_callback.Run(BluetoothApiSocket::kNotConnected,
117 kSocketNotConnectedError);
118 return;
121 socket_->Receive(count,
122 success_callback,
123 base::Bind(&OnSocketReceiveError, error_callback));
126 // static
127 void BluetoothApiSocket::OnSocketReceiveError(
128 const ErrorCompletionCallback& error_callback,
129 device::BluetoothSocket::ErrorReason reason,
130 const std::string& message) {
131 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
132 BluetoothApiSocket::ErrorReason error_reason;
133 switch (reason) {
134 case device::BluetoothSocket::kIOPending:
135 error_reason = BluetoothApiSocket::kIOPending;
136 break;
137 case device::BluetoothSocket::kDisconnected:
138 error_reason = BluetoothApiSocket::kDisconnected;
139 break;
140 case device::BluetoothSocket::kSystemError:
141 error_reason = BluetoothApiSocket::kSystemError;
142 break;
144 error_callback.Run(error_reason, message);
147 void BluetoothApiSocket::Send(scoped_refptr<net::IOBuffer> buffer,
148 int buffer_size,
149 const SendCompletionCallback& success_callback,
150 const ErrorCompletionCallback& error_callback) {
151 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
153 if (!socket_.get() || !IsConnected()) {
154 error_callback.Run(BluetoothApiSocket::kNotConnected,
155 kSocketNotConnectedError);
156 return;
159 socket_->Send(buffer,
160 buffer_size,
161 success_callback,
162 base::Bind(&OnSocketSendError, error_callback));
165 // static
166 void BluetoothApiSocket::OnSocketSendError(
167 const ErrorCompletionCallback& error_callback,
168 const std::string& message) {
169 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
170 error_callback.Run(BluetoothApiSocket::kSystemError, message);
173 void BluetoothApiSocket::Accept(
174 const AcceptCompletionCallback& success_callback,
175 const ErrorCompletionCallback& error_callback) {
176 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
178 if (!socket_.get() || IsConnected()) {
179 error_callback.Run(BluetoothApiSocket::kNotListening,
180 kSocketNotListeningError);
181 return;
184 socket_->Accept(success_callback,
185 base::Bind(&OnSocketAcceptError, error_callback));
188 // static
189 void BluetoothApiSocket::OnSocketAcceptError(
190 const ErrorCompletionCallback& error_callback,
191 const std::string& message) {
192 DCHECK(content::BrowserThread::CurrentlyOn(kThreadId));
193 error_callback.Run(BluetoothApiSocket::kSystemError, message);
196 } // namespace extensions