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

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

Powered by Google App Engine
This is Rietveld 408576698