OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "device/bluetooth/bluetooth_discovery_manager_mac.h" | |
6 | |
7 #import <IOBluetooth/objc/IOBluetoothDevice.h> | |
8 #import <IOBluetooth/objc/IOBluetoothDeviceInquiry.h> | |
9 | |
10 #include "base/mac/scoped_nsobject.h" | |
11 #include "base/mac/sdk_forward_declarations.h" | |
12 | |
13 namespace device { | |
14 | |
15 class BluetoothDiscoveryManagerMacClassic; | |
16 | |
17 } // namespace device | |
18 | |
19 // Replicate specific 10.7 SDK declarations for building with prior SDKs. | |
20 #if !defined(MAC_OS_X_VERSION_10_7) || \ | |
21 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | |
22 | |
23 @protocol IOBluetoothDeviceInquiryDelegate | |
24 - (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender; | |
25 - (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender | |
26 device:(IOBluetoothDevice*)device; | |
27 - (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender | |
28 error:(IOReturn)error | |
29 aborted:(BOOL)aborted; | |
30 @end | |
31 | |
32 #endif // MAC_OS_X_VERSION_10_7 | |
Ilya Sherman
2014/06/10 23:23:01
To clarify my previous comment, the idea is that a
armansito
2014/06/13 02:14:54
Ah, I misunderstood. Done.
| |
33 | |
34 // IOBluetoothDeviceInquiryDelegate implementation. | |
35 @interface BluetoothDeviceInquiryDelegate | |
36 : NSObject<IOBluetoothDeviceInquiryDelegate> { | |
37 @private | |
38 device::BluetoothDiscoveryManagerMacClassic* manager_; // weak | |
39 } | |
40 | |
41 - (id)initWithManager:(device::BluetoothDiscoveryManagerMacClassic*)manager; | |
42 | |
43 @end | |
44 | |
45 namespace device { | |
46 | |
47 // ementation of BluetoothDiscoveryManagerMac for Bluetooth classic device | |
48 // discovery, using the IOBluetooth framework. | |
49 class BluetoothDiscoveryManagerMacClassic | |
50 : public BluetoothDiscoveryManagerMac { | |
51 public: | |
52 BluetoothDiscoveryManagerMacClassic() | |
53 : should_do_discovery_(false), | |
54 inquiry_running_(false), | |
55 inquiry_delegate_( | |
56 [[BluetoothDeviceInquiryDelegate alloc] initWithManager:this]), | |
57 inquiry_([[IOBluetoothDeviceInquiry alloc] | |
58 initWithDelegate:inquiry_delegate_]) {} | |
59 | |
60 virtual ~BluetoothDiscoveryManagerMacClassic() {} | |
61 | |
62 // BluetoothDiscoveryManagerMac override. | |
63 virtual bool IsDiscovering() const OVERRIDE { return should_do_discovery_; } | |
64 | |
65 // BluetoothDiscoveryManagerMac override. | |
66 virtual bool StartDiscovery() OVERRIDE { | |
67 DVLOG(1) << "Bluetooth Classic: StartDiscovery"; | |
68 DCHECK(!should_do_discovery_); | |
69 | |
70 DVLOG(1) << "Discovery requested"; | |
71 should_do_discovery_ = true; | |
72 | |
73 if (inquiry_running_) { | |
74 DVLOG(1) << "Device inquiry already running"; | |
75 return true; | |
76 } | |
77 | |
78 DVLOG(1) << "Requesting to start device inquiry"; | |
79 if ([inquiry_ start] != kIOReturnSuccess) { | |
80 DVLOG(1) << "Failed to start device inquiry"; | |
81 | |
82 // Set |should_do_discovery_| to false here. Since we're reporting an | |
83 // error, we're indicating that the adapter call StartDiscovery again | |
84 // if needed. | |
85 should_do_discovery_ = false; | |
86 return false; | |
87 } | |
88 | |
89 DVLOG(1) << "Device inquiry start was successful"; | |
90 return true; | |
91 } | |
92 | |
93 // BluetoothDiscoveryManagerMac override. | |
94 virtual bool StopDiscovery() OVERRIDE { | |
95 DVLOG(1) << "Bluetooth Classic: StopDiscovery"; | |
96 DCHECK(should_do_discovery_); | |
97 | |
98 should_do_discovery_ = false; | |
99 | |
100 if (!inquiry_running_) { | |
101 DVLOG(1) << "No device inquiry running; discovery stopped"; | |
102 return true; | |
103 } | |
104 | |
105 DVLOG(1) << "Requesting to stop device inquiry"; | |
106 IOReturn status = [inquiry_ stop]; | |
107 if (status == kIOReturnSuccess) { | |
108 DVLOG(1) << "Device inquiry stop was successful"; | |
109 return true; | |
110 } | |
111 | |
112 if (status == kIOReturnNotPermitted) { | |
113 DVLOG(1) << "Device inquiry was already stopped"; | |
114 return true; | |
115 } | |
116 | |
117 LOG(WARNING) << "Failed to stop device inquiry"; | |
118 return false; | |
119 } | |
120 | |
121 // Called by BluetoothDeviceInquiryDelegate. | |
122 void DeviceInquiryStarted(IOBluetoothDeviceInquiry* inquiry) { | |
123 DCHECK(!inquiry_running_); | |
124 | |
125 DVLOG(1) << "Device inquiry started!"; | |
126 | |
127 // If discovery was requested to stop in the mean time, stop the inquiry. | |
128 if (!should_do_discovery_) { | |
129 DVLOG(1) << "Discovery stop was requested earlier. Stopping inquiry"; | |
130 [inquiry stop]; | |
131 return; | |
132 } | |
133 | |
134 inquiry_running_ = true; | |
135 } | |
136 | |
137 void DeviceFound(IOBluetoothDeviceInquiry* inquiry, | |
138 IOBluetoothDevice* device) { | |
139 FOR_EACH_OBSERVER(Observer, observers_, DeviceFound(this, device)); | |
140 } | |
141 | |
142 void DeviceInquiryComplete(IOBluetoothDeviceInquiry* inquiry, | |
143 IOReturn error, | |
144 bool aborted) { | |
145 DCHECK_EQ(inquiry_, inquiry); | |
146 DVLOG(1) << "Device inquiry complete"; | |
147 inquiry_running_ = false; | |
148 | |
149 // If discovery is no longer desired, notify observers that discovery | |
150 // has stopped and return. | |
151 if (!should_do_discovery_) { | |
152 FOR_EACH_OBSERVER( | |
153 Observer, observers_, DiscoveryStopped(this, false /* unexpected */)); | |
154 return; | |
155 } | |
156 | |
157 // If discovery has stopped due to an unexpected reason, notify the | |
158 // observers and return. | |
159 if (error != kIOReturnSuccess) { | |
160 DVLOG(1) << "Inquiry has stopped with an error: " << error; | |
161 should_do_discovery_ = false; | |
162 FOR_EACH_OBSERVER( | |
163 Observer, observers_, DiscoveryStopped(this, true /* unexpected */)); | |
164 return; | |
165 } | |
166 | |
167 DVLOG(1) << "Restarting device inquiry"; | |
168 | |
169 if ([inquiry_ start] == kIOReturnSuccess) { | |
170 DVLOG(1) << "Device inquiry restart was successful"; | |
171 return; | |
172 } | |
173 | |
174 DVLOG(1) << "Failed to restart discovery"; | |
175 should_do_discovery_ = false; | |
176 FOR_EACH_OBSERVER( | |
177 Observer, observers_, DiscoveryStopped(this, true /* unexpected */)); | |
178 } | |
179 | |
180 private: | |
181 // The requested discovery state. | |
182 bool should_do_discovery_; | |
183 | |
184 // The current inquiry state. | |
185 bool inquiry_running_; | |
186 | |
187 // Objective-C objects for running and tracking device inquiry. | |
188 base::scoped_nsobject<BluetoothDeviceInquiryDelegate> inquiry_delegate_; | |
189 base::scoped_nsobject<IOBluetoothDeviceInquiry> inquiry_; | |
190 | |
191 DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoveryManagerMacClassic); | |
192 }; | |
193 | |
194 BluetoothDiscoveryManagerMac::BluetoothDiscoveryManagerMac() { | |
195 } | |
196 BluetoothDiscoveryManagerMac::~BluetoothDiscoveryManagerMac() { | |
197 } | |
198 | |
199 void BluetoothDiscoveryManagerMac::AddObserver(Observer* observer) { | |
200 observers_.AddObserver(observer); | |
201 } | |
202 | |
203 void BluetoothDiscoveryManagerMac::RemoveObserver(Observer* observer) { | |
204 observers_.RemoveObserver(observer); | |
205 } | |
206 | |
207 // static | |
208 BluetoothDiscoveryManagerMac* BluetoothDiscoveryManagerMac::CreateClassic() { | |
209 return new BluetoothDiscoveryManagerMacClassic(); | |
210 } | |
211 | |
212 } // namespace device | |
213 | |
214 @implementation BluetoothDeviceInquiryDelegate | |
215 | |
216 - (id)initWithManager: | |
217 (device::BluetoothDiscoveryManagerMacClassic*)manager { | |
218 if ((self = [super init])) | |
219 manager_ = manager; | |
220 | |
221 return self; | |
222 } | |
223 | |
224 - (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender { | |
225 manager_->DeviceInquiryStarted(sender); | |
226 } | |
227 | |
228 - (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender | |
229 device:(IOBluetoothDevice*)device { | |
230 manager_->DeviceFound(sender, device); | |
231 } | |
232 | |
233 - (void)deviceInquiryComplete:(IOBluetoothDeviceInquiry*)sender | |
234 error:(IOReturn)error | |
235 aborted:(BOOL)aborted { | |
236 manager_->DeviceInquiryComplete(sender, error, aborted); | |
237 } | |
238 | |
239 @end | |
OLD | NEW |