OLD | NEW |
---|---|
(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 "base/metrics/field_trial.h" | |
8 #include "chrome/browser/media/media_stream_devices_controller.h" | |
9 #include "chrome/browser/media/media_stream_infobar_delegate.h" | |
10 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" | |
11 #include "content/public/browser/browser_thread.h" | |
12 #include "content/public/browser/web_contents.h" | |
13 | |
14 #if defined(ENABLE_EXTENSIONS) | |
15 #include "extensions/common/extension.h" | |
16 #endif | |
17 | |
18 using content::BrowserThread; | |
19 | |
20 namespace { | |
Sergey Ulanov
2015/05/07 01:05:48
nit: empty line after this one
changbin
2015/05/22 05:10:58
Done.
| |
21 // A finch experiment to enable the permission bubble for media requests only. | |
22 bool MediaStreamPermissionBubbleExperimentEnabled() { | |
23 const std::string group = | |
24 base::FieldTrialList::FindFullName("MediaStreamPermissionBubble"); | |
25 if (group == "enabled") | |
26 return true; | |
27 | |
28 return false; | |
29 } | |
30 } // namespace | |
31 | |
32 PendingAccessRequest::PendingAccessRequest( | |
33 const content::MediaStreamRequest& request, | |
34 const content::MediaResponseCallback& callback) | |
35 : request(request), callback(callback) { | |
36 } | |
37 | |
38 PendingAccessRequest::~PendingAccessRequest() { | |
39 } | |
40 | |
41 PermissionBubbleMediaAccessHandler::PermissionBubbleMediaAccessHandler( | |
42 RequestsQueues* requests) | |
43 : pending_requests_(requests) { | |
44 } | |
45 | |
46 PermissionBubbleMediaAccessHandler::~PermissionBubbleMediaAccessHandler() { | |
47 } | |
48 | |
49 bool PermissionBubbleMediaAccessHandler::SupportsRequest( | |
50 const content::MediaStreamRequest& request, | |
51 const extensions::Extension* extension) { | |
52 bool res = request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE || | |
Sergey Ulanov
2015/05/07 01:05:48
s/res/result/
| |
53 request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE; | |
54 #if defined(ENABLE_EXTENSIONS) | |
55 res &= (!extension || (!extension->is_platform_app() && | |
Sergey Ulanov
2015/05/07 01:05:48
I don't think you need this check here. ExtensionM
changbin
2015/05/22 05:10:58
I agree with that. While shouldn't we make the cod
| |
56 !extension->is_media_request_white_listed())); | |
57 #endif | |
58 return res; | |
59 } | |
60 | |
61 void PermissionBubbleMediaAccessHandler::HandleRequest( | |
62 content::WebContents* web_contents, | |
63 const content::MediaStreamRequest& request, | |
64 const content::MediaResponseCallback& callback, | |
65 const extensions::Extension* extension) { | |
66 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
67 | |
68 RequestsQueue& queue = (*pending_requests_)[web_contents]; | |
69 queue.push_back(PendingAccessRequest(request, callback)); | |
70 | |
71 // If this is the only request then show the infobar. | |
72 if (queue.size() == 1) | |
73 ProcessQueuedAccessRequest(web_contents); | |
74 } | |
75 | |
76 void PermissionBubbleMediaAccessHandler::ProcessQueuedAccessRequest( | |
77 content::WebContents* web_contents) { | |
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
79 | |
80 std::map<content::WebContents*, RequestsQueue>::iterator it = | |
81 pending_requests_->find(web_contents); | |
82 | |
83 if (it == pending_requests_->end() || it->second.empty()) { | |
84 // Don't do anything if the tab was closed. | |
85 return; | |
86 } | |
87 | |
88 DCHECK(!it->second.empty()); | |
89 | |
90 if (PermissionBubbleManager::Enabled() || | |
91 MediaStreamPermissionBubbleExperimentEnabled()) { | |
92 scoped_ptr<MediaStreamDevicesController> controller( | |
93 new MediaStreamDevicesController( | |
94 web_contents, it->second.front().request, | |
95 base::Bind( | |
96 &PermissionBubbleMediaAccessHandler::OnAccessRequestResponse, | |
97 base::Unretained(this), web_contents))); | |
98 if (controller->DismissInfoBarAndTakeActionOnSettings()) | |
99 return; | |
100 PermissionBubbleManager* bubble_manager = | |
101 PermissionBubbleManager::FromWebContents(web_contents); | |
102 if (bubble_manager) | |
103 bubble_manager->AddRequest(controller.release()); | |
104 return; | |
105 } | |
106 | |
107 // TODO(gbillock): delete this block and the MediaStreamInfoBarDelegate | |
108 // when we've transitioned to bubbles. (crbug/337458) | |
109 MediaStreamInfoBarDelegate::Create( | |
110 web_contents, it->second.front().request, | |
111 base::Bind(&PermissionBubbleMediaAccessHandler::OnAccessRequestResponse, | |
112 base::Unretained(this), web_contents)); | |
113 } | |
114 | |
115 void PermissionBubbleMediaAccessHandler::OnAccessRequestResponse( | |
116 content::WebContents* web_contents, | |
117 const content::MediaStreamDevices& devices, | |
118 content::MediaStreamRequestResult result, | |
119 scoped_ptr<content::MediaStreamUI> ui) { | |
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
121 | |
122 std::map<content::WebContents*, RequestsQueue>::iterator it = | |
123 pending_requests_->find(web_contents); | |
124 if (it == pending_requests_->end()) { | |
125 // WebContents has been destroyed. Don't need to do anything. | |
126 return; | |
127 } | |
128 | |
129 RequestsQueue& queue(it->second); | |
130 if (queue.empty()) | |
131 return; | |
132 | |
133 content::MediaResponseCallback callback = queue.front().callback; | |
134 queue.pop_front(); | |
135 | |
136 if (!queue.empty()) { | |
137 // Post a task to process next queued request. It has to be done | |
138 // asynchronously to make sure that calling infobar is not destroyed until | |
139 // after this function returns. | |
140 BrowserThread::PostTask( | |
141 BrowserThread::UI, FROM_HERE, | |
142 base::Bind( | |
143 &PermissionBubbleMediaAccessHandler::ProcessQueuedAccessRequest, | |
144 base::Unretained(this), web_contents)); | |
145 } | |
146 | |
147 callback.Run(devices, result, ui.Pass()); | |
148 } | |
OLD | NEW |