device_request_message_filter.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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/renderer_host/media/media_stream_manager.h" 9#include "content/common/media/media_stream_messages.h" 10#include "content/public/browser/media_device_id.h" 11#include "content/public/browser/resource_context.h" 12 13// Clears the MediaStreamDevice.name from all devices in |device_list|. 14static void ClearDeviceLabels(content::StreamDeviceInfoArray* devices) { 15 for (content::StreamDeviceInfoArray::iterator device_itr = devices->begin(); 16 device_itr != devices->end(); 17 ++device_itr) { 18 device_itr->device.name.clear(); 19 } 20} 21 22namespace content { 23 24DeviceRequestMessageFilter::DeviceRequestMessageFilter( 25 ResourceContext* resource_context, 26 MediaStreamManager* media_stream_manager) 27 : resource_context_(resource_context), 28 media_stream_manager_(media_stream_manager) { 29 DCHECK(resource_context); 30 DCHECK(media_stream_manager); 31} 32 33DeviceRequestMessageFilter::~DeviceRequestMessageFilter() { 34 DCHECK(requests_.empty()); 35} 36 37struct DeviceRequestMessageFilter::DeviceRequest { 38 DeviceRequest(int request_id, 39 const GURL& origin, 40 const std::string& audio_devices_label, 41 const std::string& video_devices_label) 42 : request_id(request_id), 43 origin(origin), 44 has_audio_returned(false), 45 has_video_returned(false), 46 audio_devices_label(audio_devices_label), 47 video_devices_label(video_devices_label) {} 48 49 int request_id; 50 GURL origin; 51 bool has_audio_returned; 52 bool has_video_returned; 53 std::string audio_devices_label; 54 std::string video_devices_label; 55 StreamDeviceInfoArray audio_devices; 56 StreamDeviceInfoArray video_devices; 57}; 58 59void DeviceRequestMessageFilter::StreamGenerated( 60 const std::string& label, 61 const StreamDeviceInfoArray& audio_devices, 62 const StreamDeviceInfoArray& video_devices) { 63 NOTIMPLEMENTED(); 64} 65 66void DeviceRequestMessageFilter::StreamGenerationFailed( 67 const std::string& label) { 68 NOTIMPLEMENTED(); 69} 70 71void DeviceRequestMessageFilter::StopGeneratedStream( 72 int render_view_id, 73 const std::string& label) { 74 NOTIMPLEMENTED(); 75} 76 77void DeviceRequestMessageFilter::DevicesEnumerated( 78 const std::string& label, 79 const StreamDeviceInfoArray& new_devices) { 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 81 82 // Look up the DeviceRequest by id. 83 DeviceRequestList::iterator request_it = requests_.begin(); 84 for (; request_it != requests_.end(); ++request_it) { 85 if (label == request_it->audio_devices_label || 86 label == request_it->video_devices_label) { 87 break; 88 } 89 } 90 DCHECK(request_it != requests_.end()); 91 92 StreamDeviceInfoArray* audio_devices = &request_it->audio_devices; 93 StreamDeviceInfoArray* video_devices = &request_it->video_devices; 94 95 // Store hmac'd device ids instead of raw device ids. 96 if (label == request_it->audio_devices_label) { 97 request_it->has_audio_returned = true; 98 DCHECK(audio_devices->empty()); 99 HmacDeviceIds(request_it->origin, new_devices, audio_devices); 100 } else { 101 DCHECK(label == request_it->video_devices_label); 102 request_it->has_video_returned = true; 103 DCHECK(video_devices->empty()); 104 HmacDeviceIds(request_it->origin, new_devices, video_devices); 105 } 106 107 if (!request_it->has_audio_returned || !request_it->has_video_returned) { 108 // Wait for the rest of the devices to complete. 109 return; 110 } 111 112 // Query for mic and camera permissions. 113 if (!resource_context_->AllowMicAccess(request_it->origin)) 114 ClearDeviceLabels(audio_devices); 115 if (!resource_context_->AllowCameraAccess(request_it->origin)) 116 ClearDeviceLabels(video_devices); 117 118 // Both audio and video devices are ready for copying. 119 StreamDeviceInfoArray all_devices = *audio_devices; 120 all_devices.insert( 121 all_devices.end(), video_devices->begin(), video_devices->end()); 122 123 Send(new MediaStreamMsg_GetSourcesACK(request_it->request_id, all_devices)); 124 125 media_stream_manager_->CancelRequest(request_it->audio_devices_label); 126 media_stream_manager_->CancelRequest(request_it->video_devices_label); 127 requests_.erase(request_it); 128} 129 130void DeviceRequestMessageFilter::DeviceOpened( 131 const std::string& label, 132 const StreamDeviceInfo& video_device) { 133 NOTIMPLEMENTED(); 134} 135 136bool DeviceRequestMessageFilter::OnMessageReceived(const IPC::Message& message, 137 bool* message_was_ok) { 138 bool handled = true; 139 IPC_BEGIN_MESSAGE_MAP_EX(DeviceRequestMessageFilter, message, *message_was_ok) 140 IPC_MESSAGE_HANDLER(MediaStreamHostMsg_GetSources, OnGetSources) 141 IPC_MESSAGE_UNHANDLED(handled = false) 142 IPC_END_MESSAGE_MAP_EX() 143 return handled; 144} 145 146void DeviceRequestMessageFilter::OnChannelClosing() { 147 // Since the IPC channel is gone, cancel outstanding device requests. 148 media_stream_manager_->CancelAllRequests(peer_pid()); 149 150 requests_.clear(); 151} 152 153void DeviceRequestMessageFilter::HmacDeviceIds( 154 const GURL& origin, 155 const StreamDeviceInfoArray& raw_devices, 156 StreamDeviceInfoArray* devices_with_guids) { 157 DCHECK(devices_with_guids); 158 159 // Replace raw ids with hmac'd ids before returning to renderer process. 160 for (StreamDeviceInfoArray::const_iterator device_itr = raw_devices.begin(); 161 device_itr != raw_devices.end(); 162 ++device_itr) { 163 StreamDeviceInfo current_device_info = *device_itr; 164 current_device_info.device.id = 165 content::GetHMACForMediaDeviceID(origin, device_itr->device.id); 166 devices_with_guids->push_back(current_device_info); 167 } 168} 169 170void DeviceRequestMessageFilter::OnGetSources(int request_id, 171 const GURL& security_origin) { 172 // Make request to get audio devices. 173 const std::string& audio_label = media_stream_manager_->EnumerateDevices( 174 this, -1, -1, -1, MEDIA_DEVICE_AUDIO_CAPTURE, security_origin); 175 DCHECK(!audio_label.empty()); 176 177 // Make request for video devices. 178 const std::string& video_label = media_stream_manager_->EnumerateDevices( 179 this, -1, -1, -1, MEDIA_DEVICE_VIDEO_CAPTURE, security_origin); 180 DCHECK(!video_label.empty()); 181 182 requests_.push_back(DeviceRequest( 183 request_id, security_origin, audio_label, video_label)); 184} 185 186} // namespace content 187