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

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: Add blankline 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
106 if (IsAllowedForVideo()) {
107 content_settings_types.push_back(
108 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
109 }
110
111 // If the site had been previously granted the access to audio or video but
112 // Chrome is now missing the necessary permission, we need to show an infobar
113 // to resolve the difference.
114 if (!content_settings_types.empty() &&
115 PermissionUpdateInfoBarDelegate::ShouldShowPermissionInfobar(
116 web_contents, content_settings_types)) {
117 return;
118 }
119 #endif
120
95 // Otherwise we can run the callback immediately. 121 // Otherwise we can run the callback immediately.
96 RunCallback(old_audio_setting_, old_video_setting_, denial_reason); 122 RunCallback(old_audio_setting_, old_video_setting_, denial_reason);
97 } 123 }
98 124
99 MediaStreamDevicesController::~MediaStreamDevicesController() { 125 MediaStreamDevicesController::~MediaStreamDevicesController() {
100 if (!callback_.is_null()) { 126 if (!callback_.is_null()) {
101 callback_.Run(content::MediaStreamDevices(), 127 callback_.Run(content::MediaStreamDevices(),
102 content::MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN, 128 content::MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN,
103 scoped_ptr<content::MediaStreamUI>()); 129 scoped_ptr<content::MediaStreamUI>());
104 } 130 }
105 } 131 }
106 132
107 // static 133 // static
108 void MediaStreamDevicesController::RegisterProfilePrefs( 134 void MediaStreamDevicesController::RegisterProfilePrefs(
109 user_prefs::PrefRegistrySyncable* prefs) { 135 user_prefs::PrefRegistrySyncable* prefs) {
110 prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, true); 136 prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, true);
111 prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, true); 137 prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, true);
112 prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls); 138 prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls);
113 prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls); 139 prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls);
114 } 140 }
115 141
142 bool MediaStreamDevicesController::IsAllowedForAudio() const {
143 return old_audio_setting_ == CONTENT_SETTING_ALLOW;
144 }
145
146 bool MediaStreamDevicesController::IsAllowedForVideo() const {
147 return old_video_setting_ == CONTENT_SETTING_ALLOW;
148 }
149
116 bool MediaStreamDevicesController::IsAskingForAudio() const { 150 bool MediaStreamDevicesController::IsAskingForAudio() const {
117 return old_audio_setting_ == CONTENT_SETTING_ASK; 151 return old_audio_setting_ == CONTENT_SETTING_ASK;
118 } 152 }
119 153
120 bool MediaStreamDevicesController::IsAskingForVideo() const { 154 bool MediaStreamDevicesController::IsAskingForVideo() const {
121 return old_video_setting_ == CONTENT_SETTING_ASK; 155 return old_video_setting_ == CONTENT_SETTING_ASK;
122 } 156 }
123 157
124 const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const { 158 const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
125 return request_.security_origin.spec(); 159 return request_.security_origin.spec();
126 } 160 }
127 161
162 void MediaStreamDevicesController::ForcePermissionDeniedTemporarily() {
163 base::AutoReset<bool> persist_permissions(
164 &persist_permission_changes_, false);
165 UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
166 kDeny, kPermissionActionsMax);
167 RunCallback(CONTENT_SETTING_BLOCK,
168 CONTENT_SETTING_BLOCK,
169 content::MEDIA_DEVICE_PERMISSION_DENIED);
170 }
171
128 int MediaStreamDevicesController::GetIconId() const { 172 int MediaStreamDevicesController::GetIconId() const {
129 if (IsAskingForVideo()) 173 if (IsAskingForVideo())
130 return IDR_INFOBAR_MEDIA_STREAM_CAMERA; 174 return IDR_INFOBAR_MEDIA_STREAM_CAMERA;
131 175
132 return IDR_INFOBAR_MEDIA_STREAM_MIC; 176 return IDR_INFOBAR_MEDIA_STREAM_MIC;
133 } 177 }
134 178
135 base::string16 MediaStreamDevicesController::GetMessageText() const { 179 base::string16 MediaStreamDevicesController::GetMessageText() const {
136 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO; 180 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO;
137 if (!IsAskingForAudio()) 181 if (!IsAskingForAudio())
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); 346 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
303 } 347 }
304 348
305 return devices; 349 return devices;
306 } 350 }
307 351
308 void MediaStreamDevicesController::RunCallback( 352 void MediaStreamDevicesController::RunCallback(
309 ContentSetting audio_setting, 353 ContentSetting audio_setting,
310 ContentSetting video_setting, 354 ContentSetting video_setting,
311 content::MediaStreamRequestResult denial_reason) { 355 content::MediaStreamRequestResult denial_reason) {
312 StorePermission(audio_setting, video_setting); 356 CHECK(!callback_.is_null());
313 UpdateTabSpecificContentSettings(audio_setting, video_setting); 357
358 if (persist_permission_changes_) {
359 StorePermission(audio_setting, video_setting);
360 UpdateTabSpecificContentSettings(audio_setting, video_setting);
361 }
314 362
315 content::MediaStreamDevices devices = 363 content::MediaStreamDevices devices =
316 GetDevices(audio_setting, video_setting); 364 GetDevices(audio_setting, video_setting);
317 365
318 // If either audio or video are allowed then the callback should report 366 // If either audio or video are allowed then the callback should report
319 // success, otherwise we report |denial_reason|. 367 // success, otherwise we report |denial_reason|.
320 content::MediaStreamRequestResult request_result = content::MEDIA_DEVICE_OK; 368 content::MediaStreamRequestResult request_result = content::MEDIA_DEVICE_OK;
321 if (audio_setting != CONTENT_SETTING_ALLOW && 369 if (audio_setting != CONTENT_SETTING_ALLOW &&
322 video_setting != CONTENT_SETTING_ALLOW) { 370 video_setting != CONTENT_SETTING_ALLOW) {
323 DCHECK_NE(content::MEDIA_DEVICE_OK, denial_reason); 371 DCHECK_NE(content::MEDIA_DEVICE_OK, denial_reason);
324 request_result = denial_reason; 372 request_result = denial_reason;
325 } else if (devices.empty()) { 373 } else if (devices.empty()) {
326 // Even if one of the content settings was allowed, if there are no devices 374 // Even if one of the content settings was allowed, if there are no devices
327 // at this point we still report a failure. 375 // at this point we still report a failure.
328 request_result = content::MEDIA_DEVICE_NO_HARDWARE; 376 request_result = content::MEDIA_DEVICE_NO_HARDWARE;
329 } 377 }
330 378
331 scoped_ptr<content::MediaStreamUI> ui; 379 scoped_ptr<content::MediaStreamUI> ui;
332 if (!devices.empty()) { 380 if (!devices.empty()) {
333 ui = MediaCaptureDevicesDispatcher::GetInstance() 381 ui = MediaCaptureDevicesDispatcher::GetInstance()
334 ->GetMediaStreamCaptureIndicator() 382 ->GetMediaStreamCaptureIndicator()
335 ->RegisterMediaStream(web_contents_, devices); 383 ->RegisterMediaStream(web_contents_, devices);
336 } 384 }
337 content::MediaResponseCallback cb = callback_; 385 base::ResetAndReturn(&callback_).Run(devices, request_result, ui.Pass());
338 callback_.Reset();
339 cb.Run(devices, request_result, ui.Pass());
340 } 386 }
341 387
342 void MediaStreamDevicesController::StorePermission( 388 void MediaStreamDevicesController::StorePermission(
343 ContentSetting new_audio_setting, 389 ContentSetting new_audio_setting,
344 ContentSetting new_video_setting) const { 390 ContentSetting new_video_setting) const {
345 DCHECK_CURRENTLY_ON(BrowserThread::UI); 391 DCHECK_CURRENTLY_ON(BrowserThread::UI);
346 ContentSettingsPattern primary_pattern = 392 ContentSettingsPattern primary_pattern =
347 ContentSettingsPattern::FromURLNoWildcard(request_.security_origin); 393 ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
348 394
349 bool is_pepper_request = request_.request_type == content::MEDIA_OPEN_DEVICE; 395 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) 530 if (android_permission_blocked)
485 return false; 531 return false;
486 532
487 // Don't approve device requests if the tab was hidden. 533 // Don't approve device requests if the tab was hidden.
488 // TODO(qinmin): Add a test for this. http://crbug.com/396869. 534 // 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? 535 // TODO(raymes): Shouldn't this apply to all permissions not just audio/video?
490 return web_contents_->GetRenderWidgetHostView()->IsShowing(); 536 return web_contents_->GetRenderWidgetHostView()->IsShowing();
491 #endif 537 #endif
492 return true; 538 return true;
493 } 539 }
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