- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / device_monitor_mac.mm
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 "content/browser/device_monitor_mac.h"
6
7 #import <QTKit/QTKit.h>
8
9 #include "base/logging.h"
10
11 namespace content {
12
13 class DeviceMonitorMac::QTMonitorImpl {
14  public:
15   explicit QTMonitorImpl(DeviceMonitorMac* monitor);
16   virtual ~QTMonitorImpl() {}
17
18   void Start();
19   void Stop();
20
21  private:
22   void CountDevices();
23   void OnAttributeChanged(NSNotification* notification);
24   void OnDeviceChanged();
25
26   DeviceMonitorMac* monitor_;
27   int number_audio_devices_;
28   int number_video_devices_;
29   id device_arrival_;
30   id device_removal_;
31   id device_change_;
32
33   DISALLOW_COPY_AND_ASSIGN(QTMonitorImpl);
34 };
35
36 DeviceMonitorMac::QTMonitorImpl::QTMonitorImpl(DeviceMonitorMac* monitor)
37     : monitor_(monitor),
38       number_audio_devices_(-1),
39       number_video_devices_(-1),
40       device_arrival_(nil),
41       device_removal_(nil) {
42   DCHECK(monitor);
43 }
44
45 void DeviceMonitorMac::QTMonitorImpl::Start() {
46   NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
47   device_arrival_ =
48       [nc addObserverForName:QTCaptureDeviceWasConnectedNotification
49                       object:nil
50                        queue:nil
51                   usingBlock:^(NSNotification* notification) {
52                       OnDeviceChanged();}];
53
54   device_removal_ =
55       [nc addObserverForName:QTCaptureDeviceWasDisconnectedNotification
56                       object:nil
57                        queue:nil
58                   usingBlock:^(NSNotification* notification) {
59                       OnDeviceChanged();}];
60
61   device_change_ =
62       [nc addObserverForName:QTCaptureDeviceAttributeDidChangeNotification
63                       object:nil
64                        queue:nil
65                   usingBlock:^(NSNotification* notification) {
66                       OnAttributeChanged(notification);}];
67 }
68
69 void DeviceMonitorMac::QTMonitorImpl::Stop() {
70   if (!monitor_)
71     return;
72
73   NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
74   [nc removeObserver:device_arrival_];
75   [nc removeObserver:device_removal_];
76   [nc removeObserver:device_change_];
77 }
78
79 void DeviceMonitorMac::QTMonitorImpl::OnAttributeChanged(
80     NSNotification* notification) {
81   if ([[[notification userInfo] objectForKey:QTCaptureDeviceChangedAttributeKey]
82           isEqualToString:QTCaptureDeviceSuspendedAttribute])
83     OnDeviceChanged();
84 }
85
86 void DeviceMonitorMac::QTMonitorImpl::CountDevices() {
87   NSArray* devices = [QTCaptureDevice inputDevices];
88   number_video_devices_ = 0;
89   number_audio_devices_ = 0;
90   for (QTCaptureDevice* device in devices) {
91     // Act as if suspended video capture devices are not attached.  For
92     // example, a laptop's internal webcam is suspended when the lid is closed.
93     if (([device hasMediaType:QTMediaTypeVideo] ||
94          [device hasMediaType:QTMediaTypeMuxed]) &&
95         ![[device attributeForKey:QTCaptureDeviceSuspendedAttribute] boolValue])
96       ++number_video_devices_;
97
98     if ([device hasMediaType:QTMediaTypeSound] ||
99         [device hasMediaType:QTMediaTypeMuxed])
100       ++number_audio_devices_;
101   }
102 }
103
104 void DeviceMonitorMac::QTMonitorImpl::OnDeviceChanged() {
105   int number_video_devices = number_video_devices_;
106   int number_audio_devices = number_audio_devices_;
107   CountDevices();
108
109   if (number_video_devices_ != number_video_devices)
110     monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
111
112   if (number_audio_devices_ != number_audio_devices)
113     monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
114 }
115
116 DeviceMonitorMac::DeviceMonitorMac() {
117   qt_monitor_.reset(new QTMonitorImpl(this));
118   qt_monitor_->Start();
119 }
120
121 DeviceMonitorMac::~DeviceMonitorMac() {
122   qt_monitor_->Stop();
123 }
124
125 void DeviceMonitorMac::NotifyDeviceChanged(
126     base::SystemMonitor::DeviceType type) {
127   // TODO(xians): Remove the global variable for SystemMonitor.
128   base::SystemMonitor::Get()->ProcessDevicesChanged(type);
129 }
130
131 }  // namespace content