OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/permission_bubble_media_access_handler.h" | 5 #include "chrome/browser/media/webrtc/permission_bubble_media_access_handler.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
10 #include "chrome/browser/media/webrtc/media_permission.h" | 10 #include "chrome/browser/media/webrtc/media_permission.h" |
11 #include "chrome/browser/media/webrtc/media_stream_device_permissions.h" | 11 #include "chrome/browser/media/webrtc/media_stream_device_permissions.h" |
12 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h" | 12 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h" |
13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/common/features.h" | 14 #include "chrome/common/features.h" |
15 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
16 #include "components/content_settings/core/browser/host_content_settings_map.h" | 16 #include "components/content_settings/core/browser/host_content_settings_map.h" |
17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
18 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
19 #include "content/public/browser/notification_types.h" | 19 #include "content/public/browser/notification_types.h" |
20 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
21 | 21 |
22 #if BUILDFLAG(ANDROID_JAVA_UI) | 22 #if BUILDFLAG(ANDROID_JAVA_UI) |
23 #include <vector> | 23 #include <vector> |
24 | 24 |
25 #include "base/bind.h" | 25 #include "base/bind.h" |
26 #include "base/bind_helpers.h" | 26 #include "base/bind_helpers.h" |
| 27 #include "chrome/browser/android/chrome_feature_list.h" |
27 #include "chrome/browser/media/webrtc/media_stream_infobar_delegate_android.h" | 28 #include "chrome/browser/media/webrtc/media_stream_infobar_delegate_android.h" |
| 29 #include "chrome/browser/media/webrtc/screen_capture_infobar_delegate_android.h" |
28 #include "chrome/browser/permissions/permission_update_infobar_delegate_android.
h" | 30 #include "chrome/browser/permissions/permission_update_infobar_delegate_android.
h" |
29 #else | 31 #else |
30 #include "chrome/browser/permissions/permission_request_manager.h" | 32 #include "chrome/browser/permissions/permission_request_manager.h" |
31 #endif // BUILDFLAG(ANDROID_JAVA_UI) | 33 #endif // BUILDFLAG(ANDROID_JAVA_UI) |
32 | 34 |
33 #if BUILDFLAG(ANDROID_JAVA_UI) | 35 #if BUILDFLAG(ANDROID_JAVA_UI) |
34 namespace { | 36 namespace { |
35 // Callback for the permission update infobar when the site and Chrome | 37 // Callback for the permission update infobar when the site and Chrome |
36 // permissions are mismatched on Android. | 38 // permissions are mismatched on Android. |
37 void OnPermissionConflictResolved( | 39 void OnPermissionConflictResolved( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 72 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
71 content::NotificationService::AllSources()); | 73 content::NotificationService::AllSources()); |
72 } | 74 } |
73 | 75 |
74 PermissionBubbleMediaAccessHandler::~PermissionBubbleMediaAccessHandler() { | 76 PermissionBubbleMediaAccessHandler::~PermissionBubbleMediaAccessHandler() { |
75 } | 77 } |
76 | 78 |
77 bool PermissionBubbleMediaAccessHandler::SupportsStreamType( | 79 bool PermissionBubbleMediaAccessHandler::SupportsStreamType( |
78 const content::MediaStreamType type, | 80 const content::MediaStreamType type, |
79 const extensions::Extension* extension) { | 81 const extensions::Extension* extension) { |
| 82 #if BUILDFLAG(ANDROID_JAVA_UI) |
| 83 return type == content::MEDIA_DEVICE_VIDEO_CAPTURE || |
| 84 type == content::MEDIA_DEVICE_AUDIO_CAPTURE || |
| 85 type == content::MEDIA_DESKTOP_VIDEO_CAPTURE; |
| 86 #else |
80 return type == content::MEDIA_DEVICE_VIDEO_CAPTURE || | 87 return type == content::MEDIA_DEVICE_VIDEO_CAPTURE || |
81 type == content::MEDIA_DEVICE_AUDIO_CAPTURE; | 88 type == content::MEDIA_DEVICE_AUDIO_CAPTURE; |
| 89 #endif |
82 } | 90 } |
83 | 91 |
84 bool PermissionBubbleMediaAccessHandler::CheckMediaAccessPermission( | 92 bool PermissionBubbleMediaAccessHandler::CheckMediaAccessPermission( |
85 content::WebContents* web_contents, | 93 content::WebContents* web_contents, |
86 const GURL& security_origin, | 94 const GURL& security_origin, |
87 content::MediaStreamType type, | 95 content::MediaStreamType type, |
88 const extensions::Extension* extension) { | 96 const extensions::Extension* extension) { |
89 Profile* profile = | 97 Profile* profile = |
90 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 98 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
91 ContentSettingsType content_settings_type = | 99 ContentSettingsType content_settings_type = |
92 type == content::MEDIA_DEVICE_AUDIO_CAPTURE | 100 type == content::MEDIA_DEVICE_AUDIO_CAPTURE |
93 ? CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC | 101 ? CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC |
94 : CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA; | 102 : CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA; |
95 | 103 |
96 MediaPermission permission(content_settings_type, security_origin, | 104 MediaPermission permission(content_settings_type, security_origin, |
97 web_contents->GetLastCommittedURL().GetOrigin(), profile); | 105 web_contents->GetLastCommittedURL().GetOrigin(), profile); |
98 content::MediaStreamRequestResult unused; | 106 content::MediaStreamRequestResult unused; |
99 return permission.GetPermissionStatus(&unused) == CONTENT_SETTING_ALLOW; | 107 return permission.GetPermissionStatus(&unused) == CONTENT_SETTING_ALLOW; |
100 } | 108 } |
101 | 109 |
102 void PermissionBubbleMediaAccessHandler::HandleRequest( | 110 void PermissionBubbleMediaAccessHandler::HandleRequest( |
103 content::WebContents* web_contents, | 111 content::WebContents* web_contents, |
104 const content::MediaStreamRequest& request, | 112 const content::MediaStreamRequest& request, |
105 const content::MediaResponseCallback& callback, | 113 const content::MediaResponseCallback& callback, |
106 const extensions::Extension* extension) { | 114 const extensions::Extension* extension) { |
107 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 115 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
108 | 116 |
| 117 #if BUILDFLAG(ANDROID_JAVA_UI) |
| 118 if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE && |
| 119 !base::FeatureList::IsEnabled( |
| 120 chrome::android::kUserMediaScreenCapturing)) { |
| 121 // If screen capturing isn't enabled on Android, we'll use "invalid state" |
| 122 // as result, same as on desktop. |
| 123 callback.Run(content::MediaStreamDevices(), |
| 124 content::MEDIA_DEVICE_INVALID_STATE, nullptr); |
| 125 return; |
| 126 } |
| 127 #endif // BUILDFLAG(ANDROID_JAVA_UI) |
| 128 |
109 RequestsQueue& queue = pending_requests_[web_contents]; | 129 RequestsQueue& queue = pending_requests_[web_contents]; |
110 queue.push_back(PendingAccessRequest(request, callback)); | 130 queue.push_back(PendingAccessRequest(request, callback)); |
111 | 131 |
112 // If this is the only request then show the infobar. | 132 // If this is the only request then show the infobar. |
113 if (queue.size() == 1) | 133 if (queue.size() == 1) |
114 ProcessQueuedAccessRequest(web_contents); | 134 ProcessQueuedAccessRequest(web_contents); |
115 } | 135 } |
116 | 136 |
117 void PermissionBubbleMediaAccessHandler::ProcessQueuedAccessRequest( | 137 void PermissionBubbleMediaAccessHandler::ProcessQueuedAccessRequest( |
118 content::WebContents* web_contents) { | 138 content::WebContents* web_contents) { |
119 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 139 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
120 | 140 |
121 std::map<content::WebContents*, RequestsQueue>::iterator it = | 141 std::map<content::WebContents*, RequestsQueue>::iterator it = |
122 pending_requests_.find(web_contents); | 142 pending_requests_.find(web_contents); |
123 | 143 |
124 if (it == pending_requests_.end() || it->second.empty()) { | 144 if (it == pending_requests_.end() || it->second.empty()) { |
125 // Don't do anything if the tab was closed. | 145 // Don't do anything if the tab was closed. |
126 return; | 146 return; |
127 } | 147 } |
128 | 148 |
129 DCHECK(!it->second.empty()); | 149 DCHECK(!it->second.empty()); |
130 | 150 |
| 151 const content::MediaStreamRequest request = it->second.front().request; |
| 152 #if BUILDFLAG(ANDROID_JAVA_UI) |
| 153 if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| 154 ScreenCaptureInfoBarDelegateAndroid::Create( |
| 155 web_contents, request, |
| 156 base::Bind(&PermissionBubbleMediaAccessHandler::OnAccessRequestResponse, |
| 157 base::Unretained(this), web_contents)); |
| 158 return; |
| 159 } |
| 160 #endif |
| 161 |
131 std::unique_ptr<MediaStreamDevicesController> controller( | 162 std::unique_ptr<MediaStreamDevicesController> controller( |
132 new MediaStreamDevicesController( | 163 new MediaStreamDevicesController( |
133 web_contents, it->second.front().request, | 164 web_contents, request, |
134 base::Bind( | 165 base::Bind( |
135 &PermissionBubbleMediaAccessHandler::OnAccessRequestResponse, | 166 &PermissionBubbleMediaAccessHandler::OnAccessRequestResponse, |
136 base::Unretained(this), web_contents))); | 167 base::Unretained(this), web_contents))); |
137 if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) { | 168 if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) { |
138 #if BUILDFLAG(ANDROID_JAVA_UI) | 169 #if BUILDFLAG(ANDROID_JAVA_UI) |
139 // If either audio or video was previously allowed and Chrome no longer has | 170 // If either audio or video was previously allowed and Chrome no longer has |
140 // the necessary permissions, show a infobar to attempt to address this | 171 // the necessary permissions, show a infobar to attempt to address this |
141 // mismatch. | 172 // mismatch. |
142 std::vector<ContentSettingsType> content_settings_types; | 173 std::vector<ContentSettingsType> content_settings_types; |
143 if (controller->IsAllowedForAudio()) | 174 if (controller->IsAllowedForAudio()) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 | 266 |
236 void PermissionBubbleMediaAccessHandler::Observe( | 267 void PermissionBubbleMediaAccessHandler::Observe( |
237 int type, | 268 int type, |
238 const content::NotificationSource& source, | 269 const content::NotificationSource& source, |
239 const content::NotificationDetails& details) { | 270 const content::NotificationDetails& details) { |
240 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 271 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
241 DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type); | 272 DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type); |
242 | 273 |
243 pending_requests_.erase(content::Source<content::WebContents>(source).ptr()); | 274 pending_requests_.erase(content::Source<content::WebContents>(source).ptr()); |
244 } | 275 } |
OLD | NEW |