OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h" | 5 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/command_line.h" |
11 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
12 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
14 #include "base/values.h" | 15 #include "base/values.h" |
15 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 16 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
16 #include "chrome/browser/content_settings/tab_specific_content_settings.h" | 17 #include "chrome/browser/content_settings/tab_specific_content_settings.h" |
17 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" | 18 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" |
18 #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" | 19 #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" |
19 #include "chrome/browser/media/webrtc/media_stream_device_permissions.h" | 20 #include "chrome/browser/media/webrtc/media_stream_device_permissions.h" |
20 #include "chrome/browser/permissions/permission_manager.h" | 21 #include "chrome/browser/permissions/permission_manager.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 | 76 |
76 return false; | 77 return false; |
77 } | 78 } |
78 | 79 |
79 using PermissionActionCallback = | 80 using PermissionActionCallback = |
80 base::Callback<void(ContentSettingsType, | 81 base::Callback<void(ContentSettingsType, |
81 PermissionRequestGestureType, | 82 PermissionRequestGestureType, |
82 const GURL&, | 83 const GURL&, |
83 Profile*)>; | 84 Profile*)>; |
84 | 85 |
85 void RecordSinglePermissionAction(const content::MediaStreamRequest& request, | 86 |
86 ContentSettingsType content_type, | 87 // Calls |action_function| for each permission requested by |request|. |
87 Profile* profile, | 88 void RecordPermissionAction(bool is_asking_for_audio, |
88 PermissionActionCallback callback) { | 89 bool is_asking_for_video, |
89 if (ContentTypeIsRequested(content_type, request)) { | 90 const GURL& security_origin, |
90 // TODO(stefanocs): Pass the actual |gesture_type| once this file has been | 91 Profile* profile, |
91 // refactored into PermissionContext. | 92 PermissionActionCallback callback) { |
92 callback.Run(content_type, PermissionRequestGestureType::UNKNOWN, | 93 // TODO(stefanocs): Pass the actual |gesture_type| once this file has been |
93 request.security_origin, profile); | 94 // refactored into PermissionContext. |
| 95 if (is_asking_for_audio) { |
| 96 callback.Run(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, |
| 97 PermissionRequestGestureType::UNKNOWN, security_origin, |
| 98 profile); |
| 99 } |
| 100 |
| 101 if (is_asking_for_video) { |
| 102 callback.Run(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, |
| 103 PermissionRequestGestureType::UNKNOWN, security_origin, |
| 104 profile); |
94 } | 105 } |
95 } | 106 } |
96 | 107 |
97 // Calls |action_function| for each permission requested by |request|. | |
98 void RecordPermissionAction(const content::MediaStreamRequest& request, | |
99 Profile* profile, | |
100 PermissionActionCallback callback) { | |
101 RecordSinglePermissionAction(request, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, | |
102 profile, callback); | |
103 RecordSinglePermissionAction( | |
104 request, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, profile, callback); | |
105 } | |
106 | |
107 #if defined(OS_ANDROID) | |
108 // Callback for the permission update infobar when the site and Chrome | |
109 // permissions are mismatched on Android. | |
110 void OnPermissionConflictResolved( | |
111 std::unique_ptr<MediaStreamDevicesController> controller, | |
112 bool allowed) { | |
113 if (allowed) | |
114 controller->PermissionGranted(); | |
115 else | |
116 controller->ForcePermissionDeniedTemporarily(); | |
117 } | |
118 | |
119 #endif // defined(OS_ANDROID) | |
120 | |
121 // This helper class helps to measure the number of media stream requests that | 108 // This helper class helps to measure the number of media stream requests that |
122 // occur. It ensures that only one request will be recorded per navigation, per | 109 // occur. It ensures that only one request will be recorded per navigation, per |
123 // frame. TODO(raymes): Remove this when https://crbug.com/526324 is fixed. | 110 // frame. TODO(raymes): Remove this when https://crbug.com/526324 is fixed. |
124 class MediaPermissionRequestLogger : content::WebContentsObserver { | 111 class MediaPermissionRequestLogger : content::WebContentsObserver { |
125 // Map of <render process id, render frame id> -> | 112 // Map of <render process id, render frame id> -> |
126 // MediaPermissionRequestLogger. | 113 // MediaPermissionRequestLogger. |
127 using RequestMap = std::map<std::pair<int, int>, | 114 using RequestMap = std::map<std::pair<int, int>, |
128 std::unique_ptr<MediaPermissionRequestLogger>>; | 115 std::unique_ptr<MediaPermissionRequestLogger>>; |
129 | 116 |
130 public: | 117 public: |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 // device id is non-empty, then the corresponding device list must not be | 186 // device id is non-empty, then the corresponding device list must not be |
200 // NULL. | 187 // NULL. |
201 if (!device_id.empty() && !devices->FindById(device_id)) | 188 if (!device_id.empty() && !devices->FindById(device_id)) |
202 return false; | 189 return false; |
203 | 190 |
204 return true; | 191 return true; |
205 } | 192 } |
206 | 193 |
207 } // namespace | 194 } // namespace |
208 | 195 |
209 // Stores whether a permission has been requested or blocked during the course | 196 namespace internal { |
210 // of a permission request, as well as the denial reason | |
211 class MediaStreamDevicesController::MediaPermissionStatus { | |
212 public: | |
213 explicit MediaPermissionStatus(const content::MediaStreamRequest& request) | |
214 : audio_requested_( | |
215 ContentTypeIsRequested(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, | |
216 request)), | |
217 video_requested_( | |
218 ContentTypeIsRequested(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, | |
219 request)) {} | |
220 | 197 |
221 ~MediaPermissionStatus() {} | 198 MediaStreamPermissionRequest::MediaStreamPermissionRequest( |
| 199 Profile* profile, |
| 200 bool is_asking_for_audio, |
| 201 bool is_asking_for_video, |
| 202 GURL security_origin, |
| 203 base::Callback<void(ContentSetting, bool)> prompt_answered_callback) |
| 204 : profile_(profile), |
| 205 is_asking_for_audio_(is_asking_for_audio), |
| 206 is_asking_for_video_(is_asking_for_video), |
| 207 security_origin_(security_origin), |
| 208 prompt_answered_callback_(prompt_answered_callback) {} |
222 | 209 |
223 bool audio_requested() const { return audio_requested_; } | 210 MediaStreamPermissionRequest::~MediaStreamPermissionRequest() { |
224 bool video_requested() const { return video_requested_; } | 211 RecordPermissionAction(is_asking_for_audio_, is_asking_for_video_, |
| 212 security_origin_, profile_, |
| 213 base::Bind(PermissionUmaUtil::PermissionIgnored)); |
| 214 } |
225 | 215 |
226 bool audio_blocked() const { return audio_blocked_; } | 216 bool MediaStreamPermissionRequest::IsAskingForAudio() const { |
227 bool video_blocked() const { return video_blocked_; } | 217 return is_asking_for_audio_; |
| 218 } |
228 | 219 |
229 content::MediaStreamRequestResult denial_reason() const { | 220 bool MediaStreamPermissionRequest::IsAskingForVideo() const { |
230 return denial_reason_; | 221 return is_asking_for_video_; |
231 } | 222 } |
232 | 223 |
233 void SetAudioBlocked(content::MediaStreamRequestResult denial_reason) { | 224 base::string16 MediaStreamPermissionRequest::GetMessageText() const { |
234 DCHECK(audio_requested_); | 225 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO; |
235 audio_blocked_ = true; | 226 if (!IsAskingForAudio()) |
236 denial_reason_ = denial_reason; | 227 message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY; |
237 } | 228 else if (!IsAskingForVideo()) |
| 229 message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY; |
| 230 return l10n_util::GetStringFUTF16( |
| 231 message_id, |
| 232 url_formatter::FormatUrlForSecurityDisplay( |
| 233 GetOrigin(), url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)); |
| 234 } |
238 | 235 |
239 void SetVideoBlocked(content::MediaStreamRequestResult denial_reason) { | 236 PermissionRequest::IconId MediaStreamPermissionRequest::GetIconId() const { |
240 DCHECK(video_requested_); | 237 #if defined(OS_ANDROID) |
241 video_blocked_ = true; | 238 return IsAskingForVideo() ? IDR_INFOBAR_MEDIA_STREAM_CAMERA |
242 denial_reason_ = denial_reason; | 239 : IDR_INFOBAR_MEDIA_STREAM_MIC; |
243 } | 240 #else |
| 241 return IsAskingForVideo() ? ui::kVideocamIcon : ui::kMicrophoneIcon; |
| 242 #endif |
| 243 } |
244 | 244 |
245 private: | 245 base::string16 MediaStreamPermissionRequest::GetMessageTextFragment() const { |
246 bool audio_requested_ = false; | 246 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_FRAGMENT; |
247 bool video_requested_ = false; | 247 if (!IsAskingForAudio()) |
248 bool audio_blocked_ = false; | 248 message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT; |
249 bool video_blocked_ = false; | 249 else if (!IsAskingForVideo()) |
| 250 message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT; |
| 251 return l10n_util::GetStringUTF16(message_id); |
| 252 } |
250 | 253 |
251 content::MediaStreamRequestResult denial_reason_ = content::MEDIA_DEVICE_OK; | 254 GURL MediaStreamPermissionRequest::GetOrigin() const { |
252 }; | 255 return security_origin_; |
| 256 } |
| 257 |
| 258 void MediaStreamPermissionRequest::PermissionGranted() { |
| 259 RecordPermissionAction(is_asking_for_audio_, is_asking_for_video_, |
| 260 security_origin_, profile_, |
| 261 base::Bind(PermissionUmaUtil::PermissionGranted)); |
| 262 prompt_answered_callback_.Run(CONTENT_SETTING_ALLOW, persist()); |
| 263 } |
| 264 |
| 265 void MediaStreamPermissionRequest::PermissionDenied() { |
| 266 RecordPermissionAction(is_asking_for_audio_, is_asking_for_video_, |
| 267 security_origin_, profile_, |
| 268 base::Bind(PermissionUmaUtil::PermissionDenied)); |
| 269 prompt_answered_callback_.Run(CONTENT_SETTING_BLOCK, persist()); |
| 270 } |
| 271 |
| 272 bool MediaStreamPermissionRequest::ShouldShowPersistenceToggle() const { |
| 273 return PermissionUtil::ShouldShowPersistenceToggle(); |
| 274 } |
| 275 |
| 276 void MediaStreamPermissionRequest::Cancelled() { |
| 277 RecordPermissionAction(is_asking_for_audio_, is_asking_for_video_, |
| 278 security_origin_, profile_, |
| 279 base::Bind(PermissionUmaUtil::PermissionDismissed)); |
| 280 prompt_answered_callback_.Run(CONTENT_SETTING_ASK, persist()); |
| 281 } |
| 282 |
| 283 void MediaStreamPermissionRequest::RequestFinished() { |
| 284 delete this; |
| 285 } |
| 286 |
| 287 PermissionRequestType MediaStreamPermissionRequest::GetPermissionRequestType() |
| 288 const { |
| 289 return PermissionRequestType::MEDIA_STREAM; |
| 290 } |
| 291 |
| 292 } // namespace internal |
253 | 293 |
254 // Implementation of PermissionPromptDelegate which actually shows a permission | 294 // Implementation of PermissionPromptDelegate which actually shows a permission |
255 // prompt. | 295 // prompt. |
256 class MediaStreamDevicesController::PermissionPromptDelegateImpl | 296 class MediaStreamDevicesController::PermissionPromptDelegateImpl |
257 : public internal::PermissionPromptDelegate { | 297 : public internal::PermissionPromptDelegate { |
258 public: | 298 public: |
259 void ShowPrompt( | 299 void ShowPrompt(bool user_gesture, |
260 bool user_gesture, | 300 content::WebContents* web_contents, |
261 content::WebContents* web_contents, | 301 std::unique_ptr<internal::MediaStreamPermissionRequest> |
262 std::unique_ptr<MediaStreamDevicesController> controller) override { | 302 request) override { |
263 #if defined(OS_ANDROID) | 303 #if defined(OS_ANDROID) |
264 PermissionUmaUtil::RecordPermissionPromptShown( | 304 PermissionUmaUtil::RecordPermissionPromptShown( |
265 controller->GetPermissionRequestType(), | 305 request->GetPermissionRequestType(), |
266 PermissionUtil::GetGestureType(user_gesture)); | 306 PermissionUtil::GetGestureType(user_gesture)); |
267 if (PermissionDialogDelegate::ShouldShowDialog(user_gesture)) { | 307 if (PermissionDialogDelegate::ShouldShowDialog(user_gesture)) { |
268 PermissionDialogDelegate::CreateMediaStreamDialog( | 308 PermissionDialogDelegate::CreateMediaStreamDialog( |
269 web_contents, user_gesture, std::move(controller)); | 309 web_contents, user_gesture, std::move(request)); |
270 } else { | 310 } else { |
271 MediaStreamInfoBarDelegateAndroid::Create(web_contents, user_gesture, | 311 MediaStreamInfoBarDelegateAndroid::Create(web_contents, user_gesture, |
272 std::move(controller)); | 312 std::move(request)); |
273 } | 313 } |
274 #else | 314 #else |
275 PermissionRequestManager* permission_request_manager = | 315 PermissionRequestManager* permission_request_manager = |
276 PermissionRequestManager::FromWebContents(web_contents); | 316 PermissionRequestManager::FromWebContents(web_contents); |
277 if (permission_request_manager) | 317 if (permission_request_manager) |
278 permission_request_manager->AddRequest(controller.release()); | 318 permission_request_manager->AddRequest(request.release()); |
279 #endif | 319 #endif |
280 } | 320 } |
281 }; | 321 }; |
282 | 322 |
283 // static | 323 // static |
284 void MediaStreamDevicesController::RequestPermissions( | 324 void MediaStreamDevicesController::RequestPermissions( |
285 const content::MediaStreamRequest& request, | 325 const content::MediaStreamRequest& request, |
286 const content::MediaResponseCallback& callback) { | 326 const content::MediaResponseCallback& callback) { |
287 PermissionPromptDelegateImpl delegate; | 327 PermissionPromptDelegateImpl delegate; |
288 RequestPermissionsWithDelegate(request, callback, &delegate); | 328 RequestPermissionsWithDelegate(request, callback, &delegate); |
289 } | 329 } |
290 | 330 |
291 // static | 331 // static |
292 void MediaStreamDevicesController::RegisterProfilePrefs( | 332 void MediaStreamDevicesController::RegisterProfilePrefs( |
293 user_prefs::PrefRegistrySyncable* prefs) { | 333 user_prefs::PrefRegistrySyncable* prefs) { |
294 prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, true); | 334 prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, true); |
295 prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, true); | 335 prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, true); |
296 prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls); | 336 prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls); |
297 prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls); | 337 prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls); |
298 } | 338 } |
299 | 339 |
300 MediaStreamDevicesController::~MediaStreamDevicesController() { | 340 MediaStreamDevicesController::~MediaStreamDevicesController() { |
301 if (!callback_.is_null()) { | 341 if (!callback_.is_null()) { |
302 RecordPermissionAction(request_, profile_, | |
303 base::Bind(PermissionUmaUtil::PermissionIgnored)); | |
304 callback_.Run(content::MediaStreamDevices(), | 342 callback_.Run(content::MediaStreamDevices(), |
305 content::MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN, | 343 content::MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN, |
306 std::unique_ptr<content::MediaStreamUI>()); | 344 std::unique_ptr<content::MediaStreamUI>()); |
307 } | 345 } |
308 } | 346 } |
309 | 347 |
310 bool MediaStreamDevicesController::IsAskingForAudio() const { | 348 bool MediaStreamDevicesController::IsAskingForAudio() const { |
311 return old_audio_setting_ == CONTENT_SETTING_ASK; | 349 return audio_setting_ == CONTENT_SETTING_ASK; |
312 } | 350 } |
313 | 351 |
314 bool MediaStreamDevicesController::IsAskingForVideo() const { | 352 bool MediaStreamDevicesController::IsAskingForVideo() const { |
315 return old_video_setting_ == CONTENT_SETTING_ASK; | 353 return video_setting_ == CONTENT_SETTING_ASK; |
316 } | 354 } |
317 | 355 |
318 base::string16 MediaStreamDevicesController::GetMessageText() const { | 356 void MediaStreamDevicesController::PromptAnswered(ContentSetting setting, |
319 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO; | 357 bool persist) { |
320 if (!IsAskingForAudio()) | 358 if (setting != CONTENT_SETTING_ALLOW) |
321 message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY; | 359 denial_reason_ = content::MEDIA_DEVICE_PERMISSION_DENIED; |
322 else if (!IsAskingForVideo()) | 360 |
323 message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY; | 361 HostContentSettingsMap* host_content_settings_map = |
324 return l10n_util::GetStringFUTF16( | 362 HostContentSettingsMapFactory::GetForProfile(profile_); |
325 message_id, | 363 if (audio_setting_ == CONTENT_SETTING_ASK) { |
326 url_formatter::FormatUrlForSecurityDisplay( | 364 if (persist) { |
327 GetOrigin(), url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)); | 365 host_content_settings_map->SetContentSettingDefaultScope( |
| 366 request_.security_origin, GURL(), |
| 367 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string(), setting); |
| 368 } |
| 369 audio_setting_ = setting; |
| 370 } |
| 371 |
| 372 if (video_setting_ == CONTENT_SETTING_ASK) { |
| 373 if (persist) { |
| 374 host_content_settings_map->SetContentSettingDefaultScope( |
| 375 request_.security_origin, GURL(), |
| 376 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string(), setting); |
| 377 } |
| 378 video_setting_ = setting; |
| 379 } |
| 380 |
| 381 RunCallback(); |
328 } | 382 } |
329 | 383 |
330 void MediaStreamDevicesController::ForcePermissionDeniedTemporarily() { | 384 void MediaStreamDevicesController::PromptAnsweredGroupedRequest( |
331 set_persist(false); | 385 const std::vector<ContentSetting>& response) { |
332 // TODO(tsergeant): Determine whether it is appropriate to record permission | 386 if (audio_setting_ == CONTENT_SETTING_ASK) |
333 // action metrics here, as this is a different sort of user action. | 387 audio_setting_ = response.front(); |
334 RunCallback(CONTENT_SETTING_BLOCK, | 388 |
335 CONTENT_SETTING_BLOCK, | 389 if (video_setting_ == CONTENT_SETTING_ASK) |
336 content::MEDIA_DEVICE_PERMISSION_DENIED); | 390 video_setting_ = response.back(); |
337 set_persist(true); | 391 |
| 392 if (audio_setting_ != CONTENT_SETTING_ALLOW && |
| 393 video_setting_ != CONTENT_SETTING_ALLOW) |
| 394 denial_reason_ = content::MEDIA_DEVICE_PERMISSION_DENIED; |
| 395 |
| 396 RunCallback(); |
338 } | 397 } |
339 | 398 |
340 PermissionRequest::IconId MediaStreamDevicesController::GetIconId() const { | 399 void MediaStreamDevicesController::AndroidOSPromptAnswered(bool allowed) { |
341 #if defined(OS_ANDROID) | 400 if (!allowed) { |
342 return IsAskingForVideo() ? IDR_INFOBAR_MEDIA_STREAM_CAMERA | 401 denial_reason_ = content::MEDIA_DEVICE_PERMISSION_DENIED; |
343 : IDR_INFOBAR_MEDIA_STREAM_MIC; | 402 if (audio_setting_ == CONTENT_SETTING_ALLOW) |
344 #else | 403 audio_setting_ = CONTENT_SETTING_BLOCK; |
345 return IsAskingForVideo() ? ui::kVideocamIcon : ui::kMicrophoneIcon; | 404 if (video_setting_ == CONTENT_SETTING_ALLOW) |
346 #endif | 405 video_setting_ = CONTENT_SETTING_BLOCK; |
| 406 } |
| 407 |
| 408 RunCallback(); |
347 } | 409 } |
348 | 410 |
349 base::string16 MediaStreamDevicesController::GetMessageTextFragment() const { | 411 void MediaStreamDevicesController::RequestFinishedNoPrompt() { |
350 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_FRAGMENT; | 412 RunCallback(); |
351 if (!IsAskingForAudio()) | |
352 message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT; | |
353 else if (!IsAskingForVideo()) | |
354 message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT; | |
355 return l10n_util::GetStringUTF16(message_id); | |
356 } | |
357 | |
358 GURL MediaStreamDevicesController::GetOrigin() const { | |
359 return request_.security_origin; | |
360 } | |
361 | |
362 void MediaStreamDevicesController::PermissionGranted() { | |
363 RecordPermissionAction(request_, profile_, | |
364 base::Bind(PermissionUmaUtil::PermissionGranted)); | |
365 RunCallback(GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, | |
366 old_audio_setting_, CONTENT_SETTING_ALLOW), | |
367 GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, | |
368 old_video_setting_, CONTENT_SETTING_ALLOW), | |
369 content::MEDIA_DEVICE_PERMISSION_DENIED); | |
370 } | |
371 | |
372 void MediaStreamDevicesController::PermissionDenied() { | |
373 RecordPermissionAction(request_, profile_, | |
374 base::Bind(PermissionUmaUtil::PermissionDenied)); | |
375 RunCallback(GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, | |
376 old_audio_setting_, CONTENT_SETTING_BLOCK), | |
377 GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, | |
378 old_video_setting_, CONTENT_SETTING_BLOCK), | |
379 content::MEDIA_DEVICE_PERMISSION_DENIED); | |
380 } | |
381 | |
382 bool MediaStreamDevicesController::ShouldShowPersistenceToggle() const { | |
383 return PermissionUtil::ShouldShowPersistenceToggle(); | |
384 } | |
385 | |
386 void MediaStreamDevicesController::Cancelled() { | |
387 RecordPermissionAction(request_, profile_, | |
388 base::Bind(PermissionUmaUtil::PermissionDismissed)); | |
389 RunCallback(old_audio_setting_, old_video_setting_, | |
390 content::MEDIA_DEVICE_PERMISSION_DISMISSED); | |
391 } | |
392 | |
393 void MediaStreamDevicesController::RequestFinished() { | |
394 delete this; | |
395 } | |
396 | |
397 PermissionRequestType MediaStreamDevicesController::GetPermissionRequestType() | |
398 const { | |
399 return PermissionRequestType::MEDIA_STREAM; | |
400 } | 413 } |
401 | 414 |
402 // static | 415 // static |
403 void MediaStreamDevicesController::RequestPermissionsWithDelegate( | 416 void MediaStreamDevicesController::RequestPermissionsWithDelegate( |
404 const content::MediaStreamRequest& request, | 417 const content::MediaStreamRequest& request, |
405 const content::MediaResponseCallback& callback, | 418 const content::MediaResponseCallback& callback, |
406 internal::PermissionPromptDelegate* delegate) { | 419 internal::PermissionPromptDelegate* delegate) { |
| 420 content::RenderFrameHost* rfh = content::RenderFrameHost::FromID( |
| 421 request.render_process_id, request.render_frame_id); |
407 content::WebContents* web_contents = | 422 content::WebContents* web_contents = |
408 content::WebContents::FromRenderFrameHost( | 423 content::WebContents::FromRenderFrameHost(rfh); |
409 content::RenderFrameHost::FromID(request.render_process_id, | |
410 request.render_frame_id)); | |
411 if (request.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY) { | 424 if (request.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY) { |
412 MediaPermissionRequestLogger::LogRequest( | 425 MediaPermissionRequestLogger::LogRequest( |
413 web_contents, request.render_process_id, request.render_frame_id, | 426 web_contents, request.render_process_id, request.render_frame_id, |
414 content::IsOriginSecure(request.security_origin)); | 427 content::IsOriginSecure(request.security_origin)); |
415 } | 428 } |
416 | 429 |
417 MediaPermissionStatus initial_permission(request); | 430 std::unique_ptr<MediaStreamDevicesController> controller( |
418 if (initial_permission.audio_requested() && | 431 new MediaStreamDevicesController(web_contents, request, callback)); |
419 !HasAvailableDevices(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, | |
420 request.requested_audio_device_id)) { | |
421 initial_permission.SetAudioBlocked(content::MEDIA_DEVICE_NO_HARDWARE); | |
422 } | |
423 | 432 |
424 if (initial_permission.video_requested() && | 433 #if defined(OS_ANDROID) |
425 !HasAvailableDevices(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, | |
426 request.requested_video_device_id)) { | |
427 initial_permission.SetVideoBlocked(content::MEDIA_DEVICE_NO_HARDWARE); | |
428 } | |
429 | |
430 std::unique_ptr<MediaStreamDevicesController> controller( | |
431 new MediaStreamDevicesController(web_contents, request, callback, | |
432 initial_permission)); | |
433 if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) { | 434 if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) { |
434 #if defined(OS_ANDROID) | |
435 // If either audio or video was previously allowed and Chrome no longer has | 435 // If either audio or video was previously allowed and Chrome no longer has |
436 // the necessary permissions, show a infobar to attempt to address this | 436 // the necessary permissions, show a infobar to attempt to address this |
437 // mismatch. | 437 // mismatch. |
438 std::vector<ContentSettingsType> content_settings_types; | 438 std::vector<ContentSettingsType> content_settings_types; |
439 if (controller->IsAllowedForAudio()) | 439 if (controller->IsAllowedForAudio()) |
440 content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); | 440 content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); |
441 | 441 |
442 if (controller->IsAllowedForVideo()) { | 442 if (controller->IsAllowedForVideo()) { |
443 content_settings_types.push_back( | 443 content_settings_types.push_back( |
444 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); | 444 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
445 } | 445 } |
446 if (!content_settings_types.empty() && | 446 if (!content_settings_types.empty() && |
447 PermissionUpdateInfoBarDelegate::ShouldShowPermissionInfobar( | 447 PermissionUpdateInfoBarDelegate::ShouldShowPermissionInfobar( |
448 web_contents, content_settings_types)) { | 448 web_contents, content_settings_types)) { |
449 PermissionUpdateInfoBarDelegate::Create( | 449 PermissionUpdateInfoBarDelegate::Create( |
450 web_contents, content_settings_types, | 450 web_contents, content_settings_types, |
451 base::Bind(&OnPermissionConflictResolved, base::Passed(&controller))); | 451 base::Bind(&AndroidOSPromptAnswered, base::Passed(&controller))); |
| 452 return; |
452 } | 453 } |
| 454 } |
453 #endif | 455 #endif |
454 return; | 456 |
| 457 Profile* profile = |
| 458 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 459 if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) { |
| 460 controller->RequestFinishedNoPrompt(); |
| 461 } else { |
| 462 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 463 switches::kEnableGroupedMediaPermissionPrompts)) { |
| 464 std::vector<ContentSettingsType> content_settings_types; |
| 465 |
| 466 if (controller->IsAskingForAudio()) |
| 467 content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); |
| 468 if (controller->IsAskingForVideo()) { |
| 469 content_settings_types.push_back( |
| 470 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
| 471 } |
| 472 |
| 473 LOG(ERROR) << content_settings_types.size(); |
| 474 |
| 475 PermissionManager::Get(profile)->RequestPermissions( |
| 476 content_settings_types, rfh, request.security_origin, |
| 477 request.user_gesture, |
| 478 base::Bind( |
| 479 &MediaStreamDevicesController::PromptAnsweredGroupedRequest, |
| 480 base::Passed(&controller))); |
| 481 } else { |
| 482 delegate->ShowPrompt( |
| 483 request.user_gesture, web_contents, |
| 484 base::MakeUnique<internal::MediaStreamPermissionRequest>( |
| 485 profile, controller->IsAskingForAudio(), |
| 486 controller->IsAskingForVideo(), request.security_origin, |
| 487 base::Bind(&MediaStreamDevicesController::PromptAnswered, |
| 488 base::Passed(&controller)))); |
| 489 } |
455 } | 490 } |
456 | |
457 delegate->ShowPrompt(request.user_gesture, web_contents, | |
458 std::move(controller)); | |
459 } | 491 } |
460 | 492 |
461 MediaStreamDevicesController::MediaStreamDevicesController( | 493 MediaStreamDevicesController::MediaStreamDevicesController( |
462 content::WebContents* web_contents, | 494 content::WebContents* web_contents, |
463 const content::MediaStreamRequest& request, | 495 const content::MediaStreamRequest& request, |
464 const content::MediaResponseCallback& callback, | 496 const content::MediaResponseCallback& callback) |
465 const MediaPermissionStatus& initial_permission) | |
466 : web_contents_(web_contents), request_(request), callback_(callback) { | 497 : web_contents_(web_contents), request_(request), callback_(callback) { |
467 profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 498 profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
468 content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents); | 499 content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents); |
469 | 500 |
470 content::MediaStreamRequestResult denial_reason = | 501 denial_reason_ = content::MEDIA_DEVICE_OK; |
471 initial_permission.denial_reason(); | 502 audio_setting_ = GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, |
472 old_audio_setting_ = | 503 request, &denial_reason_); |
473 GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, request, | 504 video_setting_ = GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, |
474 initial_permission.audio_requested(), | 505 request, &denial_reason_); |
475 initial_permission.audio_blocked(), &denial_reason); | |
476 old_video_setting_ = | |
477 GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, request, | |
478 initial_permission.video_requested(), | |
479 initial_permission.video_blocked(), &denial_reason); | |
480 | |
481 // If either setting is ask, we show the infobar. | |
482 if (old_audio_setting_ == CONTENT_SETTING_ASK || | |
483 old_video_setting_ == CONTENT_SETTING_ASK) { | |
484 return; | |
485 } | |
486 | |
487 #if defined(OS_ANDROID) | |
488 std::vector<ContentSettingsType> content_settings_types; | |
489 if (IsAllowedForAudio()) | |
490 content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); | |
491 | |
492 if (IsAllowedForVideo()) { | |
493 content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); | |
494 } | |
495 | |
496 // If the site had been previously granted the access to audio or video but | |
497 // Chrome is now missing the necessary permission, we need to show an infobar | |
498 // to resolve the difference. | |
499 if (!content_settings_types.empty() && | |
500 PermissionUpdateInfoBarDelegate::ShouldShowPermissionInfobar( | |
501 web_contents, content_settings_types)) { | |
502 return; | |
503 } | |
504 #endif | |
505 | |
506 // Otherwise we can run the callback immediately. | |
507 RunCallback(old_audio_setting_, old_video_setting_, denial_reason); | |
508 } | 506 } |
509 | 507 |
510 bool MediaStreamDevicesController::IsAllowedForAudio() const { | 508 bool MediaStreamDevicesController::IsAllowedForAudio() const { |
511 return old_audio_setting_ == CONTENT_SETTING_ALLOW; | 509 return audio_setting_ == CONTENT_SETTING_ALLOW; |
512 } | 510 } |
513 | 511 |
514 bool MediaStreamDevicesController::IsAllowedForVideo() const { | 512 bool MediaStreamDevicesController::IsAllowedForVideo() const { |
515 return old_video_setting_ == CONTENT_SETTING_ALLOW; | 513 return video_setting_ == CONTENT_SETTING_ALLOW; |
516 } | 514 } |
517 | 515 |
518 content::MediaStreamDevices MediaStreamDevicesController::GetDevices( | 516 content::MediaStreamDevices MediaStreamDevicesController::GetDevices( |
519 ContentSetting audio_setting, | 517 ContentSetting audio_setting, |
520 ContentSetting video_setting) { | 518 ContentSetting video_setting) { |
521 bool audio_allowed = audio_setting == CONTENT_SETTING_ALLOW; | 519 bool audio_allowed = audio_setting == CONTENT_SETTING_ALLOW; |
522 bool video_allowed = video_setting == CONTENT_SETTING_ALLOW; | 520 bool video_allowed = video_setting == CONTENT_SETTING_ALLOW; |
523 | 521 |
524 if (!audio_allowed && !video_allowed) | 522 if (!audio_allowed && !video_allowed) |
525 return content::MediaStreamDevices(); | 523 return content::MediaStreamDevices(); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // Get the default devices for the request. | 595 // Get the default devices for the request. |
598 MediaCaptureDevicesDispatcher::GetInstance()->GetDefaultDevicesForProfile( | 596 MediaCaptureDevicesDispatcher::GetInstance()->GetDefaultDevicesForProfile( |
599 profile_, audio_allowed, video_allowed, &devices); | 597 profile_, audio_allowed, video_allowed, &devices); |
600 break; | 598 break; |
601 } | 599 } |
602 } // switch | 600 } // switch |
603 | 601 |
604 return devices; | 602 return devices; |
605 } | 603 } |
606 | 604 |
607 void MediaStreamDevicesController::RunCallback( | 605 void MediaStreamDevicesController::RunCallback() { |
608 ContentSetting audio_setting, | |
609 ContentSetting video_setting, | |
610 content::MediaStreamRequestResult denial_reason) { | |
611 CHECK(!callback_.is_null()); | 606 CHECK(!callback_.is_null()); |
612 | 607 |
613 // If the kill switch is on we don't update the tab context or persist the | 608 // If the kill switch is on we don't update the tab context. |
614 // setting. | 609 if (denial_reason_ != content::MEDIA_DEVICE_KILL_SWITCH_ON) |
615 if (denial_reason != content::MEDIA_DEVICE_KILL_SWITCH_ON) { | 610 UpdateTabSpecificContentSettings(audio_setting_, video_setting_); |
616 if (persist()) | |
617 StorePermission(audio_setting, video_setting); | |
618 UpdateTabSpecificContentSettings(audio_setting, video_setting); | |
619 } | |
620 | 611 |
621 content::MediaStreamDevices devices = | 612 content::MediaStreamDevices devices = |
622 GetDevices(audio_setting, video_setting); | 613 GetDevices(audio_setting_, video_setting_); |
623 | 614 |
624 // If either audio or video are allowed then the callback should report | 615 // If either audio or video are allowed then the callback should report |
625 // success, otherwise we report |denial_reason|. | 616 // success, otherwise we report |denial_reason_|. |
626 content::MediaStreamRequestResult request_result = content::MEDIA_DEVICE_OK; | 617 if (audio_setting_ != CONTENT_SETTING_ALLOW && |
627 if (audio_setting != CONTENT_SETTING_ALLOW && | 618 video_setting_ != CONTENT_SETTING_ALLOW) { |
628 video_setting != CONTENT_SETTING_ALLOW) { | 619 DCHECK_NE(content::MEDIA_DEVICE_OK, denial_reason_); |
629 DCHECK_NE(content::MEDIA_DEVICE_OK, denial_reason); | |
630 request_result = denial_reason; | |
631 } else if (devices.empty()) { | 620 } else if (devices.empty()) { |
632 // Even if one of the content settings was allowed, if there are no devices | 621 // Even if one of the content settings was allowed, if there are no devices |
633 // at this point we still report a failure. | 622 // at this point we still report a failure. |
634 request_result = content::MEDIA_DEVICE_NO_HARDWARE; | 623 denial_reason_ = content::MEDIA_DEVICE_NO_HARDWARE; |
635 } | 624 } |
636 | 625 |
637 std::unique_ptr<content::MediaStreamUI> ui; | 626 std::unique_ptr<content::MediaStreamUI> ui; |
638 if (!devices.empty()) { | 627 if (!devices.empty()) { |
639 ui = MediaCaptureDevicesDispatcher::GetInstance() | 628 ui = MediaCaptureDevicesDispatcher::GetInstance() |
640 ->GetMediaStreamCaptureIndicator() | 629 ->GetMediaStreamCaptureIndicator() |
641 ->RegisterMediaStream(web_contents_, devices); | 630 ->RegisterMediaStream(web_contents_, devices); |
642 } | 631 } |
643 base::ResetAndReturn(&callback_).Run(devices, request_result, std::move(ui)); | 632 base::ResetAndReturn(&callback_).Run(devices, denial_reason_, std::move(ui)); |
644 } | |
645 | |
646 void MediaStreamDevicesController::StorePermission( | |
647 ContentSetting new_audio_setting, | |
648 ContentSetting new_video_setting) const { | |
649 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
650 DCHECK(content::IsOriginSecure(request_.security_origin) || | |
651 request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY); | |
652 | |
653 if (IsAskingForAudio() && new_audio_setting != CONTENT_SETTING_ASK) { | |
654 HostContentSettingsMapFactory::GetForProfile(profile_) | |
655 ->SetContentSettingDefaultScope(request_.security_origin, GURL(), | |
656 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, | |
657 std::string(), new_audio_setting); | |
658 } | |
659 if (IsAskingForVideo() && new_video_setting != CONTENT_SETTING_ASK) { | |
660 HostContentSettingsMapFactory::GetForProfile(profile_) | |
661 ->SetContentSettingDefaultScope( | |
662 request_.security_origin, GURL(), | |
663 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string(), | |
664 new_video_setting); | |
665 } | |
666 } | 633 } |
667 | 634 |
668 void MediaStreamDevicesController::UpdateTabSpecificContentSettings( | 635 void MediaStreamDevicesController::UpdateTabSpecificContentSettings( |
669 ContentSetting audio_setting, | 636 ContentSetting audio_setting, |
670 ContentSetting video_setting) const { | 637 ContentSetting video_setting) const { |
671 if (!content_settings_) | 638 if (!content_settings_) |
672 return; | 639 return; |
673 | 640 |
674 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state = | 641 TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state = |
675 TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED; | 642 TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 } | 674 } |
708 | 675 |
709 content_settings_->OnMediaStreamPermissionSet( | 676 content_settings_->OnMediaStreamPermissionSet( |
710 request_.security_origin, microphone_camera_state, selected_audio_device, | 677 request_.security_origin, microphone_camera_state, selected_audio_device, |
711 selected_video_device, requested_audio_device, requested_video_device); | 678 selected_video_device, requested_audio_device, requested_video_device); |
712 } | 679 } |
713 | 680 |
714 ContentSetting MediaStreamDevicesController::GetContentSetting( | 681 ContentSetting MediaStreamDevicesController::GetContentSetting( |
715 ContentSettingsType content_type, | 682 ContentSettingsType content_type, |
716 const content::MediaStreamRequest& request, | 683 const content::MediaStreamRequest& request, |
717 bool was_requested, | |
718 bool was_initially_blocked, | |
719 content::MediaStreamRequestResult* denial_reason) const { | 684 content::MediaStreamRequestResult* denial_reason) const { |
720 DCHECK(content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || | 685 DCHECK(content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || |
721 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); | 686 content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
722 DCHECK(!request_.security_origin.is_empty()); | 687 DCHECK(!request_.security_origin.is_empty()); |
723 DCHECK(content::IsOriginSecure(request_.security_origin) || | 688 DCHECK(content::IsOriginSecure(request_.security_origin) || |
724 request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY); | 689 request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY); |
725 if (!was_requested) { | 690 if (!ContentTypeIsRequested(content_type, request)) { |
726 // No denial reason set as it will have been previously set. | 691 // No denial reason set as it will have been previously set. |
727 return CONTENT_SETTING_DEFAULT; | 692 return CONTENT_SETTING_DEFAULT; |
728 } | 693 } |
729 | 694 |
730 if (was_initially_blocked) { | 695 std::string device_id; |
731 // No denial reason set as it will have been previously set. | 696 if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) |
| 697 device_id = request.requested_audio_device_id; |
| 698 else |
| 699 device_id = request.requested_video_device_id; |
| 700 if (!HasAvailableDevices(content_type, device_id)) { |
| 701 *denial_reason = content::MEDIA_DEVICE_NO_HARDWARE; |
732 return CONTENT_SETTING_BLOCK; | 702 return CONTENT_SETTING_BLOCK; |
733 } | 703 } |
734 | 704 |
735 if (!IsUserAcceptAllowed(content_type)) { | 705 if (!IsUserAcceptAllowed(content_type)) { |
736 *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; | 706 *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; |
737 return CONTENT_SETTING_BLOCK; | 707 return CONTENT_SETTING_BLOCK; |
738 } | 708 } |
739 | 709 |
740 PermissionResult result = | 710 PermissionResult result = |
741 PermissionManager::Get(profile_)->GetPermissionStatus( | 711 PermissionManager::Get(profile_)->GetPermissionStatus( |
742 content_type, request.security_origin, | 712 content_type, request.security_origin, |
743 web_contents_->GetLastCommittedURL().GetOrigin()); | 713 web_contents_->GetLastCommittedURL().GetOrigin()); |
744 if (result.content_setting == CONTENT_SETTING_BLOCK) { | 714 if (result.content_setting == CONTENT_SETTING_BLOCK) { |
745 *denial_reason = (result.source == PermissionStatusSource::KILL_SWITCH) | 715 *denial_reason = (result.source == PermissionStatusSource::KILL_SWITCH) |
746 ? content::MEDIA_DEVICE_KILL_SWITCH_ON | 716 ? content::MEDIA_DEVICE_KILL_SWITCH_ON |
747 : content::MEDIA_DEVICE_PERMISSION_DENIED; | 717 : content::MEDIA_DEVICE_PERMISSION_DENIED; |
748 } | 718 } |
749 | 719 |
750 return result.content_setting; | 720 return result.content_setting; |
751 } | 721 } |
752 | 722 |
753 ContentSetting MediaStreamDevicesController::GetNewSetting( | |
754 ContentSettingsType content_type, | |
755 ContentSetting old_setting, | |
756 ContentSetting user_decision) const { | |
757 DCHECK(user_decision == CONTENT_SETTING_ALLOW || | |
758 user_decision == CONTENT_SETTING_BLOCK); | |
759 ContentSetting result = old_setting; | |
760 if (old_setting == CONTENT_SETTING_ASK) | |
761 result = user_decision; | |
762 return result; | |
763 } | |
764 | |
765 bool MediaStreamDevicesController::IsUserAcceptAllowed( | 723 bool MediaStreamDevicesController::IsUserAcceptAllowed( |
766 ContentSettingsType content_type) const { | 724 ContentSettingsType content_type) const { |
767 #if defined(OS_ANDROID) | 725 #if defined(OS_ANDROID) |
768 content::ContentViewCore* cvc = | 726 content::ContentViewCore* cvc = |
769 content::ContentViewCore::FromWebContents(web_contents_); | 727 content::ContentViewCore::FromWebContents(web_contents_); |
770 if (!cvc) | 728 if (!cvc) |
771 return false; | 729 return false; |
772 | 730 |
773 ui::WindowAndroid* window_android = cvc->GetWindowAndroid(); | 731 ui::WindowAndroid* window_android = cvc->GetWindowAndroid(); |
774 if (!window_android) | 732 if (!window_android) |
775 return false; | 733 return false; |
776 | 734 |
777 std::vector<std::string> android_permissions; | 735 std::vector<std::string> android_permissions; |
778 PrefServiceBridge::GetAndroidPermissionsForContentSetting( | 736 PrefServiceBridge::GetAndroidPermissionsForContentSetting( |
779 content_type, &android_permissions); | 737 content_type, &android_permissions); |
780 for (const auto& android_permission : android_permissions) { | 738 for (const auto& android_permission : android_permissions) { |
781 if (!window_android->HasPermission(android_permission) && | 739 if (!window_android->HasPermission(android_permission) && |
782 !window_android->CanRequestPermission(android_permission)) { | 740 !window_android->CanRequestPermission(android_permission)) { |
783 return false; | 741 return false; |
784 } | 742 } |
785 } | 743 } |
786 | 744 |
787 // Don't approve device requests if the tab was hidden. | 745 // Don't approve device requests if the tab was hidden. |
788 // TODO(qinmin): Add a test for this. http://crbug.com/396869. | 746 // TODO(qinmin): Add a test for this. http://crbug.com/396869. |
789 // TODO(raymes): Shouldn't this apply to all permissions not just audio/video? | 747 // TODO(raymes): Shouldn't this apply to all permissions not just audio/video? |
790 return web_contents_->GetRenderWidgetHostView()->IsShowing(); | 748 return web_contents_->GetRenderWidgetHostView()->IsShowing(); |
791 #endif | 749 #endif |
792 return true; | 750 return true; |
793 } | 751 } |
OLD | NEW |