Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: chrome/browser/extensions/api/bluetooth/bluetooth_event_router.cc

Issue 128523003: Unregister Bluetooth profile when the extension that added it is unloaded. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix style issue Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h" 5 #include "chrome/browser/extensions/api/bluetooth/bluetooth_event_router.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/json/json_writer.h" 11 #include "base/json/json_writer.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_vector.h" 14 #include "base/memory/scoped_vector.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h" 17 #include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h"
17 #include "chrome/browser/extensions/event_names.h" 18 #include "chrome/browser/extensions/event_names.h"
18 #include "chrome/browser/extensions/extension_system.h" 19 #include "chrome/browser/extensions/extension_system.h"
19 #include "chrome/common/extensions/api/bluetooth.h" 20 #include "chrome/common/extensions/api/bluetooth.h"
21 #include "content/public/browser/notification_details.h"
22 #include "content/public/browser/notification_source.h"
20 #include "device/bluetooth/bluetooth_adapter.h" 23 #include "device/bluetooth/bluetooth_adapter.h"
21 #include "device/bluetooth/bluetooth_adapter_factory.h" 24 #include "device/bluetooth/bluetooth_adapter_factory.h"
22 #include "device/bluetooth/bluetooth_device.h" 25 #include "device/bluetooth/bluetooth_device.h"
23 #include "device/bluetooth/bluetooth_profile.h" 26 #include "device/bluetooth/bluetooth_profile.h"
24 #include "device/bluetooth/bluetooth_socket.h" 27 #include "device/bluetooth/bluetooth_socket.h"
25 #include "extensions/browser/event_router.h" 28 #include "extensions/browser/event_router.h"
26 29
27 namespace extensions { 30 namespace extensions {
28 31
29 namespace bluetooth = api::bluetooth; 32 namespace bluetooth = api::bluetooth;
30 33
34 // A struct storing a Bluetooth socket and the extension that added it.
35 struct ExtensionBluetoothSocketRecord {
36 std::string extension_id;
37 scoped_refptr<device::BluetoothSocket> socket;
38 };
39
40 // A struct storing a Bluetooth profile and the extension that added it.
41 struct ExtensionBluetoothProfileRecord {
42 std::string extension_id;
43 device::BluetoothProfile* profile;
44 };
45
31 ExtensionBluetoothEventRouter::ExtensionBluetoothEventRouter(Profile* profile) 46 ExtensionBluetoothEventRouter::ExtensionBluetoothEventRouter(Profile* profile)
32 : send_discovery_events_(false), 47 : send_discovery_events_(false),
33 responsible_for_discovery_(false), 48 responsible_for_discovery_(false),
34 profile_(profile), 49 profile_(profile),
35 adapter_(NULL), 50 adapter_(NULL),
36 num_event_listeners_(0), 51 num_event_listeners_(0),
37 next_socket_id_(1), 52 next_socket_id_(1),
38 weak_ptr_factory_(this) { 53 weak_ptr_factory_(this) {
39 DCHECK(profile_); 54 DCHECK(profile_);
55 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
56 content::Source<Profile>(profile_));
40 } 57 }
41 58
42 ExtensionBluetoothEventRouter::~ExtensionBluetoothEventRouter() { 59 ExtensionBluetoothEventRouter::~ExtensionBluetoothEventRouter() {
43 if (adapter_.get()) { 60 if (adapter_.get()) {
44 adapter_->RemoveObserver(this); 61 adapter_->RemoveObserver(this);
45 adapter_ = NULL; 62 adapter_ = NULL;
46 } 63 }
47 DLOG_IF(WARNING, socket_map_.size() != 0) 64 DLOG_IF(WARNING, socket_map_.size() != 0)
48 << "Bluetooth sockets are still open."; 65 << "Bluetooth sockets are still open.";
49 socket_map_.clear(); 66 socket_map_.clear();
50 67
51 for (BluetoothProfileMap::iterator iter = bluetooth_profile_map_.begin(); 68 for (BluetoothProfileMap::iterator iter = bluetooth_profile_map_.begin();
52 iter != bluetooth_profile_map_.end(); 69 iter != bluetooth_profile_map_.end();
53 ++iter) { 70 ++iter) {
54 iter->second->Unregister(); 71 iter->second.profile->Unregister();
55 } 72 }
56 } 73 }
57 74
58 bool ExtensionBluetoothEventRouter::IsBluetoothSupported() const { 75 bool ExtensionBluetoothEventRouter::IsBluetoothSupported() const {
59 return adapter_.get() || 76 return adapter_.get() ||
60 device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable(); 77 device::BluetoothAdapterFactory::IsBluetoothAdapterAvailable();
61 } 78 }
62 79
63 void ExtensionBluetoothEventRouter::GetAdapter( 80 void ExtensionBluetoothEventRouter::GetAdapter(
64 const device::BluetoothAdapterFactory::AdapterCallback& callback) { 81 const device::BluetoothAdapterFactory::AdapterCallback& callback) {
(...skipping 10 matching lines...) Expand all
75 InitializeAdapterIfNeeded(); 92 InitializeAdapterIfNeeded();
76 } 93 }
77 94
78 void ExtensionBluetoothEventRouter::OnListenerRemoved() { 95 void ExtensionBluetoothEventRouter::OnListenerRemoved() {
79 if (num_event_listeners_ > 0) 96 if (num_event_listeners_ > 0)
80 num_event_listeners_--; 97 num_event_listeners_--;
81 MaybeReleaseAdapter(); 98 MaybeReleaseAdapter();
82 } 99 }
83 100
84 int ExtensionBluetoothEventRouter::RegisterSocket( 101 int ExtensionBluetoothEventRouter::RegisterSocket(
102 const std::string& extension_id,
85 scoped_refptr<device::BluetoothSocket> socket) { 103 scoped_refptr<device::BluetoothSocket> socket) {
86 // If there is a socket registered with the same fd, just return it's id 104 // If there is a socket registered with the same fd, just return it's id
87 for (SocketMap::const_iterator i = socket_map_.begin(); 105 for (SocketMap::const_iterator i = socket_map_.begin();
88 i != socket_map_.end(); ++i) { 106 i != socket_map_.end(); ++i) {
89 if (i->second.get() == socket.get()) 107 if (i->second.socket.get() == socket.get())
90 return i->first; 108 return i->first;
91 } 109 }
92 int return_id = next_socket_id_++; 110 int return_id = next_socket_id_++;
93 socket_map_[return_id] = socket; 111 ExtensionBluetoothSocketRecord record = { extension_id, socket };
112 socket_map_[return_id] = record;
94 return return_id; 113 return return_id;
95 } 114 }
96 115
97 bool ExtensionBluetoothEventRouter::ReleaseSocket(int id) { 116 bool ExtensionBluetoothEventRouter::ReleaseSocket(int id) {
98 SocketMap::iterator socket_entry = socket_map_.find(id); 117 SocketMap::iterator socket_entry = socket_map_.find(id);
99 if (socket_entry == socket_map_.end()) 118 if (socket_entry == socket_map_.end())
100 return false; 119 return false;
101 socket_map_.erase(socket_entry); 120 socket_map_.erase(socket_entry);
102 return true; 121 return true;
103 } 122 }
104 123
105 void ExtensionBluetoothEventRouter::AddProfile( 124 void ExtensionBluetoothEventRouter::AddProfile(
106 const std::string& uuid, 125 const std::string& uuid,
126 const std::string& extension_id,
107 device::BluetoothProfile* bluetooth_profile) { 127 device::BluetoothProfile* bluetooth_profile) {
108 DCHECK(!HasProfile(uuid)); 128 DCHECK(!HasProfile(uuid));
109 bluetooth_profile_map_[uuid] = bluetooth_profile; 129 ExtensionBluetoothProfileRecord record = { extension_id, bluetooth_profile };
130 bluetooth_profile_map_[uuid] = record;
110 } 131 }
111 132
112 void ExtensionBluetoothEventRouter::RemoveProfile(const std::string& uuid) { 133 void ExtensionBluetoothEventRouter::RemoveProfile(const std::string& uuid) {
113 BluetoothProfileMap::iterator iter = bluetooth_profile_map_.find(uuid); 134 BluetoothProfileMap::iterator iter = bluetooth_profile_map_.find(uuid);
114 if (iter != bluetooth_profile_map_.end()) { 135 if (iter != bluetooth_profile_map_.end()) {
115 device::BluetoothProfile* bluetooth_profile = iter->second; 136 device::BluetoothProfile* bluetooth_profile = iter->second.profile;
116 bluetooth_profile_map_.erase(iter); 137 bluetooth_profile_map_.erase(iter);
117 bluetooth_profile->Unregister(); 138 bluetooth_profile->Unregister();
118 } 139 }
119 } 140 }
120 141
121 bool ExtensionBluetoothEventRouter::HasProfile(const std::string& uuid) const { 142 bool ExtensionBluetoothEventRouter::HasProfile(const std::string& uuid) const {
122 return bluetooth_profile_map_.find(uuid) != bluetooth_profile_map_.end(); 143 return bluetooth_profile_map_.find(uuid) != bluetooth_profile_map_.end();
123 } 144 }
124 145
125 device::BluetoothProfile* ExtensionBluetoothEventRouter::GetProfile( 146 device::BluetoothProfile* ExtensionBluetoothEventRouter::GetProfile(
126 const std::string& uuid) const { 147 const std::string& uuid) const {
127 BluetoothProfileMap::const_iterator iter = bluetooth_profile_map_.find(uuid); 148 BluetoothProfileMap::const_iterator iter = bluetooth_profile_map_.find(uuid);
128 if (iter != bluetooth_profile_map_.end()) 149 if (iter != bluetooth_profile_map_.end())
129 return iter->second; 150 return iter->second.profile;
130 151
131 return NULL; 152 return NULL;
132 } 153 }
133 154
134 scoped_refptr<device::BluetoothSocket> 155 scoped_refptr<device::BluetoothSocket>
135 ExtensionBluetoothEventRouter::GetSocket(int id) { 156 ExtensionBluetoothEventRouter::GetSocket(int id) {
136 SocketMap::iterator socket_entry = socket_map_.find(id); 157 SocketMap::iterator socket_entry = socket_map_.find(id);
137 if (socket_entry == socket_map_.end()) 158 if (socket_entry == socket_map_.end())
138 return NULL; 159 return NULL;
139 return socket_entry->second; 160 return socket_entry->second.socket;;
140 } 161 }
141 162
142 void ExtensionBluetoothEventRouter::SetResponsibleForDiscovery( 163 void ExtensionBluetoothEventRouter::SetResponsibleForDiscovery(
143 bool responsible) { 164 bool responsible) {
144 responsible_for_discovery_ = responsible; 165 responsible_for_discovery_ = responsible;
145 } 166 }
146 167
147 bool ExtensionBluetoothEventRouter::IsResponsibleForDiscovery() const { 168 bool ExtensionBluetoothEventRouter::IsResponsibleForDiscovery() const {
148 return responsible_for_discovery_; 169 return responsible_for_discovery_;
149 } 170 }
(...skipping 21 matching lines...) Expand all
171 } 192 }
172 193
173 void ExtensionBluetoothEventRouter::DispatchConnectionEvent( 194 void ExtensionBluetoothEventRouter::DispatchConnectionEvent(
174 const std::string& extension_id, 195 const std::string& extension_id,
175 const std::string& uuid, 196 const std::string& uuid,
176 const device::BluetoothDevice* device, 197 const device::BluetoothDevice* device,
177 scoped_refptr<device::BluetoothSocket> socket) { 198 scoped_refptr<device::BluetoothSocket> socket) {
178 if (!HasProfile(uuid)) 199 if (!HasProfile(uuid))
179 return; 200 return;
180 201
181 int socket_id = RegisterSocket(socket); 202 int socket_id = RegisterSocket(extension_id, socket);
182 api::bluetooth::Socket result_socket; 203 api::bluetooth::Socket result_socket;
183 api::bluetooth::BluetoothDeviceToApiDevice(*device, &result_socket.device); 204 api::bluetooth::BluetoothDeviceToApiDevice(*device, &result_socket.device);
184 result_socket.profile.uuid = uuid; 205 result_socket.profile.uuid = uuid;
185 result_socket.id = socket_id; 206 result_socket.id = socket_id;
186 207
187 scoped_ptr<base::ListValue> args(new base::ListValue()); 208 scoped_ptr<base::ListValue> args(new base::ListValue());
188 args->Append(result_socket.ToValue().release()); 209 args->Append(result_socket.ToValue().release());
189 scoped_ptr<Event> event(new Event( 210 scoped_ptr<Event> event(new Event(
190 bluetooth::OnConnection::kEventName, args.Pass())); 211 bluetooth::OnConnection::kEventName, args.Pass()));
191 ExtensionSystem::Get(profile_)->event_router()->DispatchEventToExtension( 212 ExtensionSystem::Get(profile_)->event_router()->DispatchEventToExtension(
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 PopulateAdapterState(*adapter_.get(), &state); 295 PopulateAdapterState(*adapter_.get(), &state);
275 296
276 scoped_ptr<base::ListValue> args(new base::ListValue()); 297 scoped_ptr<base::ListValue> args(new base::ListValue());
277 args->Append(state.ToValue().release()); 298 args->Append(state.ToValue().release());
278 scoped_ptr<Event> event(new Event( 299 scoped_ptr<Event> event(new Event(
279 bluetooth::OnAdapterStateChanged::kEventName, 300 bluetooth::OnAdapterStateChanged::kEventName,
280 args.Pass())); 301 args.Pass()));
281 ExtensionSystem::Get(profile_)->event_router()->BroadcastEvent(event.Pass()); 302 ExtensionSystem::Get(profile_)->event_router()->BroadcastEvent(event.Pass());
282 } 303 }
283 304
305 void ExtensionBluetoothEventRouter::CleanUpForExtension(
306 const std::string& extension_id) {
307 // Remove all profiles added by the extension.
308 BluetoothProfileMap::iterator profile_iter = bluetooth_profile_map_.begin();
309 while (profile_iter != bluetooth_profile_map_.end()) {
310 ExtensionBluetoothProfileRecord record = profile_iter->second;
311 if (record.extension_id == extension_id) {
312 bluetooth_profile_map_.erase(profile_iter++);
313 record.profile->Unregister();
314 } else {
315 profile_iter++;
316 }
317 }
318
319 // Remove all sockets opened by the extension.
320 SocketMap::iterator socket_iter = socket_map_.begin();
321 while (socket_iter != socket_map_.end()) {
322 int socket_id = socket_iter->first;
323 ExtensionBluetoothSocketRecord record = socket_iter->second;
324 socket_iter++;
325 if (record.extension_id == extension_id) {
326 ReleaseSocket(socket_id);
327 }
328 }
329 }
330
331 void ExtensionBluetoothEventRouter::Observe(
332 int type,
333 const content::NotificationSource& source,
334 const content::NotificationDetails& details) {
335 switch (type) {
336 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
337 extensions::UnloadedExtensionInfo* info =
338 content::Details<extensions::UnloadedExtensionInfo>(details).ptr();
339 CleanUpForExtension(info->extension->id());
340 break;
341 }
342 }
343 }
344
284 } // namespace extensions 345 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698