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

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

Issue 2307083002: Cleanup: move WebRTC related files from chrome/browser/media to chrome/browser/media/webrtc/ (Closed)
Patch Set: Removed file wrongly resuscitated during rebase Created 4 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/media/permission_bubble_media_access_handler.h"
6
7 #include <utility>
8
9 #include "base/metrics/field_trial.h"
10 #include "chrome/browser/media/media_permission.h"
11 #include "chrome/browser/media/media_stream_device_permissions.h"
12 #include "chrome/browser/media/media_stream_devices_controller.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/features.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/content_settings/core/browser/host_content_settings_map.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/notification_types.h"
20 #include "content/public/browser/web_contents.h"
21
22 #if BUILDFLAG(ANDROID_JAVA_UI)
23 #include <vector>
24
25 #include "base/bind.h"
26 #include "base/bind_helpers.h"
27 #include "chrome/browser/media/media_stream_infobar_delegate_android.h"
28 #include "chrome/browser/permissions/permission_update_infobar_delegate_android. h"
29 #else
30 #include "chrome/browser/permissions/permission_request_manager.h"
31 #endif // BUILDFLAG(ANDROID_JAVA_UI)
32
33 #if BUILDFLAG(ANDROID_JAVA_UI)
34 namespace {
35 // Callback for the permission update infobar when the site and Chrome
36 // permissions are mismatched on Android.
37 void OnPermissionConflictResolved(
38 std::unique_ptr<MediaStreamDevicesController> controller,
39 bool allowed) {
40 if (allowed)
41 controller->PermissionGranted();
42 else
43 controller->ForcePermissionDeniedTemporarily();
44 }
45 } // namespace
46
47 #endif // BUILDFLAG(ANDROID_JAVA_UI)
48
49 using content::BrowserThread;
50
51 struct PermissionBubbleMediaAccessHandler::PendingAccessRequest {
52 PendingAccessRequest(const content::MediaStreamRequest& request,
53 const content::MediaResponseCallback& callback)
54 : request(request), callback(callback) {}
55 ~PendingAccessRequest() {}
56
57 // TODO(gbillock): make the MediaStreamDevicesController owned by
58 // this object when we're using bubbles.
59 content::MediaStreamRequest request;
60 content::MediaResponseCallback callback;
61 };
62
63 PermissionBubbleMediaAccessHandler::PermissionBubbleMediaAccessHandler() {
64 // PermissionBubbleMediaAccessHandler should be created on UI thread.
65 // Otherwise, it will not receive
66 // content::NOTIFICATION_WEB_CONTENTS_DESTROYED, and that will result in
67 // possible use after free.
68 DCHECK_CURRENTLY_ON(BrowserThread::UI);
69 notifications_registrar_.Add(this,
70 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
71 content::NotificationService::AllSources());
72 }
73
74 PermissionBubbleMediaAccessHandler::~PermissionBubbleMediaAccessHandler() {
75 }
76
77 bool PermissionBubbleMediaAccessHandler::SupportsStreamType(
78 const content::MediaStreamType type,
79 const extensions::Extension* extension) {
80 return type == content::MEDIA_DEVICE_VIDEO_CAPTURE ||
81 type == content::MEDIA_DEVICE_AUDIO_CAPTURE;
82 }
83
84 bool PermissionBubbleMediaAccessHandler::CheckMediaAccessPermission(
85 content::WebContents* web_contents,
86 const GURL& security_origin,
87 content::MediaStreamType type,
88 const extensions::Extension* extension) {
89 Profile* profile =
90 Profile::FromBrowserContext(web_contents->GetBrowserContext());
91 ContentSettingsType content_settings_type =
92 type == content::MEDIA_DEVICE_AUDIO_CAPTURE
93 ? CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC
94 : CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA;
95
96 MediaPermission permission(content_settings_type, security_origin,
97 web_contents->GetLastCommittedURL().GetOrigin(), profile);
98 content::MediaStreamRequestResult unused;
99 return permission.GetPermissionStatus(&unused) == CONTENT_SETTING_ALLOW;
100 }
101
102 void PermissionBubbleMediaAccessHandler::HandleRequest(
103 content::WebContents* web_contents,
104 const content::MediaStreamRequest& request,
105 const content::MediaResponseCallback& callback,
106 const extensions::Extension* extension) {
107 DCHECK_CURRENTLY_ON(BrowserThread::UI);
108
109 RequestsQueue& queue = pending_requests_[web_contents];
110 queue.push_back(PendingAccessRequest(request, callback));
111
112 // If this is the only request then show the infobar.
113 if (queue.size() == 1)
114 ProcessQueuedAccessRequest(web_contents);
115 }
116
117 void PermissionBubbleMediaAccessHandler::ProcessQueuedAccessRequest(
118 content::WebContents* web_contents) {
119 DCHECK_CURRENTLY_ON(BrowserThread::UI);
120
121 std::map<content::WebContents*, RequestsQueue>::iterator it =
122 pending_requests_.find(web_contents);
123
124 if (it == pending_requests_.end() || it->second.empty()) {
125 // Don't do anything if the tab was closed.
126 return;
127 }
128
129 DCHECK(!it->second.empty());
130
131 std::unique_ptr<MediaStreamDevicesController> controller(
132 new MediaStreamDevicesController(
133 web_contents, it->second.front().request,
134 base::Bind(
135 &PermissionBubbleMediaAccessHandler::OnAccessRequestResponse,
136 base::Unretained(this), web_contents)));
137 if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) {
138 #if BUILDFLAG(ANDROID_JAVA_UI)
139 // 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
141 // mismatch.
142 std::vector<ContentSettingsType> content_settings_types;
143 if (controller->IsAllowedForAudio())
144 content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
145
146 if (controller->IsAllowedForVideo()) {
147 content_settings_types.push_back(
148 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
149 }
150 if (!content_settings_types.empty() &&
151 PermissionUpdateInfoBarDelegate::ShouldShowPermissionInfobar(
152 web_contents, content_settings_types)) {
153 PermissionUpdateInfoBarDelegate::Create(
154 web_contents, content_settings_types,
155 base::Bind(
156 &OnPermissionConflictResolved, base::Passed(&controller)));
157 }
158 #endif
159 return;
160 }
161
162 #if BUILDFLAG(ANDROID_JAVA_UI)
163 MediaStreamInfoBarDelegateAndroid::Create(web_contents,
164 std::move(controller));
165 #else
166 PermissionRequestManager* permission_request_manager =
167 PermissionRequestManager::FromWebContents(web_contents);
168 if (permission_request_manager)
169 permission_request_manager->AddRequest(controller.release());
170 #endif
171 }
172
173 void PermissionBubbleMediaAccessHandler::UpdateMediaRequestState(
174 int render_process_id,
175 int render_frame_id,
176 int page_request_id,
177 content::MediaStreamType stream_type,
178 content::MediaRequestState state) {
179 DCHECK_CURRENTLY_ON(BrowserThread::UI);
180 if (state != content::MEDIA_REQUEST_STATE_CLOSING)
181 return;
182
183 bool found = false;
184 for (RequestsQueues::iterator rqs_it = pending_requests_.begin();
185 rqs_it != pending_requests_.end(); ++rqs_it) {
186 RequestsQueue& queue = rqs_it->second;
187 for (RequestsQueue::iterator it = queue.begin(); it != queue.end(); ++it) {
188 if (it->request.render_process_id == render_process_id &&
189 it->request.render_frame_id == render_frame_id &&
190 it->request.page_request_id == page_request_id) {
191 queue.erase(it);
192 found = true;
193 break;
194 }
195 }
196 if (found)
197 break;
198 }
199 }
200
201 void PermissionBubbleMediaAccessHandler::OnAccessRequestResponse(
202 content::WebContents* web_contents,
203 const content::MediaStreamDevices& devices,
204 content::MediaStreamRequestResult result,
205 std::unique_ptr<content::MediaStreamUI> ui) {
206 DCHECK_CURRENTLY_ON(BrowserThread::UI);
207
208 std::map<content::WebContents*, RequestsQueue>::iterator it =
209 pending_requests_.find(web_contents);
210 if (it == pending_requests_.end()) {
211 // WebContents has been destroyed. Don't need to do anything.
212 return;
213 }
214
215 RequestsQueue& queue(it->second);
216 if (queue.empty())
217 return;
218
219 content::MediaResponseCallback callback = queue.front().callback;
220 queue.pop_front();
221
222 if (!queue.empty()) {
223 // Post a task to process next queued request. It has to be done
224 // asynchronously to make sure that calling infobar is not destroyed until
225 // after this function returns.
226 BrowserThread::PostTask(
227 BrowserThread::UI, FROM_HERE,
228 base::Bind(
229 &PermissionBubbleMediaAccessHandler::ProcessQueuedAccessRequest,
230 base::Unretained(this), web_contents));
231 }
232
233 callback.Run(devices, result, std::move(ui));
234 }
235
236 void PermissionBubbleMediaAccessHandler::Observe(
237 int type,
238 const content::NotificationSource& source,
239 const content::NotificationDetails& details) {
240 DCHECK_CURRENTLY_ON(BrowserThread::UI);
241 DCHECK_EQ(content::NOTIFICATION_WEB_CONTENTS_DESTROYED, type);
242
243 pending_requests_.erase(content::Source<content::WebContents>(source).ptr());
244 }
OLDNEW
« no previous file with comments | « chrome/browser/media/permission_bubble_media_access_handler.h ('k') | chrome/browser/media/rtp_dump_type.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698