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