| Index: chrome/browser/extensions/bluetooth_event_router.cc | 
| diff --git a/chrome/browser/extensions/bluetooth_event_router.cc b/chrome/browser/extensions/bluetooth_event_router.cc | 
| index d38db9e8b925a6438b7a199889ee2f576b1ea5dc..44e6f8742757a3c75190bd60b50e2e707e57eaf9 100644 | 
| --- a/chrome/browser/extensions/bluetooth_event_router.cc | 
| +++ b/chrome/browser/extensions/bluetooth_event_router.cc | 
| @@ -5,6 +5,7 @@ | 
| #include "chrome/browser/extensions/bluetooth_event_router.h" | 
|  | 
| #include <map> | 
| +#include <string> | 
|  | 
| #include "base/json/json_writer.h" | 
| #include "base/memory/ref_counted.h" | 
| @@ -26,20 +27,45 @@ ExtensionBluetoothEventRouter::ExtensionBluetoothEventRouter(Profile* profile) | 
| : send_discovery_events_(false), | 
| responsible_for_discovery_(false), | 
| profile_(profile), | 
| -      adapter_(device::BluetoothAdapterFactory::DefaultAdapter()), | 
| +      adapter_(NULL), | 
| +      num_event_listeners_(0), | 
| next_socket_id_(1) { | 
| DCHECK(profile_); | 
| -  if (adapter_.get()) | 
| -    adapter_->AddObserver(this); | 
| } | 
|  | 
| ExtensionBluetoothEventRouter::~ExtensionBluetoothEventRouter() { | 
| -  if (adapter_.get()) | 
| -    adapter_->RemoveObserver(this); | 
| +  MaybeReleaseAdapter(); | 
|  | 
| socket_map_.clear(); | 
| } | 
|  | 
| +scoped_refptr<const device::BluetoothAdapter> | 
| +ExtensionBluetoothEventRouter::adapter() { | 
| +  return GetMutableAdapter(); | 
| +} | 
| + | 
| +scoped_refptr<device::BluetoothAdapter> | 
| +ExtensionBluetoothEventRouter::GetMutableAdapter() { | 
| +  if (adapter_) | 
| +    return adapter_; | 
| + | 
| +  return device::BluetoothAdapterFactory::DefaultAdapter(); | 
| +} | 
| + | 
| +void ExtensionBluetoothEventRouter::InitializeAdapterIfNeeded() { | 
| +  if (!adapter_) { | 
| +    adapter_ = GetMutableAdapter(); | 
| +    adapter_->AddObserver(this); | 
| +  } | 
| +} | 
| + | 
| +void ExtensionBluetoothEventRouter::MaybeReleaseAdapter() { | 
| +  if (adapter_) { | 
| +    adapter_->RemoveObserver(this); | 
| +    adapter_ = NULL; | 
| +  } | 
| +} | 
| + | 
| int ExtensionBluetoothEventRouter::RegisterSocket( | 
| scoped_refptr<device::BluetoothSocket> socket) { | 
| // If there is a socket registered with the same fd, just return it's id | 
| @@ -51,6 +77,8 @@ int ExtensionBluetoothEventRouter::RegisterSocket( | 
| } | 
| int return_id = next_socket_id_++; | 
| socket_map_[return_id] = socket; | 
| +  InitializeAdapterIfNeeded(); | 
| + | 
| return return_id; | 
| } | 
|  | 
| @@ -59,6 +87,9 @@ bool ExtensionBluetoothEventRouter::ReleaseSocket(int id) { | 
| if (socket_entry == socket_map_.end()) | 
| return false; | 
| socket_map_.erase(socket_entry); | 
| +  if (!IsAdapterNeeded()) | 
| +    MaybeReleaseAdapter(); | 
| + | 
| return true; | 
| } | 
|  | 
| @@ -70,6 +101,37 @@ ExtensionBluetoothEventRouter::GetSocket(int id) { | 
| return socket_entry->second; | 
| } | 
|  | 
| +// static | 
| +bool ExtensionBluetoothEventRouter::IsBluetoothEvent( | 
| +    const std::string& event_name) { | 
| +  return | 
| +      event_name == extensions::event_names::kBluetoothOnAvailabilityChanged || | 
| +      event_name == extensions::event_names::kBluetoothOnDiscoveringChanged || | 
| +      event_name == extensions::event_names::kBluetoothOnPowerChanged; | 
| +} | 
| + | 
| +bool ExtensionBluetoothEventRouter::IsAdapterNeeded() const { | 
| +  return num_event_listeners_ > 0 || socket_map_.size() > 0; | 
| +} | 
| + | 
| +void ExtensionBluetoothEventRouter::OnEventListenerAdded( | 
| +    const std::string& event_name) { | 
| +  if (IsBluetoothEvent(event_name)) { | 
| +    num_event_listeners_++; | 
| +    InitializeAdapterIfNeeded(); | 
| +  } | 
| +} | 
| + | 
| +void ExtensionBluetoothEventRouter::OnEventListenerRemoved( | 
| +    const std::string& event_name) { | 
| +  if (IsBluetoothEvent(event_name)) { | 
| +    num_event_listeners_--; | 
| +    DCHECK(num_event_listeners_ >= 0); | 
| +    if (!IsAdapterNeeded()) | 
| +      MaybeReleaseAdapter(); | 
| +  } | 
| +} | 
| + | 
| void ExtensionBluetoothEventRouter::SetResponsibleForDiscovery( | 
| bool responsible) { | 
| responsible_for_discovery_ = responsible; | 
| @@ -103,7 +165,7 @@ void ExtensionBluetoothEventRouter::DispatchDeviceEvent( | 
|  | 
| void ExtensionBluetoothEventRouter::AdapterPresentChanged( | 
| device::BluetoothAdapter* adapter, bool present) { | 
| -  if (adapter != adapter_.get()) { | 
| +  if (adapter != adapter_) { | 
| DVLOG(1) << "Ignoring event for adapter " << adapter->address(); | 
| return; | 
| } | 
| @@ -115,7 +177,7 @@ void ExtensionBluetoothEventRouter::AdapterPresentChanged( | 
|  | 
| void ExtensionBluetoothEventRouter::AdapterPoweredChanged( | 
| device::BluetoothAdapter* adapter, bool has_power) { | 
| -  if (adapter != adapter_.get()) { | 
| +  if (adapter != adapter_) { | 
| DVLOG(1) << "Ignoring event for adapter " << adapter->address(); | 
| return; | 
| } | 
| @@ -127,7 +189,7 @@ void ExtensionBluetoothEventRouter::AdapterPoweredChanged( | 
|  | 
| void ExtensionBluetoothEventRouter::AdapterDiscoveringChanged( | 
| device::BluetoothAdapter* adapter, bool discovering) { | 
| -  if (adapter != adapter_.get()) { | 
| +  if (adapter != adapter_) { | 
| DVLOG(1) << "Ignoring event for adapter " << adapter->address(); | 
| return; | 
| } | 
| @@ -146,7 +208,7 @@ void ExtensionBluetoothEventRouter::AdapterDiscoveringChanged( | 
| void ExtensionBluetoothEventRouter::DeviceAdded( | 
| device::BluetoothAdapter* adapter, | 
| device::BluetoothDevice* device) { | 
| -  if (adapter != adapter_.get()) { | 
| +  if (adapter != adapter_) { | 
| DVLOG(1) << "Ignoring event for adapter " << adapter->address(); | 
| return; | 
| } | 
|  |