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

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: addressed sky's comment and replaced "Do not allow any site to" with "Do not allow sites to" 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 has_audio_ = request_->devices.count(
66 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE) != 0;
67 has_video_ = request_->devices.count(
68 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE) != 0;
69 }
70
71 MediaStreamDevicesController::~MediaStreamDevicesController() {}
72
73 bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
74 // Deny the request if the security origin is empty, this happens with
75 // file access without |--allow-file-access-from-files| flag.
76 if (request_->security_origin.is_empty()) {
77 Deny();
78 return true;
79 }
80
81 // Deny the request and don't show the infobar if there is no devices.
82 if (!has_audio_ && !has_video_) {
83 // TODO(xians): We should detect this in a early state, and post a callback
84 // to tell the users that no device is available. Remove the code and add
85 // a DCHECK when this is done.
86 Deny();
87 return true;
88 }
89
90 // Checks if any exception has been made for this request, get the "always
91 // allowed" devices if they are available.
92 std::string audio, video;
93 GetAlwaysAllowedDevices(&audio, &video);
94 if ((has_audio_ && audio.empty()) || (has_video_ && video.empty())) {
95 // If there is no "always allowed" device for the origin, or the device is
96 // not available in the device lists, Check the default setting to see if
97 // the user has blocked the access to the media device.
98 if (IsMediaDeviceBlocked()) {
99 Deny();
100 return true;
101 }
102
103 // Show the infobar.
104 return false;
105 }
106
107 // Dismiss the infobar by selecting the "always allowed" devices.
108 Accept(audio, video, false);
109 return true;
110 }
111
112 content::MediaStreamDevices
113 MediaStreamDevicesController::GetAudioDevices() const {
114 if (!has_audio_)
115 return content::MediaStreamDevices();
116
117 content::MediaStreamDeviceMap::const_iterator it =
118 request_->devices.find(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
119 DCHECK(it != request_->devices.end());
120 return it->second;
121 }
122
123 content::MediaStreamDevices
124 MediaStreamDevicesController::GetVideoDevices() const {
125 if (!has_video_)
126 return content::MediaStreamDevices();
127
128 content::MediaStreamDeviceMap::const_iterator it =
129 request_->devices.find(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
130 DCHECK(it != request_->devices.end());
131 return it->second;
132 }
133
134 const GURL& MediaStreamDevicesController::GetSecurityOrigin() const {
135 return request_->security_origin;
136 }
137
138 void MediaStreamDevicesController::Accept(const std::string& audio_id,
139 const std::string& video_id,
140 bool always_allow) {
141 content::MediaStreamDevices devices;
142 std::string audio_device, video_device;
143 if (has_audio_) {
144 AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE,
145 audio_id, &devices, &audio_device);
146 }
147 if (has_video_) {
148 AddDeviceWithId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE,
149 video_id, &devices, &video_device);
150 }
151 DCHECK(!devices.empty());
152
153 if (always_allow)
154 AlwaysAllowOriginAndDevices(audio_device, video_device);
155
156 callback_.Run(devices);
157 }
158
159 void MediaStreamDevicesController::Deny() {
160 callback_.Run(content::MediaStreamDevices());
161 }
162
163 void MediaStreamDevicesController::AddDeviceWithId(
164 content::MediaStreamDeviceType type,
165 const std::string& id,
166 content::MediaStreamDevices* devices,
167 std::string* device_name) {
168 DCHECK(devices);
169 content::MediaStreamDeviceMap::const_iterator device_it =
170 request_->devices.find(type);
171 if (device_it == request_->devices.end())
172 return;
173
174 content::MediaStreamDevices::const_iterator it = std::find_if(
175 device_it->second.begin(), device_it->second.end(), DeviceIdEquals(id));
176 if (it == device_it->second.end())
177 return;
178
179 devices->push_back(*it);
180 *device_name = it->name;
181 }
182
183 bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() {
184 return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
185 request_->security_origin, request_->security_origin,
186 CONTENT_SETTINGS_TYPE_MEDIASTREAM);
187 }
188
189 bool MediaStreamDevicesController::IsMediaDeviceBlocked() {
190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
191 ContentSetting current_setting =
192 profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
193 CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL);
194 return (current_setting == CONTENT_SETTING_BLOCK);
195 }
196
197 void MediaStreamDevicesController::AlwaysAllowOriginAndDevices(
198 const std::string& audio_device,
199 const std::string& video_device) {
200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
201 DCHECK(!audio_device.empty() || !video_device.empty());
202 DictionaryValue* dictionary_value = new DictionaryValue();
203 if (!audio_device.empty())
204 dictionary_value->SetString(kAudioKey, audio_device);
205
206 if (!video_device.empty())
207 dictionary_value->SetString(kVideoKey, video_device);
208
209 ContentSettingsPattern primary_pattern =
210 ContentSettingsPattern::FromURLNoWildcard(request_->security_origin);
211 profile_->GetHostContentSettingsMap()->SetWebsiteSetting(
212 primary_pattern,
213 ContentSettingsPattern::Wildcard(),
214 CONTENT_SETTINGS_TYPE_MEDIASTREAM,
215 NO_RESOURCE_IDENTIFIER,
216 dictionary_value);
217 }
218
219 void MediaStreamDevicesController::GetAlwaysAllowedDevices(
220 std::string* audio_id, std::string* video_id) {
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
222 DCHECK(audio_id->empty());
223 DCHECK(video_id->empty());
224 // If the request is from internal objects like chrome://URLs, use the first
225 // devices on the lists.
226 if (ShouldAlwaysAllowOrigin()) {
227 if (has_audio_) {
228 *audio_id =
229 GetFirstDeviceId(content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE);
230 }
231 if (has_video_) {
232 *video_id =
233 GetFirstDeviceId(content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE);
234 }
235 return;
236 }
237
238 // Checks the media exceptions to get the "always allowed" devices.
239 scoped_ptr<Value> value(
240 profile_->GetHostContentSettingsMap()->GetWebsiteSetting(
241 request_->security_origin,
242 request_->security_origin,
243 CONTENT_SETTINGS_TYPE_MEDIASTREAM,
244 NO_RESOURCE_IDENTIFIER,
245 NULL));
246 if (!value.get()) {
247 NOTREACHED();
248 return;
249 }
250
251 const DictionaryValue* value_dict = NULL;
252 if (!value->GetAsDictionary(&value_dict) || value_dict->empty())
253 return;
254
255 std::string audio_name, video_name;
256 value_dict->GetString(kAudioKey, &audio_name);
257 value_dict->GetString(kVideoKey, &video_name);
258
259 if (has_audio_ && !audio_name.empty()) {
260 *audio_id = GetDeviceIdByName(
261 content::MEDIA_STREAM_DEVICE_TYPE_AUDIO_CAPTURE, audio_name);
262 }
263 if (has_video_ && !video_name.empty()) {
264 *video_id = GetDeviceIdByName(
265 content::MEDIA_STREAM_DEVICE_TYPE_VIDEO_CAPTURE, video_name);
266 }
267 }
268
269 std::string MediaStreamDevicesController::GetDeviceIdByName(
270 content::MediaStreamDeviceType type,
271 const std::string& name) {
272 content::MediaStreamDeviceMap::const_iterator device_it =
273 request_->devices.find(type);
274 if (device_it != request_->devices.end()) {
275 content::MediaStreamDevices::const_iterator it = std::find_if(
276 device_it->second.begin(), device_it->second.end(),
277 DeviceNameEquals(name));
278 if (it != device_it->second.end())
279 return it->device_id;
280 }
281
282 // Device is not available, return an empty string.
283 return std::string();
284 }
285
286 std::string MediaStreamDevicesController::GetFirstDeviceId(
287 content::MediaStreamDeviceType type) {
288 content::MediaStreamDeviceMap::const_iterator device_it =
289 request_->devices.find(type);
290 if (device_it != request_->devices.end())
291 return device_it->second.begin()->device_id;
292
293 return std::string();
294 }
OLDNEW
« no previous file with comments | « chrome/browser/media/media_stream_devices_controller.h ('k') | chrome/browser/media/media_stream_devices_menu_model.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698