Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / extensions / api / bluetooth_low_energy / bluetooth_low_energy_api.cc
blobd5b6bbfcb65bf70898a9cf9c56334598de5e661f
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 "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_api.h"
7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_event_router.h"
11 #include "chrome/common/extensions/api/bluetooth_low_energy.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "extensions/browser/event_router.h"
15 using content::BrowserContext;
16 using content::BrowserThread;
18 namespace apibtle = extensions::api::bluetooth_low_energy;
20 namespace {
22 const char kErrorAdapterNotInitialized[] =
23 "Could not initialize Bluetooth adapter.";
24 const char kErrorCharacteristicNotFoundFormat[] =
25 "Characteristic with ID \"%s\" not found.";
26 const char kErrorDeviceNotFoundFormat[] =
27 "Device with address \"%s\" not found.";
28 const char kErrorServiceNotFoundFormat[] = "Service with ID \"%s\" not found.";
29 const char kErrorPlatformNotSupported[] =
30 "This operation is not supported on the current platform";
32 extensions::BluetoothLowEnergyEventRouter* GetEventRouter(
33 BrowserContext* context) {
34 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
35 return extensions::BluetoothLowEnergyAPI::Get(context)->event_router();
38 void DoWorkCallback(const base::Callback<bool()>& callback) {
39 DCHECK(!callback.is_null());
40 callback.Run();
43 // TODO(armansito): Remove this function once the described bug is fixed.
44 // (See crbug.com/368368).
46 // Converts an apibtle::Characteristic to a base::Value. This function is
47 // necessary, as json_schema_compiler::util::AddItemToList has no template
48 // specialization for user defined enums, which get treated as integers. This is
49 // because Characteristic contains a list of enum CharacteristicProperty.
50 scoped_ptr<base::DictionaryValue> CharacteristicToValue(
51 apibtle::Characteristic* from) {
52 // Copy the properties. Use Characteristic::ToValue to generate the result
53 // dictionary without the properties, to prevent json_schema_compiler from
54 // failing.
55 std::vector<apibtle::CharacteristicProperty> properties = from->properties;
56 from->properties.clear();
57 scoped_ptr<base::DictionaryValue> to = from->ToValue();
59 // Manually set each property.
60 scoped_ptr<base::ListValue> property_list(new base::ListValue());
61 for (std::vector<apibtle::CharacteristicProperty>::iterator iter =
62 properties.begin();
63 iter != properties.end();
64 ++iter)
65 property_list->Append(new base::StringValue(apibtle::ToString(*iter)));
67 to->Set("properties", property_list.release());
69 return to.Pass();
72 } // namespace
74 namespace extensions {
76 static base::LazyInstance<BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI> >
77 g_factory = LAZY_INSTANCE_INITIALIZER;
79 // static
80 BrowserContextKeyedAPIFactory<BluetoothLowEnergyAPI>*
81 BluetoothLowEnergyAPI::GetFactoryInstance() {
82 return g_factory.Pointer();
85 // static
86 BluetoothLowEnergyAPI* BluetoothLowEnergyAPI::Get(BrowserContext* context) {
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
88 return GetFactoryInstance()->Get(context);
91 BluetoothLowEnergyAPI::BluetoothLowEnergyAPI(BrowserContext* context)
92 : event_router_(new BluetoothLowEnergyEventRouter(context)),
93 browser_context_(context) {
94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
97 BluetoothLowEnergyAPI::~BluetoothLowEnergyAPI() {
100 void BluetoothLowEnergyAPI::Shutdown() {
101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
104 namespace api {
106 BluetoothLowEnergyExtensionFunction::BluetoothLowEnergyExtensionFunction() {
109 BluetoothLowEnergyExtensionFunction::~BluetoothLowEnergyExtensionFunction() {
112 bool BluetoothLowEnergyExtensionFunction::RunAsync() {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
115 BluetoothLowEnergyEventRouter* event_router =
116 GetEventRouter(browser_context());
117 if (!event_router->IsBluetoothSupported()) {
118 SetError(kErrorPlatformNotSupported);
119 return false;
122 // It is safe to pass |this| here as ExtensionFunction is refcounted.
123 if (!event_router->InitializeAdapterAndInvokeCallback(base::Bind(
124 &DoWorkCallback,
125 base::Bind(&BluetoothLowEnergyExtensionFunction::DoWork, this)))) {
126 SetError(kErrorAdapterNotInitialized);
127 return false;
130 return true;
133 bool BluetoothLowEnergyGetServiceFunction::DoWork() {
134 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
136 BluetoothLowEnergyEventRouter* event_router =
137 GetEventRouter(browser_context());
139 // The adapter must be initialized at this point, but return an error instead
140 // of asserting.
141 if (!event_router->HasAdapter()) {
142 SetError(kErrorAdapterNotInitialized);
143 SendResponse(false);
144 return false;
147 scoped_ptr<apibtle::GetService::Params> params(
148 apibtle::GetService::Params::Create(*args_));
149 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
151 std::string service_id = params->service_id;
153 apibtle::Service service;
154 if (!event_router->GetService(service_id, &service)) {
155 SetError(
156 base::StringPrintf(kErrorServiceNotFoundFormat, service_id.c_str()));
157 SendResponse(false);
158 return false;
161 results_ = apibtle::GetService::Results::Create(service);
162 SendResponse(true);
164 return true;
167 bool BluetoothLowEnergyGetServicesFunction::DoWork() {
168 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
170 BluetoothLowEnergyEventRouter* event_router =
171 GetEventRouter(browser_context());
173 // The adapter must be initialized at this point, but return an error instead
174 // of asserting.
175 if (!event_router->HasAdapter()) {
176 SetError(kErrorAdapterNotInitialized);
177 SendResponse(false);
178 return false;
181 scoped_ptr<apibtle::GetServices::Params> params(
182 apibtle::GetServices::Params::Create(*args_));
183 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
185 std::string device_address = params->device_address;
187 BluetoothLowEnergyEventRouter::ServiceList service_list;
188 if (!event_router->GetServices(device_address, &service_list)) {
189 SetError(
190 base::StringPrintf(kErrorDeviceNotFoundFormat, device_address.c_str()));
191 SendResponse(false);
192 return false;
195 results_ = apibtle::GetServices::Results::Create(service_list);
196 SendResponse(true);
198 return true;
201 bool BluetoothLowEnergyGetCharacteristicFunction::DoWork() {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
204 BluetoothLowEnergyEventRouter* event_router =
205 GetEventRouter(browser_context());
207 // The adapter must be initialized at this point, but return an error instead
208 // of asserting.
209 if (!event_router->HasAdapter()) {
210 SetError(kErrorAdapterNotInitialized);
211 SendResponse(false);
212 return false;
215 scoped_ptr<apibtle::GetCharacteristic::Params> params(
216 apibtle::GetCharacteristic::Params::Create(*args_));
217 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
219 std::string characteristic_id = params->characteristic_id;
221 apibtle::Characteristic characteristic;
222 if (!event_router->GetCharacteristic(characteristic_id, &characteristic)) {
223 SetError(base::StringPrintf(kErrorCharacteristicNotFoundFormat,
224 characteristic_id.c_str()));
225 SendResponse(false);
226 return false;
229 // Manually construct the result instead of using
230 // apibtle::GetCharacteristic::Result::Create as it doesn't convert lists of
231 // enums correctly.
232 SetResult(CharacteristicToValue(&characteristic).release());
233 SendResponse(true);
235 return true;
238 bool BluetoothLowEnergyGetCharacteristicsFunction::DoWork() {
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
241 BluetoothLowEnergyEventRouter* event_router =
242 GetEventRouter(browser_context());
244 // The adapter must be initialized at this point, but return an error instead
245 // of asserting.
246 if (!event_router->HasAdapter()) {
247 SetError(kErrorAdapterNotInitialized);
248 SendResponse(false);
249 return false;
252 scoped_ptr<apibtle::GetCharacteristics::Params> params(
253 apibtle::GetCharacteristics::Params::Create(*args_));
254 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
256 std::string service_id = params->service_id;
258 BluetoothLowEnergyEventRouter::CharacteristicList characteristic_list;
259 if (!event_router->GetCharacteristics(service_id, &characteristic_list)) {
260 SetError(
261 base::StringPrintf(kErrorServiceNotFoundFormat, service_id.c_str()));
263 SendResponse(false);
264 return false;
267 // Manually construct the result instead of using
268 // apibtle::GetCharacteristics::Result::Create as it doesn't convert lists of
269 // enums correctly.
270 scoped_ptr<base::ListValue> result(new base::ListValue());
271 for (BluetoothLowEnergyEventRouter::CharacteristicList::iterator iter =
272 characteristic_list.begin();
273 iter != characteristic_list.end();
274 ++iter)
275 result->Append(CharacteristicToValue(iter->get()).release());
277 SetResult(result.release());
278 SendResponse(true);
280 return true;
283 bool BluetoothLowEnergyGetIncludedServicesFunction::DoWork() {
284 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
286 BluetoothLowEnergyEventRouter* event_router =
287 GetEventRouter(browser_context());
289 // The adapter must be initialized at this point, but return an error instead
290 // of asserting.
291 if (!event_router->HasAdapter()) {
292 SetError(kErrorAdapterNotInitialized);
293 SendResponse(false);
294 return false;
297 scoped_ptr<apibtle::GetIncludedServices::Params> params(
298 apibtle::GetIncludedServices::Params::Create(*args_));
299 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
301 std::string service_id = params->service_id;
303 BluetoothLowEnergyEventRouter::ServiceList service_list;
304 if (!event_router->GetIncludedServices(service_id, &service_list)) {
305 SetError(
306 base::StringPrintf(kErrorServiceNotFoundFormat, service_id.c_str()));
307 SendResponse(false);
308 return false;
311 results_ = apibtle::GetIncludedServices::Results::Create(service_list);
312 SendResponse(true);
314 return true;
317 bool BluetoothLowEnergyGetDescriptorFunction::DoWork() {
318 // TODO(armansito): Implement.
319 SetError("Call not supported.");
320 SendResponse(false);
321 return false;
324 bool BluetoothLowEnergyGetDescriptorsFunction::DoWork() {
325 // TODO(armansito): Implement.
326 SetError("Call not supported.");
327 SendResponse(false);
328 return false;
331 bool BluetoothLowEnergyReadCharacteristicValueFunction::DoWork() {
332 // TODO(armansito): Implement.
333 SetError("Call not supported.");
334 SendResponse(false);
335 return false;
338 bool BluetoothLowEnergyWriteCharacteristicValueFunction::DoWork() {
339 // TODO(armansito): Implement.
340 SetError("Call not supported.");
341 SendResponse(false);
342 return false;
345 bool BluetoothLowEnergyReadDescriptorValueFunction::DoWork() {
346 // TODO(armansito): Implement.
347 SetError("Call not supported.");
348 SendResponse(false);
349 return false;
352 bool BluetoothLowEnergyWriteDescriptorValueFunction::DoWork() {
353 // TODO(armansito): Implement.
354 SetError("Call not supported.");
355 SendResponse(false);
356 return false;
359 } // namespace api
360 } // namespace extensions