OLD | NEW |
---|---|
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 "content/browser/device_monitor_mac.h" | 5 #include "content/browser/device_monitor_mac.h" |
6 | 6 |
7 #import <QTKit/QTKit.h> | 7 #import <QTKit/QTKit.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/mac/scoped_nsobject.h" | 10 #include "base/mac/scoped_nsobject.h" |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 ![[device attributeForKey:QTCaptureDeviceSuspendedAttribute] | 197 ![[device attributeForKey:QTCaptureDeviceSuspendedAttribute] |
198 boolValue]) { | 198 boolValue]) { |
199 device_type = DeviceInfo::kAudio; | 199 device_type = DeviceInfo::kAudio; |
200 } | 200 } |
201 snapshot_devices.push_back( | 201 snapshot_devices.push_back( |
202 DeviceInfo([[device uniqueID] UTF8String], device_type)); | 202 DeviceInfo([[device uniqueID] UTF8String], device_type)); |
203 } | 203 } |
204 ConsolidateDevicesListAndNotify(snapshot_devices); | 204 ConsolidateDevicesListAndNotify(snapshot_devices); |
205 } | 205 } |
206 | 206 |
207 // Forward declaration for use by CrAVFoundationSuspendObserver. | 207 // Forward declaration for use by CrAVFoundationDeviceObserver. |
208 class AVFoundationMonitorImpl; | 208 class AVFoundationMonitorImpl; |
209 | 209 |
210 } // namespace | 210 } // namespace |
211 | 211 |
212 // This class is a Key-Value Observer (KVO) shim. It is needed because C++ | 212 // This class is a Key-Value Observer (KVO) shim. It is needed because C++ |
213 // classes cannot observe Key-Values directly. | 213 // classes cannot observe Key-Values directly. |
214 @interface CrAVFoundationSuspendObserver : NSObject { | 214 @interface CrAVFoundationDeviceObserver : NSObject { |
215 @private | 215 @private |
216 AVFoundationMonitorImpl* receiver_; | 216 AVFoundationMonitorImpl* receiver_; |
217 } | 217 } |
218 | 218 |
219 - (id)initWithChangeReceiver:(AVFoundationMonitorImpl*)receiver; | 219 - (id)initWithChangeReceiver:(AVFoundationMonitorImpl*)receiver; |
220 - (void)startObserving:(CrAVCaptureDevice*)device; | 220 - (void)startObserving:(CrAVCaptureDevice*)device; |
221 - (void)stopObserving:(CrAVCaptureDevice*)device; | 221 - (void)stopObserving:(CrAVCaptureDevice*)device; |
222 | 222 |
223 @end | 223 @end |
224 | 224 |
225 namespace { | 225 namespace { |
226 | 226 |
227 class AVFoundationMonitorImpl : public DeviceMonitorMacImpl { | 227 class AVFoundationMonitorImpl : public DeviceMonitorMacImpl { |
228 public: | 228 public: |
229 explicit AVFoundationMonitorImpl(content::DeviceMonitorMac* monitor); | 229 explicit AVFoundationMonitorImpl(content::DeviceMonitorMac* monitor); |
230 virtual ~AVFoundationMonitorImpl(); | 230 virtual ~AVFoundationMonitorImpl(); |
231 | 231 |
232 virtual void OnDeviceChanged() OVERRIDE; | 232 virtual void OnDeviceChanged() OVERRIDE; |
233 | 233 |
234 private: | 234 private: |
235 base::scoped_nsobject<CrAVFoundationSuspendObserver> suspend_observer_; | 235 base::scoped_nsobject<CrAVFoundationDeviceObserver> suspend_observer_; |
236 DISALLOW_COPY_AND_ASSIGN(AVFoundationMonitorImpl); | 236 DISALLOW_COPY_AND_ASSIGN(AVFoundationMonitorImpl); |
237 }; | 237 }; |
238 | 238 |
239 AVFoundationMonitorImpl::AVFoundationMonitorImpl( | 239 AVFoundationMonitorImpl::AVFoundationMonitorImpl( |
240 content::DeviceMonitorMac* monitor) | 240 content::DeviceMonitorMac* monitor) |
241 : DeviceMonitorMacImpl(monitor) { | 241 : DeviceMonitorMacImpl(monitor) { |
242 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; | 242 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; |
243 device_arrival_ = | 243 device_arrival_ = |
244 [nc addObserverForName:AVFoundationGlue:: | 244 [nc addObserverForName:AVFoundationGlue:: |
245 AVCaptureDeviceWasConnectedNotification() | 245 AVCaptureDeviceWasConnectedNotification() |
246 object:nil | 246 object:nil |
247 queue:nil | 247 queue:nil |
248 usingBlock:^(NSNotification* notification) { | 248 usingBlock:^(NSNotification* notification) { |
249 OnDeviceChanged();}]; | 249 OnDeviceChanged();}]; |
250 device_removal_ = | 250 device_removal_ = |
251 [nc addObserverForName:AVFoundationGlue:: | 251 [nc addObserverForName:AVFoundationGlue:: |
252 AVCaptureDeviceWasDisconnectedNotification() | 252 AVCaptureDeviceWasDisconnectedNotification() |
253 object:nil | 253 object:nil |
254 queue:nil | 254 queue:nil |
255 usingBlock:^(NSNotification* notification) { | 255 usingBlock:^(NSNotification* notification) { |
256 OnDeviceChanged();}]; | 256 OnDeviceChanged();}]; |
257 suspend_observer_.reset( | 257 suspend_observer_.reset( |
258 [[CrAVFoundationSuspendObserver alloc] initWithChangeReceiver:this]); | 258 [[CrAVFoundationDeviceObserver alloc] initWithChangeReceiver:this]); |
259 for (CrAVCaptureDevice* device in [AVCaptureDeviceGlue devices]) | 259 for (CrAVCaptureDevice* device in [AVCaptureDeviceGlue devices]) |
260 [suspend_observer_ startObserving:device]; | 260 [suspend_observer_ startObserving:device]; |
261 } | 261 } |
262 | 262 |
263 AVFoundationMonitorImpl::~AVFoundationMonitorImpl() { | 263 AVFoundationMonitorImpl::~AVFoundationMonitorImpl() { |
264 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; | 264 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; |
265 [nc removeObserver:device_arrival_]; | 265 [nc removeObserver:device_arrival_]; |
266 [nc removeObserver:device_removal_]; | 266 [nc removeObserver:device_removal_]; |
267 for (CrAVCaptureDevice* device in [AVCaptureDeviceGlue devices]) | 267 for (CrAVCaptureDevice* device in [AVCaptureDeviceGlue devices]) |
268 [suspend_observer_ stopObserving:device]; | 268 [suspend_observer_ stopObserving:device]; |
(...skipping 16 matching lines...) Expand all Loading... | |
285 device_type = DeviceInfo::kAudio; | 285 device_type = DeviceInfo::kAudio; |
286 } | 286 } |
287 snapshot_devices.push_back(DeviceInfo([[device uniqueID] UTF8String], | 287 snapshot_devices.push_back(DeviceInfo([[device uniqueID] UTF8String], |
288 device_type)); | 288 device_type)); |
289 } | 289 } |
290 ConsolidateDevicesListAndNotify(snapshot_devices); | 290 ConsolidateDevicesListAndNotify(snapshot_devices); |
291 } | 291 } |
292 | 292 |
293 } // namespace | 293 } // namespace |
294 | 294 |
295 @implementation CrAVFoundationSuspendObserver | 295 @implementation CrAVFoundationDeviceObserver |
296 | 296 |
297 - (id)initWithChangeReceiver:(AVFoundationMonitorImpl*)receiver { | 297 - (id)initWithChangeReceiver:(AVFoundationMonitorImpl*)receiver { |
298 if ((self = [super init])) { | 298 if ((self = [super init])) { |
299 DCHECK(receiver != NULL); | 299 DCHECK(receiver != NULL); |
300 receiver_ = receiver; | 300 receiver_ = receiver; |
301 } | 301 } |
302 return self; | 302 return self; |
303 } | 303 } |
304 | 304 |
305 - (void)startObserving:(CrAVCaptureDevice*)device { | 305 - (void)startObserving:(CrAVCaptureDevice*)device { |
306 DCHECK(device != nil); | 306 DCHECK(device != nil); |
307 [device addObserver:self | 307 [device addObserver:self |
308 forKeyPath:@"suspended" | 308 forKeyPath:@"suspended" |
309 options:0 | 309 options:0 |
310 context:nil]; | 310 context:device]; |
311 [device addObserver:self | |
312 forKeyPath:@"connected" | |
313 options:0 | |
314 context:device]; | |
311 } | 315 } |
312 | 316 |
313 - (void)stopObserving:(CrAVCaptureDevice*)device { | 317 - (void)stopObserving:(CrAVCaptureDevice*)device { |
314 DCHECK(device != nil); | 318 DCHECK(device != nil); |
315 [device removeObserver:self | 319 [device removeObserver:self |
316 forKeyPath:@"suspended"]; | 320 forKeyPath:@"suspended"]; |
321 [device removeObserver:self | |
322 forKeyPath:@"connected"]; | |
317 } | 323 } |
318 | 324 |
319 - (void)observeValueForKeyPath:(NSString*)keyPath | 325 - (void)observeValueForKeyPath:(NSString*)keyPath |
320 ofObject:(id)object | 326 ofObject:(id)object |
321 change:(NSDictionary*)change | 327 change:(NSDictionary*)change |
322 context:(void*)context { | 328 context:(void*)context { |
323 if ([keyPath isEqual:@"suspended"]) | 329 if ([keyPath isEqual:@"suspended"]) |
324 receiver_->OnDeviceChanged(); | 330 receiver_->OnDeviceChanged(); |
331 if ([keyPath isEqual:@"connected"]) { | |
Robert Sesek
2014/03/06 17:08:20
nit: you don't have braces around the other if, so
mcasas
2014/03/06 17:21:58
Done.
Apologies, forgot them after removing debug
| |
332 [self stopObserving:(CrAVCaptureDevice*)context]; | |
Robert Sesek
2014/03/06 17:08:20
static_cast
mcasas
2014/03/06 17:21:58
Done.
| |
333 } | |
325 } | 334 } |
326 | 335 |
327 @end // @implementation CrAVFoundationSuspendObserver | 336 @end // @implementation CrAVFoundationDeviceObserver |
328 | 337 |
329 namespace content { | 338 namespace content { |
330 | 339 |
331 DeviceMonitorMac::DeviceMonitorMac() { | 340 DeviceMonitorMac::DeviceMonitorMac() { |
332 if (AVFoundationGlue::IsAVFoundationSupported()) { | 341 if (AVFoundationGlue::IsAVFoundationSupported()) { |
333 DVLOG(1) << "Monitoring via AVFoundation"; | 342 DVLOG(1) << "Monitoring via AVFoundation"; |
334 device_monitor_impl_.reset(new AVFoundationMonitorImpl(this)); | 343 device_monitor_impl_.reset(new AVFoundationMonitorImpl(this)); |
335 // For the AVFoundation to start sending connect/disconnect notifications, | 344 // For the AVFoundation to start sending connect/disconnect notifications, |
336 // the AVFoundation NSBundle has to be loaded and the devices enumerated. | 345 // the AVFoundation NSBundle has to be loaded and the devices enumerated. |
337 // This operation seems to take in the range of hundred of ms. so should be | 346 // This operation seems to take in the range of hundred of ms. so should be |
338 // moved to the point when is needed, and that is during | 347 // moved to the point when is needed, and that is during |
339 // DeviceVideoCaptureMac +getDeviceNames. | 348 // DeviceVideoCaptureMac +getDeviceNames. |
340 } else { | 349 } else { |
341 DVLOG(1) << "Monitoring via QTKit"; | 350 DVLOG(1) << "Monitoring via QTKit"; |
342 device_monitor_impl_.reset(new QTKitMonitorImpl(this)); | 351 device_monitor_impl_.reset(new QTKitMonitorImpl(this)); |
343 } | 352 } |
344 } | 353 } |
345 | 354 |
346 DeviceMonitorMac::~DeviceMonitorMac() {} | 355 DeviceMonitorMac::~DeviceMonitorMac() {} |
347 | 356 |
348 void DeviceMonitorMac::NotifyDeviceChanged( | 357 void DeviceMonitorMac::NotifyDeviceChanged( |
349 base::SystemMonitor::DeviceType type) { | 358 base::SystemMonitor::DeviceType type) { |
350 // TODO(xians): Remove the global variable for SystemMonitor. | 359 // TODO(xians): Remove the global variable for SystemMonitor. |
351 base::SystemMonitor::Get()->ProcessDevicesChanged(type); | 360 base::SystemMonitor::Get()->ProcessDevicesChanged(type); |
352 } | 361 } |
353 | 362 |
354 } // namespace content | 363 } // namespace content |
OLD | NEW |