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 "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 
     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>*
     52 BluetoothAPI::GetFactoryInstance() {
     53   return g_factory.Pointer();
     54 }
     55 
     56 // static
     57 BluetoothAPI* BluetoothAPI::Get(BrowserContext* context) {
     58   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     59   return GetFactoryInstance()->Get(context);
     60 }
     61 
     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 
     73 BluetoothAPI::~BluetoothAPI() {}
     74 
     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 
     83 void BluetoothAPI::Shutdown() {
     84   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     85   EventRouter::Get(browser_context_)->UnregisterObserver(this);
     86 }
     87 
     88 void BluetoothAPI::OnListenerAdded(const EventListenerInfo& details) {
     89   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     90   if (event_router()->IsBluetoothSupported())
     91     event_router()->OnListenerAdded();
     92 }
     93 
     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 
    102 BluetoothGetAdapterStateFunction::~BluetoothGetAdapterStateFunction() {}
    103 
    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 
    113 BluetoothGetDevicesFunction::~BluetoothGetDevicesFunction() {}
    114 
    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 
    140 BluetoothGetDeviceFunction::~BluetoothGetDeviceFunction() {}
    141 
    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 
    163 void BluetoothStartDiscoveryFunction::OnSuccessCallback() {
    164   SendResponse(true);
    165 }
    166 
    167 void BluetoothStartDiscoveryFunction::OnErrorCallback() {
    168   SetError(kStartDiscoveryFailed);
    169   SendResponse(false);
    170 }
    171 
    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 
    183 void BluetoothStopDiscoveryFunction::OnSuccessCallback() {
    184   SendResponse(true);
    185 }
    186 
    187 void BluetoothStopDiscoveryFunction::OnErrorCallback() {
    188   SetError(kStopDiscoveryFailed);
    189   SendResponse(false);
    190 }
    191 
    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