• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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.
4 
5 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api.h"
6 
7 #include <string>
8 
9 #include "base/bind_helpers.h"
10 #include "base/lazy_instance.h"
11 #include "base/memory/ref_counted.h"
12 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h"
13 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h"
14 #include "chrome/browser/profiles/profile_manager.h"
15 #include "chrome/common/extensions/api/bluetooth.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "device/bluetooth/bluetooth_adapter.h"
18 #include "device/bluetooth/bluetooth_device.h"
19 #include "extensions/browser/event_router.h"
20 
21 using content::BrowserContext;
22 using content::BrowserThread;
23 
24 using device::BluetoothAdapter;
25 using device::BluetoothDevice;
26 
27 namespace bluetooth = extensions::api::bluetooth;
28 namespace GetDevice = extensions::api::bluetooth::GetDevice;
29 namespace GetDevices = extensions::api::bluetooth::GetDevices;
30 
31 namespace {
32 
33 const char kInvalidDevice[] = "Invalid device";
34 const char kStartDiscoveryFailed[] = "Starting discovery failed";
35 const char kStopDiscoveryFailed[] = "Failed to stop discovery";
36 
GetEventRouter(BrowserContext * context)37 extensions::BluetoothEventRouter* GetEventRouter(BrowserContext* context) {
38   // Note: |context| is valid on UI thread only.
39   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
40   return extensions::BluetoothAPI::Get(context)->event_router();
41 }
42 
43 }  // namespace
44 
45 namespace extensions {
46 
47 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothAPI> >
48     g_factory = LAZY_INSTANCE_INITIALIZER;
49 
50 // static
51 BrowserContextKeyedAPIFactory<BluetoothAPI>*
GetFactoryInstance()52 BluetoothAPI::GetFactoryInstance() {
53   return g_factory.Pointer();
54 }
55 
56 // static
Get(BrowserContext * context)57 BluetoothAPI* BluetoothAPI::Get(BrowserContext* context) {
58   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59   return GetFactoryInstance()->Get(context);
60 }
61 
BluetoothAPI(content::BrowserContext * context)62 BluetoothAPI::BluetoothAPI(content::BrowserContext* context)
63     : browser_context_(context) {
64   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
65   EventRouter* event_router = EventRouter::Get(browser_context_);
66   event_router->RegisterObserver(this,
67                                  bluetooth::OnAdapterStateChanged::kEventName);
68   event_router->RegisterObserver(this, bluetooth::OnDeviceAdded::kEventName);
69   event_router->RegisterObserver(this, bluetooth::OnDeviceChanged::kEventName);
70   event_router->RegisterObserver(this, bluetooth::OnDeviceRemoved::kEventName);
71 }
72 
~BluetoothAPI()73 BluetoothAPI::~BluetoothAPI() {}
74 
event_router()75 BluetoothEventRouter* BluetoothAPI::event_router() {
76   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
77   if (!event_router_) {
78     event_router_.reset(new BluetoothEventRouter(browser_context_));
79   }
80   return event_router_.get();
81 }
82 
Shutdown()83 void BluetoothAPI::Shutdown() {
84   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
85   EventRouter::Get(browser_context_)->UnregisterObserver(this);
86 }
87 
OnListenerAdded(const EventListenerInfo & details)88 void BluetoothAPI::OnListenerAdded(const EventListenerInfo& details) {
89   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
90   if (event_router()->IsBluetoothSupported())
91     event_router()->OnListenerAdded();
92 }
93 
OnListenerRemoved(const EventListenerInfo & details)94 void BluetoothAPI::OnListenerRemoved(const EventListenerInfo& details) {
95   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96   if (event_router()->IsBluetoothSupported())
97     event_router()->OnListenerRemoved();
98 }
99 
100 namespace api {
101 
~BluetoothGetAdapterStateFunction()102 BluetoothGetAdapterStateFunction::~BluetoothGetAdapterStateFunction() {}
103 
DoWork(scoped_refptr<BluetoothAdapter> adapter)104 bool BluetoothGetAdapterStateFunction::DoWork(
105     scoped_refptr<BluetoothAdapter> adapter) {
106   bluetooth::AdapterState state;
107   PopulateAdapterState(*adapter.get(), &state);
108   results_ = bluetooth::GetAdapterState::Results::Create(state);
109   SendResponse(true);
110   return true;
111 }
112 
~BluetoothGetDevicesFunction()113 BluetoothGetDevicesFunction::~BluetoothGetDevicesFunction() {}
114 
DoWork(scoped_refptr<BluetoothAdapter> adapter)115 bool BluetoothGetDevicesFunction::DoWork(
116     scoped_refptr<BluetoothAdapter> adapter) {
117   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
118 
119   base::ListValue* device_list = new base::ListValue;
120   SetResult(device_list);
121 
122   BluetoothAdapter::DeviceList devices = adapter->GetDevices();
123   for (BluetoothAdapter::DeviceList::const_iterator iter = devices.begin();
124        iter != devices.end();
125        ++iter) {
126     const BluetoothDevice* device = *iter;
127     DCHECK(device);
128 
129     bluetooth::Device extension_device;
130     bluetooth::BluetoothDeviceToApiDevice(*device, &extension_device);
131 
132     device_list->Append(extension_device.ToValue().release());
133   }
134 
135   SendResponse(true);
136 
137   return true;
138 }
139 
~BluetoothGetDeviceFunction()140 BluetoothGetDeviceFunction::~BluetoothGetDeviceFunction() {}
141 
DoWork(scoped_refptr<BluetoothAdapter> adapter)142 bool BluetoothGetDeviceFunction::DoWork(
143     scoped_refptr<BluetoothAdapter> adapter) {
144   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
145 
146   scoped_ptr<GetDevice::Params> params(GetDevice::Params::Create(*args_));
147   EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
148 
149   BluetoothDevice* device = adapter->GetDevice(params->device_address);
150   if (device) {
151     bluetooth::Device extension_device;
152     bluetooth::BluetoothDeviceToApiDevice(*device, &extension_device);
153     SetResult(extension_device.ToValue().release());
154     SendResponse(true);
155   } else {
156     SetError(kInvalidDevice);
157     SendResponse(false);
158   }
159 
160   return false;
161 }
162 
OnSuccessCallback()163 void BluetoothStartDiscoveryFunction::OnSuccessCallback() {
164   SendResponse(true);
165 }
166 
OnErrorCallback()167 void BluetoothStartDiscoveryFunction::OnErrorCallback() {
168   SetError(kStartDiscoveryFailed);
169   SendResponse(false);
170 }
171 
DoWork(scoped_refptr<BluetoothAdapter> adapter)172 bool BluetoothStartDiscoveryFunction::DoWork(
173     scoped_refptr<BluetoothAdapter> adapter) {
174   GetEventRouter(browser_context())->StartDiscoverySession(
175       adapter,
176       extension_id(),
177       base::Bind(&BluetoothStartDiscoveryFunction::OnSuccessCallback, this),
178       base::Bind(&BluetoothStartDiscoveryFunction::OnErrorCallback, this));
179 
180   return true;
181 }
182 
OnSuccessCallback()183 void BluetoothStopDiscoveryFunction::OnSuccessCallback() {
184   SendResponse(true);
185 }
186 
OnErrorCallback()187 void BluetoothStopDiscoveryFunction::OnErrorCallback() {
188   SetError(kStopDiscoveryFailed);
189   SendResponse(false);
190 }
191 
DoWork(scoped_refptr<BluetoothAdapter> adapter)192 bool BluetoothStopDiscoveryFunction::DoWork(
193     scoped_refptr<BluetoothAdapter> adapter) {
194   GetEventRouter(browser_context())->StopDiscoverySession(
195       adapter,
196       extension_id(),
197       base::Bind(&BluetoothStopDiscoveryFunction::OnSuccessCallback, this),
198       base::Bind(&BluetoothStopDiscoveryFunction::OnErrorCallback, this));
199 
200   return true;
201 }
202 
203 }  // namespace api
204 }  // namespace extensions
205