Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / media / device_request_message_filter.cc
1 // Copyright 2013 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/renderer_host/media/device_request_message_filter.h"
6
7 #include "content/browser/browser_main_loop.h"
8 #include "content/browser/child_process_security_policy_impl.h"
9 #include "content/browser/renderer_host/media/media_stream_manager.h"
10 #include "content/common/media/media_stream_messages.h"
11 #include "content/public/browser/resource_context.h"
12
13 namespace content {
14
15 DeviceRequestMessageFilter::DeviceRequestMessageFilter(
16     ResourceContext* resource_context,
17     MediaStreamManager* media_stream_manager,
18     int render_process_id)
19     : BrowserMessageFilter(MediaStreamMsgStart),
20       resource_context_(resource_context),
21       media_stream_manager_(media_stream_manager),
22       render_process_id_(render_process_id) {
23   DCHECK(resource_context);
24   DCHECK(media_stream_manager);
25 }
26
27 DeviceRequestMessageFilter::~DeviceRequestMessageFilter() {
28   // CHECK rather than DCHECK to make sure this never happens in the
29   // wild. We want to be sure due to http://crbug.com/341211
30   CHECK(requests_.empty());
31 }
32
33 struct DeviceRequestMessageFilter::DeviceRequest {
34   DeviceRequest(int request_id,
35                 const GURL& origin,
36                 const std::string& audio_devices_label,
37                 const std::string& video_devices_label)
38       : request_id(request_id),
39         origin(origin),
40         has_audio_returned(false),
41         has_video_returned(false),
42         audio_devices_label(audio_devices_label),
43         video_devices_label(video_devices_label) {}
44
45   int request_id;
46   GURL origin;
47   bool has_audio_returned;
48   bool has_video_returned;
49   std::string audio_devices_label;
50   std::string video_devices_label;
51   StreamDeviceInfoArray audio_devices;
52   StreamDeviceInfoArray video_devices;
53 };
54
55 void DeviceRequestMessageFilter::DevicesEnumerated(
56     int render_frame_id,
57     int page_request_id,
58     const std::string& label,
59     const StreamDeviceInfoArray& new_devices) {
60   DCHECK_CURRENTLY_ON(BrowserThread::IO);
61
62   // Look up the DeviceRequest by id.
63   DeviceRequestList::iterator request_it = requests_.begin();
64   for (; request_it != requests_.end(); ++request_it) {
65     if (label == request_it->audio_devices_label ||
66         label == request_it->video_devices_label) {
67       break;
68     }
69   }
70   DCHECK(request_it != requests_.end());
71
72   StreamDeviceInfoArray* audio_devices = &request_it->audio_devices;
73   StreamDeviceInfoArray* video_devices = &request_it->video_devices;
74
75   // Store hmac'd device ids instead of raw device ids.
76   if (label == request_it->audio_devices_label) {
77     request_it->has_audio_returned = true;
78     DCHECK(audio_devices->empty());
79     *audio_devices = new_devices;
80   } else {
81     DCHECK(label == request_it->video_devices_label);
82     request_it->has_video_returned = true;
83     DCHECK(video_devices->empty());
84     *video_devices = new_devices;
85   }
86
87   if (!request_it->has_audio_returned || !request_it->has_video_returned) {
88     // Wait for the rest of the devices to complete.
89     return;
90   }
91
92   // Both audio and video devices are ready for copying.
93   StreamDeviceInfoArray all_devices = *audio_devices;
94   all_devices.insert(
95       all_devices.end(), video_devices->begin(), video_devices->end());
96
97   Send(new MediaStreamMsg_GetSourcesACK(request_it->request_id, all_devices));
98
99   media_stream_manager_->CancelRequest(request_it->audio_devices_label);
100   media_stream_manager_->CancelRequest(request_it->video_devices_label);
101   requests_.erase(request_it);
102 }
103
104 bool DeviceRequestMessageFilter::OnMessageReceived(
105     const IPC::Message& message) {
106   bool handled = true;
107   IPC_BEGIN_MESSAGE_MAP(DeviceRequestMessageFilter, message)
108     IPC_MESSAGE_HANDLER(MediaStreamHostMsg_GetSources, OnGetSources)
109     IPC_MESSAGE_UNHANDLED(handled = false)
110   IPC_END_MESSAGE_MAP()
111   return handled;
112 }
113
114 void DeviceRequestMessageFilter::OnChannelClosing() {
115   // Since the IPC channel is gone, cancel outstanding device requests.
116   for (DeviceRequestList::iterator request_it = requests_.begin();
117        request_it != requests_.end(); ++request_it) {
118     media_stream_manager_->CancelRequest(request_it->audio_devices_label);
119     media_stream_manager_->CancelRequest(request_it->video_devices_label);
120   }
121   requests_.clear();
122 }
123
124 void DeviceRequestMessageFilter::OnGetSources(int request_id,
125                                               const GURL& security_origin) {
126   if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(
127           render_process_id_, security_origin)) {
128     LOG(ERROR) << "Disallowed URL in DRMF::OnGetSources: " << security_origin;
129     return;
130   }
131
132   // Make request to get audio devices.
133   const std::string& audio_label = media_stream_manager_->EnumerateDevices(
134       this, render_process_id_, -1, resource_context_->GetMediaDeviceIDSalt(),
135       -1, MEDIA_DEVICE_AUDIO_CAPTURE, security_origin);
136   DCHECK(!audio_label.empty());
137
138   // Make request for video devices.
139   const std::string& video_label = media_stream_manager_->EnumerateDevices(
140       this, render_process_id_, -1, resource_context_->GetMediaDeviceIDSalt(),
141       -1, MEDIA_DEVICE_VIDEO_CAPTURE, security_origin);
142   DCHECK(!video_label.empty());
143
144   requests_.push_back(DeviceRequest(
145       request_id, security_origin, audio_label, video_label));
146 }
147
148 }  // namespace content