Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: chrome/browser/media/media_stream_devices_controller.cc

Issue 10537099: add "always allow" option to the mediastream infobar and allow user to allow/not allow acces to devi (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased, addressed comments from Ivan, let "block" apply before exceptions Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "chrome/browser/media/media_stream_devices_controller.h"
6
7 #include "base/values.h"
8 #include "chrome/browser/content_settings/content_settings_provider.h"
9 #include "chrome/browser/content_settings/host_content_settings_map.h"
10 #include "chrome/browser/prefs/scoped_user_pref_update.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/common/content_settings.h"
14 #include "chrome/common/pref_names.h"
15
16 using content::BrowserThread;
17
18 namespace {
19
20 // A predicate that checks if a StreamDeviceInfo object has the same ID as the
21 // device ID specified at construction.
22 class DeviceIdEquals {
23 public:
24 explicit DeviceIdEquals(const std::string& device_id)
25 : device_id_(device_id) {
26 }
27
28 bool operator() (const content::MediaStreamDevice& device) {
29 return device.device_id == device_id_;
30 }
31
32 private:
33 std::string device_id_;
34 };
35
36 // A predicate that checks if a StreamDeviceInfo object has the same device
37 // name as the device name specified at construction.
38 class DeviceNameEquals {
39 public:
40 explicit DeviceNameEquals(const std::string& device_name)
41 : device_name_(device_name) {
42 }
43
44 bool operator() (const content::MediaStreamDevice& device) {
45 return device.name == device_name_;
46 }
47
48 private:
49 std::string device_name_;
50 };
51
52 const char kAudioKey[] = "audio";
53 const char kVideoKey[] = "video";
54
55 } // namespace
56
57 MediaStreamDevicesController::MediaStreamDevicesController(
58 Profile* profile,
59 const content::MediaStreamRequest* request,
60 const content::MediaResponseCallback& callback)
61 : profile_(profile),
62 request_(request),
63 callback_(callback) {
64 DCHECK(request_);
65 DCHECK(!request_->security_origin.is_empty());
66 has_audio_ = request_->devices.count(
67 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) != 0;
68 has_video_ = request_->devices.count(
69 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) != 0;
70 }
71
72 MediaStreamDevicesController::~MediaStreamDevicesController() {}
73
74 bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
75 // Deny the request and don't show the infobar if there is no devices.
76 if (!has_audio_ && !has_video_) {
77 Deny();
78 return true;
79 }
80
81 // If the user has blocked the access to the media device in content
82 // settings, deny the request without showing the infobar.
83 if (IsMediaDeviceBlocked()){
84 Deny();
85 return true;
86 }
87
88 // If there are "always allowed" devices for the request, accept the request
89 // without showing the infobar.
90 std::string audio, video;
91 GetAlwaysAllowedDevices(&audio, &video);
92 // If there is no "always allowed" device for the origin, or the device is
93 // not available in the device lists, force showing the infobar.
94 if ((has_audio_ && audio.empty()) || (has_video_ && video.empty()))
95 return false;
96
97 Accept(audio, video, false);
98 return true;
99 }
100
101 content::MediaStreamDevices
102 MediaStreamDevicesController::GetAudioDevices() const {
103 if (!has_audio_)
104 return content::MediaStreamDevices();
105
106 content::MediaStreamDeviceMap::const_iterator it =
107 request_->devices.find(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
108 DCHECK(it != request_->devices.end());
109 return it->second;
110 }
111
112 content::MediaStreamDevices
113 MediaStreamDevicesController::GetVideoDevices() const {
114 if (!has_video_)
115 return content::MediaStreamDevices();
116
117 content::MediaStreamDeviceMap::const_iterator it =
118 request_->devices.find(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
119 DCHECK(it != request_->devices.end());
120 return it->second;
121 }
122
123 const GURL& MediaStreamDevicesController::GetSecurityOrigin() const {
124 return request_->security_origin;
125 }
126
127 void MediaStreamDevicesController::Accept(const std::string& audio_id,
128 const std::string& video_id,
129 bool always_allow) {
130 content::MediaStreamDevices devices;
131 std::string audio_device, video_device;
132 if (has_audio_) {
133 AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE,
134 audio_id, &devices, &audio_device);
135 }
136 if (has_video_) {
137 AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
138 video_id, &devices, &video_device);
139 }
140 DCHECK(!devices.empty());
141
142 if (always_allow)
143 AlwaysAllowOriginAndDevices(audio_device, video_device);
144
145 callback_.Run(devices);
146 }
147
148 void MediaStreamDevicesController::Deny() {
149 callback_.Run(content::MediaStreamDevices());
150 }
151
152 void MediaStreamDevicesController::AddDeviceWithId(
153 content::MediaStreamDeviceType type,
154 const std::string& id,
155 content::MediaStreamDevices* devices,
156 std::string* device_name) {
157 DCHECK(devices);
158 content::MediaStreamDeviceMap::const_iterator device_it =
159 request_->devices.find(type);
160 if (device_it != request_->devices.end()) {
161 content::MediaStreamDevices::const_iterator it = std::find_if(
162 device_it->second.begin(), device_it->second.end(), DeviceIdEquals(id));
163 if (it != device_it->second.end()) {
164 devices->push_back(*it);
165 *device_name = it->name;
166 }
167 }
168 }
169
170 bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() {
171 return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
172 request_->security_origin, request_->security_origin,
173 CONTENT_SETTINGS_TYPE_MEDIASTREAM);
174 }
175
176 bool MediaStreamDevicesController::IsMediaDeviceBlocked() {
177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
178 ContentSetting current_setting =
179 profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
180 CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL);
181 return (current_setting == CONTENT_SETTING_BLOCK);
182 }
183
184 void MediaStreamDevicesController::AlwaysAllowOriginAndDevices(
185 const std::string& audio_device,
186 const std::string& video_device) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
188 DCHECK(!audio_device.empty() || !video_device.empty());
189 DictionaryValue* dictionary_value = new DictionaryValue();
190 if (!audio_device.empty()) {
191 dictionary_value->SetString(kAudioKey, audio_device);
192 }
193 if (!video_device.empty()) {
194 dictionary_value->SetString(kVideoKey, video_device);
195 }
196
197 ContentSettingsPattern primary_pattern =
198 ContentSettingsPattern::FromURLNoWildcard(request_->security_origin);
199 profile_->GetHostContentSettingsMap()->SetWebsiteSetting(
200 primary_pattern,
201 ContentSettingsPattern::Wildcard(),
202 CONTENT_SETTINGS_TYPE_MEDIASTREAM,
203 NO_RESOURCE_IDENTIFIER,
204 dictionary_value);
205 }
206
207 void MediaStreamDevicesController::GetAlwaysAllowedDevices(
208 std::string* audio_id, std::string* video_id) {
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
210 DCHECK(audio_id->empty());
211 DCHECK(video_id->empty());
212 // If the request is from internal objects like chrome://URLs, use the first
213 // devices on the lists.
214 if (ShouldAlwaysAllowOrigin()) {
215 if (has_audio_) {
216 *audio_id =
217 GetFirstDevice(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
218 }
219 if (has_video_) {
220 *video_id =
221 GetFirstDevice(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
222 }
223 return;
224 }
225
226 // Checks the media exceptions to get the "always allowed" devices.
227 content_settings::SettingInfo info;
228 scoped_ptr<Value> value(
229 profile_->GetHostContentSettingsMap()->GetWebsiteSetting(
230 request_->security_origin,
231 request_->security_origin,
232 CONTENT_SETTINGS_TYPE_MEDIASTREAM,
233 NO_RESOURCE_IDENTIFIER,
234 &info));
235 if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY))
236 return;
237
238 const DictionaryValue* value_dict =
239 static_cast<const DictionaryValue*>(value.get());
240 if (value_dict->empty())
241 return;
242
243 std::string audio_name, video_name;
244 value_dict->GetString(kAudioKey, &audio_name);
245 value_dict->GetString(kVideoKey, &video_name);
246
247 if (has_audio_ && !audio_name.empty()) {
248 *audio_id = GetDeviceIdByName(
249 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE, audio_name);
250 }
251 if (has_video_ && !video_name.empty()) {
252 *video_id = GetDeviceIdByName(
253 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, video_name);
254 }
255
256 return;
257 }
258
259 std::string MediaStreamDevicesController::GetDeviceIdByName(
260 content::MediaStreamDeviceType type,
261 const std::string& name) {
262 content::MediaStreamDeviceMap::const_iterator device_it =
263 request_->devices.find(type);
264 if (device_it != request_->devices.end()) {
265 content::MediaStreamDevices::const_iterator it = std::find_if(
266 device_it->second.begin(), device_it->second.end(),
267 DeviceNameEquals(name));
268 if (it != device_it->second.end())
269 return it->device_id;
270 }
271
272 // Device is not available, return an empty string.
273 return std::string();
274 }
275
276 std::string MediaStreamDevicesController::GetFirstDevice(
277 content::MediaStreamDeviceType type) {
278 content::MediaStreamDeviceMap::const_iterator device_it =
279 request_->devices.find(type);
280 if (device_it != request_->devices.end())
281 return device_it->second.begin()->device_id;
282
283 return std::string();
284 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698