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

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

Issue 1362803002: Add logic to resolve permission mismatches in Android M for webrtc. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 5 years, 2 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
OLDNEW
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/media_stream_devices_controller.h" 5 #include "chrome/browser/media/media_stream_devices_controller.h"
6 6
7 #include "base/auto_reset.h"
8 #include "base/callback_helpers.h"
7 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
8 #include "base/prefs/scoped_user_pref_update.h" 10 #include "base/prefs/scoped_user_pref_update.h"
9 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h" 12 #include "base/values.h"
11 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 13 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
12 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 14 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
13 #include "chrome/browser/media/media_capture_devices_dispatcher.h" 15 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
14 #include "chrome/browser/media/media_permission.h" 16 #include "chrome/browser/media/media_permission.h"
15 #include "chrome/browser/media/media_stream_capture_indicator.h" 17 #include "chrome/browser/media/media_stream_capture_indicator.h"
16 #include "chrome/browser/media/media_stream_device_permissions.h" 18 #include "chrome/browser/media/media_stream_device_permissions.h"
17 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h" 20 #include "chrome/browser/ui/browser.h"
19 #include "chrome/common/chrome_switches.h" 21 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/pref_names.h" 22 #include "chrome/common/pref_names.h"
21 #include "chrome/grit/generated_resources.h" 23 #include "chrome/grit/generated_resources.h"
22 #include "components/content_settings/core/browser/host_content_settings_map.h" 24 #include "components/content_settings/core/browser/host_content_settings_map.h"
23 #include "components/content_settings/core/common/content_settings_pattern.h" 25 #include "components/content_settings/core/common/content_settings_pattern.h"
24 #include "components/pref_registry/pref_registry_syncable.h" 26 #include "components/pref_registry/pref_registry_syncable.h"
25 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/render_widget_host_view.h" 28 #include "content/public/browser/render_widget_host_view.h"
27 #include "content/public/common/media_stream_request.h" 29 #include "content/public/common/media_stream_request.h"
28 #include "content/public/common/origin_util.h" 30 #include "content/public/common/origin_util.h"
29 #include "extensions/common/constants.h" 31 #include "extensions/common/constants.h"
30 #include "grit/theme_resources.h" 32 #include "grit/theme_resources.h"
31 #include "ui/base/l10n/l10n_util.h" 33 #include "ui/base/l10n/l10n_util.h"
32 34
33 #if defined(OS_ANDROID) 35 #if defined(OS_ANDROID)
36 #include <vector>
37
34 #include "chrome/browser/android/preferences/pref_service_bridge.h" 38 #include "chrome/browser/android/preferences/pref_service_bridge.h"
39 #include "chrome/browser/permissions/permission_update_infobar_delegate_android. h"
35 #include "content/public/browser/android/content_view_core.h" 40 #include "content/public/browser/android/content_view_core.h"
36 #include "ui/android/window_android.h" 41 #include "ui/android/window_android.h"
37 #endif // OS_ANDROID 42 #endif // OS_ANDROID
38 43
39 using content::BrowserThread; 44 using content::BrowserThread;
40 45
41 namespace { 46 namespace {
42 47
43 enum DevicePermissionActions { 48 enum DevicePermissionActions {
44 kAllowHttps = 0, 49 kAllowHttps = 0,
(...skipping 20 matching lines...) Expand all
65 } 70 }
66 71
67 } // namespace 72 } // namespace
68 73
69 MediaStreamDevicesController::MediaStreamDevicesController( 74 MediaStreamDevicesController::MediaStreamDevicesController(
70 content::WebContents* web_contents, 75 content::WebContents* web_contents,
71 const content::MediaStreamRequest& request, 76 const content::MediaStreamRequest& request,
72 const content::MediaResponseCallback& callback) 77 const content::MediaResponseCallback& callback)
73 : web_contents_(web_contents), 78 : web_contents_(web_contents),
74 request_(request), 79 request_(request),
75 callback_(callback) { 80 callback_(callback),
81 persist_permission_changes_(true) {
76 if (request_.request_type == content::MEDIA_OPEN_DEVICE) { 82 if (request_.request_type == content::MEDIA_OPEN_DEVICE) {
77 UMA_HISTOGRAM_BOOLEAN("Pepper.SecureOrigin.MediaStreamRequest", 83 UMA_HISTOGRAM_BOOLEAN("Pepper.SecureOrigin.MediaStreamRequest",
78 content::IsOriginSecure(request_.security_origin)); 84 content::IsOriginSecure(request_.security_origin));
79 } 85 }
80 profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); 86 profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
81 content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents); 87 content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents);
82 88
83 content::MediaStreamRequestResult denial_reason = content::MEDIA_DEVICE_OK; 89 content::MediaStreamRequestResult denial_reason = content::MEDIA_DEVICE_OK;
84 old_audio_setting_ = GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 90 old_audio_setting_ = GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
85 request_, &denial_reason); 91 request_, &denial_reason);
86 old_video_setting_ = GetContentSetting( 92 old_video_setting_ = GetContentSetting(
87 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, request_, &denial_reason); 93 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, request_, &denial_reason);
88 94
89 // If either setting is ask, we show the infobar. 95 // If either setting is ask, we show the infobar.
90 if (old_audio_setting_ == CONTENT_SETTING_ASK || 96 if (old_audio_setting_ == CONTENT_SETTING_ASK ||
91 old_video_setting_ == CONTENT_SETTING_ASK) { 97 old_video_setting_ == CONTENT_SETTING_ASK) {
92 return; 98 return;
93 } 99 }
94 100
101 #if defined(OS_ANDROID)
102 std::vector<ContentSettingsType> content_settings_types;
103 if (IsAllowedForAudio())
104 content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
105 if (IsAllowedForVideo()) {
tommi (sloooow) - chröme 2015/09/29 14:49:48 nit: empty line above this one for readability.
Ted C 2015/09/29 21:25:30 Done.
106 content_settings_types.push_back(
107 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
108 }
109
110 // If the site had been previously granted the access to audio or video but
111 // Chrome is now missing the necessary permission, we need to show an infobar
112 // to resolve the difference.
113 if (!content_settings_types.empty() &&
114 PermissionUpdateInfoBarDelegate::ShouldShowPermissionInfobar(
115 web_contents, content_settings_types)) {
116 return;
117 }
118 #endif
119
95 // Otherwise we can run the callback immediately. 120 // Otherwise we can run the callback immediately.
96 RunCallback(old_audio_setting_, old_video_setting_, denial_reason); 121 RunCallback(old_audio_setting_, old_video_setting_, denial_reason);
97 } 122 }
98 123
99 MediaStreamDevicesController::~MediaStreamDevicesController() { 124 MediaStreamDevicesController::~MediaStreamDevicesController() {
100 if (!callback_.is_null()) { 125 if (!callback_.is_null()) {
101 callback_.Run(content::MediaStreamDevices(), 126 callback_.Run(content::MediaStreamDevices(),
102 content::MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN, 127 content::MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN,
103 scoped_ptr<content::MediaStreamUI>()); 128 scoped_ptr<content::MediaStreamUI>());
104 } 129 }
105 } 130 }
106 131
107 // static 132 // static
108 void MediaStreamDevicesController::RegisterProfilePrefs( 133 void MediaStreamDevicesController::RegisterProfilePrefs(
109 user_prefs::PrefRegistrySyncable* prefs) { 134 user_prefs::PrefRegistrySyncable* prefs) {
110 prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, true); 135 prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, true);
111 prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, true); 136 prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, true);
112 prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls); 137 prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls);
113 prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls); 138 prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls);
114 } 139 }
115 140
141 bool MediaStreamDevicesController::IsAllowedForAudio() const {
142 return old_audio_setting_ == CONTENT_SETTING_ALLOW;
143 }
144
145 bool MediaStreamDevicesController::IsAllowedForVideo() const {
146 return old_video_setting_ == CONTENT_SETTING_ALLOW;
147 }
148
116 bool MediaStreamDevicesController::IsAskingForAudio() const { 149 bool MediaStreamDevicesController::IsAskingForAudio() const {
117 return old_audio_setting_ == CONTENT_SETTING_ASK; 150 return old_audio_setting_ == CONTENT_SETTING_ASK;
118 } 151 }
119 152
120 bool MediaStreamDevicesController::IsAskingForVideo() const { 153 bool MediaStreamDevicesController::IsAskingForVideo() const {
121 return old_video_setting_ == CONTENT_SETTING_ASK; 154 return old_video_setting_ == CONTENT_SETTING_ASK;
122 } 155 }
123 156
124 const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const { 157 const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
125 return request_.security_origin.spec(); 158 return request_.security_origin.spec();
126 } 159 }
127 160
161 void MediaStreamDevicesController::ForcePermissionDeniedTemporarily() {
162 base::AutoReset<bool> persist_permissions(
163 &persist_permission_changes_, false);
164 UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
165 kDeny, kPermissionActionsMax);
166 RunCallback(CONTENT_SETTING_BLOCK,
167 CONTENT_SETTING_BLOCK,
168 content::MEDIA_DEVICE_PERMISSION_DENIED);
169 }
170
128 int MediaStreamDevicesController::GetIconId() const { 171 int MediaStreamDevicesController::GetIconId() const {
129 if (IsAskingForVideo()) 172 if (IsAskingForVideo())
130 return IDR_INFOBAR_MEDIA_STREAM_CAMERA; 173 return IDR_INFOBAR_MEDIA_STREAM_CAMERA;
131 174
132 return IDR_INFOBAR_MEDIA_STREAM_MIC; 175 return IDR_INFOBAR_MEDIA_STREAM_MIC;
133 } 176 }
134 177
135 base::string16 MediaStreamDevicesController::GetMessageText() const { 178 base::string16 MediaStreamDevicesController::GetMessageText() const {
136 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO; 179 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO;
137 if (!IsAskingForAudio()) 180 if (!IsAskingForAudio())
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); 345 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
303 } 346 }
304 347
305 return devices; 348 return devices;
306 } 349 }
307 350
308 void MediaStreamDevicesController::RunCallback( 351 void MediaStreamDevicesController::RunCallback(
309 ContentSetting audio_setting, 352 ContentSetting audio_setting,
310 ContentSetting video_setting, 353 ContentSetting video_setting,
311 content::MediaStreamRequestResult denial_reason) { 354 content::MediaStreamRequestResult denial_reason) {
312 StorePermission(audio_setting, video_setting); 355 CHECK(!callback_.is_null());
313 UpdateTabSpecificContentSettings(audio_setting, video_setting); 356
357 if (persist_permission_changes_) {
358 StorePermission(audio_setting, video_setting);
359 UpdateTabSpecificContentSettings(audio_setting, video_setting);
360 }
314 361
315 content::MediaStreamDevices devices = 362 content::MediaStreamDevices devices =
316 GetDevices(audio_setting, video_setting); 363 GetDevices(audio_setting, video_setting);
317 364
318 // If either audio or video are allowed then the callback should report 365 // If either audio or video are allowed then the callback should report
319 // success, otherwise we report |denial_reason|. 366 // success, otherwise we report |denial_reason|.
320 content::MediaStreamRequestResult request_result = content::MEDIA_DEVICE_OK; 367 content::MediaStreamRequestResult request_result = content::MEDIA_DEVICE_OK;
321 if (audio_setting != CONTENT_SETTING_ALLOW && 368 if (audio_setting != CONTENT_SETTING_ALLOW &&
322 video_setting != CONTENT_SETTING_ALLOW) { 369 video_setting != CONTENT_SETTING_ALLOW) {
323 DCHECK_NE(content::MEDIA_DEVICE_OK, denial_reason); 370 DCHECK_NE(content::MEDIA_DEVICE_OK, denial_reason);
324 request_result = denial_reason; 371 request_result = denial_reason;
325 } else if (devices.empty()) { 372 } else if (devices.empty()) {
326 // Even if one of the content settings was allowed, if there are no devices 373 // Even if one of the content settings was allowed, if there are no devices
327 // at this point we still report a failure. 374 // at this point we still report a failure.
328 request_result = content::MEDIA_DEVICE_NO_HARDWARE; 375 request_result = content::MEDIA_DEVICE_NO_HARDWARE;
329 } 376 }
330 377
331 scoped_ptr<content::MediaStreamUI> ui; 378 scoped_ptr<content::MediaStreamUI> ui;
332 if (!devices.empty()) { 379 if (!devices.empty()) {
333 ui = MediaCaptureDevicesDispatcher::GetInstance() 380 ui = MediaCaptureDevicesDispatcher::GetInstance()
334 ->GetMediaStreamCaptureIndicator() 381 ->GetMediaStreamCaptureIndicator()
335 ->RegisterMediaStream(web_contents_, devices); 382 ->RegisterMediaStream(web_contents_, devices);
336 } 383 }
337 content::MediaResponseCallback cb = callback_; 384 base::ResetAndReturn(&callback_).Run(devices, request_result, ui.Pass());
338 callback_.Reset();
339 cb.Run(devices, request_result, ui.Pass());
340 } 385 }
341 386
342 void MediaStreamDevicesController::StorePermission( 387 void MediaStreamDevicesController::StorePermission(
343 ContentSetting new_audio_setting, 388 ContentSetting new_audio_setting,
344 ContentSetting new_video_setting) const { 389 ContentSetting new_video_setting) const {
345 DCHECK_CURRENTLY_ON(BrowserThread::UI); 390 DCHECK_CURRENTLY_ON(BrowserThread::UI);
346 ContentSettingsPattern primary_pattern = 391 ContentSettingsPattern primary_pattern =
347 ContentSettingsPattern::FromURLNoWildcard(request_.security_origin); 392 ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
348 393
349 bool is_pepper_request = request_.request_type == content::MEDIA_OPEN_DEVICE; 394 bool is_pepper_request = request_.request_type == content::MEDIA_OPEN_DEVICE;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 if (android_permission_blocked) 529 if (android_permission_blocked)
485 return false; 530 return false;
486 531
487 // Don't approve device requests if the tab was hidden. 532 // Don't approve device requests if the tab was hidden.
488 // TODO(qinmin): Add a test for this. http://crbug.com/396869. 533 // TODO(qinmin): Add a test for this. http://crbug.com/396869.
489 // TODO(raymes): Shouldn't this apply to all permissions not just audio/video? 534 // TODO(raymes): Shouldn't this apply to all permissions not just audio/video?
490 return web_contents_->GetRenderWidgetHostView()->IsShowing(); 535 return web_contents_->GetRenderWidgetHostView()->IsShowing();
491 #endif 536 #endif
492 return true; 537 return true;
493 } 538 }
OLDNEW
« no previous file with comments | « chrome/browser/media/media_stream_devices_controller.h ('k') | chrome/browser/media/media_stream_infobar_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698