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

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

Issue 365123003: Implement midi permissions on top of the new common permission classes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Initial review comments Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/midi_permission_context.h" 5 #include "chrome/browser/media/midi_permission_context.h"
6 6
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/content_settings/host_content_settings_map.h"
9 #include "chrome/browser/content_settings/permission_queue_controller.h"
10 #include "chrome/browser/content_settings/permission_request_id.h" 7 #include "chrome/browser/content_settings/permission_request_id.h"
11 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 8 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
12 #include "chrome/browser/profiles/profile.h" 9 #include "url/gurl.h"
13 #include "chrome/browser/tab_contents/tab_util.h"
14 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
15 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
16 #include "chrome/common/pref_names.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/web_contents.h"
21 #include "grit/generated_resources.h"
22 #include "grit/theme_resources.h"
23 #include "net/base/net_util.h"
24 #include "ui/base/l10n/l10n_util.h"
25
26 class MidiPermissionRequest : public PermissionBubbleRequest {
27 public:
28 MidiPermissionRequest(
29 MidiPermissionContext* context,
30 const PermissionRequestID& id,
31 const GURL& requesting_frame,
32 bool user_gesture,
33 const std::string& display_languages,
34 const base::Callback<void(bool)>& callback);
35 virtual ~MidiPermissionRequest();
36
37 // PermissionBubbleDelegate:
38 virtual int GetIconID() const OVERRIDE;
39 virtual base::string16 GetMessageText() const OVERRIDE;
40 virtual base::string16 GetMessageTextFragment() const OVERRIDE;
41 virtual bool HasUserGesture() const OVERRIDE;
42 virtual GURL GetRequestingHostname() const OVERRIDE;
43 virtual void PermissionGranted() OVERRIDE;
44 virtual void PermissionDenied() OVERRIDE;
45 virtual void Cancelled() OVERRIDE;
46 virtual void RequestFinished() OVERRIDE;
47
48 private:
49 MidiPermissionContext* context_;
50 const PermissionRequestID id_;
51 GURL requesting_frame_;
52 bool user_gesture_;
53 std::string display_languages_;
54 const base::Callback<void(bool)>& callback_;
55 bool is_finished_;
56
57 DISALLOW_COPY_AND_ASSIGN(MidiPermissionRequest);
58 };
59
60 MidiPermissionRequest::MidiPermissionRequest(
61 MidiPermissionContext* context,
62 const PermissionRequestID& id,
63 const GURL& requesting_frame,
64 bool user_gesture,
65 const std::string& display_languages,
66 const base::Callback<void(bool)>& callback)
67 : context_(context),
68 id_(id),
69 requesting_frame_(requesting_frame),
70 user_gesture_(user_gesture),
71 display_languages_(display_languages),
72 callback_(callback),
73 is_finished_(false) {}
74
75 MidiPermissionRequest::~MidiPermissionRequest() {
76 DCHECK(is_finished_);
77 }
78
79 int MidiPermissionRequest::GetIconID() const {
80 return IDR_ALLOWED_MIDI_SYSEX;
81 }
82
83 base::string16 MidiPermissionRequest::GetMessageText() const {
84 return l10n_util::GetStringFUTF16(
85 IDS_MIDI_SYSEX_INFOBAR_QUESTION,
86 net::FormatUrl(requesting_frame_.GetOrigin(), display_languages_,
87 net::kFormatUrlOmitUsernamePassword |
88 net::kFormatUrlOmitTrailingSlashOnBareHostname,
89 net::UnescapeRule::SPACES, NULL, NULL, NULL));
90 }
91
92 base::string16 MidiPermissionRequest::GetMessageTextFragment() const {
93 return l10n_util::GetStringUTF16(IDS_MIDI_SYSEX_PERMISSION_FRAGMENT);
94 }
95
96 bool MidiPermissionRequest::HasUserGesture() const {
97 return user_gesture_;
98 }
99
100 GURL MidiPermissionRequest::GetRequestingHostname() const {
101 return requesting_frame_;
102 }
103
104 void MidiPermissionRequest::PermissionGranted() {
105 context_->NotifyPermissionSet(id_, requesting_frame_, callback_, true);
106 }
107
108 void MidiPermissionRequest::PermissionDenied() {
109 context_->NotifyPermissionSet(id_, requesting_frame_, callback_, false);
110 }
111
112 void MidiPermissionRequest::Cancelled() {
113 }
114
115 void MidiPermissionRequest::RequestFinished() {
116 is_finished_ = true;
117 // Deletes 'this'.
118 context_->RequestFinished(this);
119 }
120 10
121 MidiPermissionContext::MidiPermissionContext(Profile* profile) 11 MidiPermissionContext::MidiPermissionContext(Profile* profile)
122 : profile_(profile), 12 : PermissionContextBase(profile, CONTENT_SETTINGS_TYPE_MIDI_SYSEX){
123 shutting_down_(false),
124 weak_factory_(this) {
125 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
126 } 13 }
127 14
128 MidiPermissionContext::~MidiPermissionContext() { 15 MidiPermissionContext::~MidiPermissionContext() {
129 DCHECK(!permission_queue_controller_);
130 DCHECK(pending_requests_.empty());
131 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
132 } 16 }
133 17
134 void MidiPermissionContext::Shutdown() {
135 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
136 permission_queue_controller_.reset();
137 shutting_down_ = true;
138 }
139 18
140 void MidiPermissionContext::RequestMidiSysExPermission( 19 void MidiPermissionContext::UpdateTabContext(const PermissionRequestID& id,
141 content::WebContents* web_contents, 20 const GURL& requesting_frame,
142 int bridge_id, 21 bool allowed) {
143 const GURL& requesting_frame,
144 bool user_gesture,
145 const base::Callback<void(bool)>& result_callback,
146 base::Closure* cancel_callback) {
147 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
148 DCHECK(!shutting_down_);
149
150 // TODO(toyoshim): Support Extension's manifest declared permission.
151 // See http://crbug.com/266338.
152
153 int render_process_id = web_contents->GetRenderProcessHost()->GetID();
154 int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
155 if (cancel_callback) {
156 *cancel_callback = base::Bind(
157 &MidiPermissionContext::CancelMidiSysExPermissionRequest,
158 weak_factory_.GetWeakPtr(), render_process_id, render_view_id,
159 bridge_id);
160 }
161
162 const PermissionRequestID id(
163 render_process_id, render_view_id, bridge_id, GURL());
164
165 GURL embedder = web_contents->GetURL();
166 // |requesting_frame| can be empty and invalid when the frame is a local
167 // file. Here local files should be granted to show an infobar.
168 // Any user's action will not be stored to content settings data base.
169 if ((!requesting_frame.is_valid() && !requesting_frame.is_empty()) ||
170 !embedder.is_valid()) {
171 LOG(WARNING) << "Attempt to use MIDI sysex from an invalid URL: "
172 << requesting_frame << "," << embedder
173 << " (Web MIDI is not supported in popups)";
174 PermissionDecided(id, requesting_frame, embedder, result_callback, false);
175 return;
176 }
177
178 DecidePermission(web_contents, id, requesting_frame, embedder, user_gesture,
179 result_callback);
180 }
181
182 void MidiPermissionContext::CancelMidiSysExPermissionRequest(
183 int render_process_id,
184 int render_view_id,
185 int bridge_id) {
186 CancelPendingInfobarRequest(
187 PermissionRequestID(
188 render_process_id, render_view_id, bridge_id, GURL()));
189 }
190
191 void MidiPermissionContext::DecidePermission(
192 content::WebContents* web_contents,
193 const PermissionRequestID& id,
194 const GURL& requesting_frame,
195 const GURL& embedder,
196 bool user_gesture,
197 const base::Callback<void(bool)>& callback) {
198 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
199
200 ContentSetting content_setting =
201 profile_->GetHostContentSettingsMap()->GetContentSetting(
202 requesting_frame,
203 embedder,
204 CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
205 std::string());
206 switch (content_setting) {
207 case CONTENT_SETTING_BLOCK:
208 PermissionDecided(id, requesting_frame, embedder, callback, false);
209 break;
210 case CONTENT_SETTING_ALLOW:
211 PermissionDecided(id, requesting_frame, embedder, callback, true);
212 break;
213 default:
214 if (PermissionBubbleManager::Enabled()) {
215 PermissionBubbleManager* bubble_manager =
216 PermissionBubbleManager::FromWebContents(web_contents);
217 if (bubble_manager) {
218 scoped_ptr<MidiPermissionRequest> request_ptr(
219 new MidiPermissionRequest(
220 this, id, requesting_frame, user_gesture,
221 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
222 callback));
223 MidiPermissionRequest* request = request_ptr.get();
224 bool inserted = pending_requests_.add(
225 id.ToString(), request_ptr.Pass()).second;
226 DCHECK(inserted) << "Duplicate id " << id.ToString();
227 bubble_manager->AddRequest(request);
228 }
229 return;
230 }
231
232 // TODO(gbillock): Delete this and the infobar delegate when
233 // we're using only bubbles. crbug.com/337458
234 GetQueueController()->CreateInfoBarRequest(
235 id, requesting_frame, embedder, std::string(), base::Bind(
236 &MidiPermissionContext::NotifyPermissionSet,
237 base::Unretained(this), id, requesting_frame, callback));
238 }
239 }
240
241 void MidiPermissionContext::PermissionDecided(
242 const PermissionRequestID& id,
243 const GURL& requesting_frame,
244 const GURL& embedder,
245 const base::Callback<void(bool)>& callback,
246 bool allowed) {
247 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
248 NotifyPermissionSet(id, requesting_frame, callback, allowed);
249 }
250
251 void MidiPermissionContext::NotifyPermissionSet(
252 const PermissionRequestID& id,
253 const GURL& requesting_frame,
254 const base::Callback<void(bool)>& callback,
255 bool allowed) {
256 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
257
258 TabSpecificContentSettings* content_settings = 22 TabSpecificContentSettings* content_settings =
259 TabSpecificContentSettings::Get(id.render_process_id(), 23 TabSpecificContentSettings::Get(id.render_process_id(),
260 id.render_view_id()); 24 id.render_view_id());
261 if (content_settings) { 25 if (content_settings) {
262 if (allowed) 26 if (allowed)
263 content_settings->OnMidiSysExAccessed(requesting_frame); 27 content_settings->OnMidiSysExAccessed(requesting_frame);
264 else 28 else
265 content_settings->OnMidiSysExAccessBlocked(requesting_frame); 29 content_settings->OnMidiSysExAccessBlocked(requesting_frame);
266 } 30 }
267
268 callback.Run(allowed);
269 } 31 }
270
271 PermissionQueueController* MidiPermissionContext::GetQueueController() {
272 if (!permission_queue_controller_) {
273 permission_queue_controller_.reset(
274 new PermissionQueueController(profile_,
275 CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
276 }
277 return permission_queue_controller_.get();
278 }
279
280 void MidiPermissionContext::RequestFinished(
281 MidiPermissionRequest* request) {
282 base::ScopedPtrHashMap<std::string, MidiPermissionRequest>::iterator it;
283 for (it = pending_requests_.begin(); it != pending_requests_.end(); it++) {
284 if (it->second == request) {
285 pending_requests_.take_and_erase(it);
286 return;
287 }
288 }
289
290 NOTREACHED() << "Missing request";
291 }
292
293 void MidiPermissionContext::CancelPendingInfobarRequest(
294 const PermissionRequestID& id) {
295 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
296 if (shutting_down_)
297 return;
298
299 if (PermissionBubbleManager::Enabled()) {
300 MidiPermissionRequest* cancelling = pending_requests_.get(id.ToString());
301 content::WebContents* web_contents = tab_util::GetWebContentsByID(
302 id.render_process_id(), id.render_view_id());
303 if (cancelling != NULL && web_contents != NULL &&
304 PermissionBubbleManager::FromWebContents(web_contents) != NULL) {
305 PermissionBubbleManager::FromWebContents(web_contents)->
306 CancelRequest(cancelling);
307 }
308 return;
309 }
310
311 GetQueueController()->CancelInfoBarRequest(id);
312 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698