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

Side by Side Diff: android_webview/browser/aw_permission_manager.cc

Issue 1342833002: permissions: handle request ids for permissions in permission manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix test failures 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 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 "android_webview/browser/aw_permission_manager.h" 5 #include "android_webview/browser/aw_permission_manager.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "android_webview/browser/aw_browser_permission_request_delegate.h" 9 #include "android_webview/browser/aw_browser_permission_request_delegate.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/containers/hash_tables.h" 11 #include "base/containers/hash_tables.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/weak_ptr.h"
14 #include "content/public/browser/permission_type.h" 13 #include "content/public/browser/permission_type.h"
15 #include "content/public/browser/render_frame_host.h" 14 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/render_process_host.h" 15 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/web_contents.h" 16 #include "content/public/browser/web_contents.h"
18 17
19 using content::PermissionStatus; 18 using content::PermissionStatus;
20 using content::PermissionType; 19 using content::PermissionType;
21 20
22 namespace android_webview { 21 namespace android_webview {
23 22
24 class LastRequestResultCache { 23 class LastRequestResultCache {
25 public: 24 public:
26 LastRequestResultCache() : weak_factory_(this) {} 25 LastRequestResultCache() = default;
27 26
28 void SetResult(PermissionType permission, 27 void SetResult(PermissionType permission,
29 const GURL& requesting_origin, 28 const GURL& requesting_origin,
30 const GURL& embedding_origin, 29 const GURL& embedding_origin,
31 PermissionStatus status) { 30 PermissionStatus status) {
32 DCHECK(status == content::PERMISSION_STATUS_GRANTED || 31 DCHECK(status == content::PERMISSION_STATUS_GRANTED ||
33 status == content::PERMISSION_STATUS_DENIED); 32 status == content::PERMISSION_STATUS_DENIED);
34 33
35 // TODO(ddorwin): We should be denying empty origins at a higher level. 34 // TODO(ddorwin): We should be denying empty origins at a higher level.
36 if (requesting_origin.is_empty() || embedding_origin.is_empty()) { 35 if (requesting_origin.is_empty() || embedding_origin.is_empty()) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 106
108 if (permission != PermissionType::PROTECTED_MEDIA_IDENTIFIER) { 107 if (permission != PermissionType::PROTECTED_MEDIA_IDENTIFIER) {
109 // Other permissions are not cached, so nothing to clear. 108 // Other permissions are not cached, so nothing to clear.
110 return; 109 return;
111 } 110 }
112 111
113 std::string key = GetCacheKey(requesting_origin, embedding_origin); 112 std::string key = GetCacheKey(requesting_origin, embedding_origin);
114 pmi_result_cache_.erase(key); 113 pmi_result_cache_.erase(key);
115 } 114 }
116 115
117 base::WeakPtr<LastRequestResultCache> GetWeakPtr() {
118 return weak_factory_.GetWeakPtr();
119 }
120
121 private: 116 private:
122 // Returns a concatenation of the origins to be used as the index. 117 // Returns a concatenation of the origins to be used as the index.
123 // Returns the empty string if either origin is invalid or empty. 118 // Returns the empty string if either origin is invalid or empty.
124 static std::string GetCacheKey(const GURL& requesting_origin, 119 static std::string GetCacheKey(const GURL& requesting_origin,
125 const GURL& embedding_origin) { 120 const GURL& embedding_origin) {
126 const std::string& requesting = requesting_origin.spec(); 121 const std::string& requesting = requesting_origin.spec();
127 const std::string& embedding = embedding_origin.spec(); 122 const std::string& embedding = embedding_origin.spec();
128 if (requesting.empty() || embedding.empty()) 123 if (requesting.empty() || embedding.empty())
129 return std::string(); 124 return std::string();
130 return requesting + "," + embedding; 125 return requesting + "," + embedding;
131 } 126 }
132 127
133 using StatusMap = base::hash_map<std::string, PermissionStatus>; 128 using StatusMap = base::hash_map<std::string, PermissionStatus>;
134 StatusMap pmi_result_cache_; 129 StatusMap pmi_result_cache_;
135 130
136 base::WeakPtrFactory<LastRequestResultCache> weak_factory_;
137
138 DISALLOW_COPY_AND_ASSIGN(LastRequestResultCache); 131 DISALLOW_COPY_AND_ASSIGN(LastRequestResultCache);
139 }; 132 };
140 133
141 namespace { 134 struct AwPermissionManager::PendingRequest {
142 135 PermissionType permission;
143 void CallbackPermisisonStatusWrapper( 136 GURL requesting_origin;
144 const base::WeakPtr<LastRequestResultCache>& result_cache, 137 int render_process_id;
145 const base::Callback<void(PermissionStatus)>& callback, 138 int render_frame_id;
146 PermissionType permission, 139 };
147 const GURL& requesting_origin,
148 const GURL& embedding_origin,
149 bool allowed) {
150 PermissionStatus status = allowed ? content::PERMISSION_STATUS_GRANTED
151 : content::PERMISSION_STATUS_DENIED;
152 if (result_cache.get()) {
153 result_cache->SetResult(permission, requesting_origin, embedding_origin,
154 status);
155 }
156
157 callback.Run(status);
158 }
159
160 } // anonymous namespace
161 140
162 AwPermissionManager::AwPermissionManager() 141 AwPermissionManager::AwPermissionManager()
163 : content::PermissionManager(), result_cache_(new LastRequestResultCache) { 142 : content::PermissionManager(),
143 result_cache_(new LastRequestResultCache),
144 weak_ptr_factory_(this) {
164 } 145 }
165 146
166 AwPermissionManager::~AwPermissionManager() { 147 AwPermissionManager::~AwPermissionManager() {
167 } 148 }
168 149
169 void AwPermissionManager::RequestPermission( 150 int AwPermissionManager::RequestPermission(
170 PermissionType permission, 151 PermissionType permission,
171 content::RenderFrameHost* render_frame_host, 152 content::RenderFrameHost* render_frame_host,
172 int request_id, 153 const GURL& requesting_origin,
173 const GURL& origin,
174 bool user_gesture, 154 bool user_gesture,
175 const base::Callback<void(PermissionStatus)>& callback) { 155 const base::Callback<void(PermissionStatus)>& callback) {
176 int render_process_id = render_frame_host->GetProcess()->GetID(); 156 int render_process_id = render_frame_host->GetProcess()->GetID();
177 int render_frame_id = render_frame_host->GetRoutingID(); 157 int render_frame_id = render_frame_host->GetRoutingID();
178 AwBrowserPermissionRequestDelegate* delegate = 158 AwBrowserPermissionRequestDelegate* delegate =
179 AwBrowserPermissionRequestDelegate::FromID(render_process_id, 159 AwBrowserPermissionRequestDelegate::FromID(render_process_id,
180 render_frame_id); 160 render_frame_id);
181 if (!delegate) { 161 if (!delegate) {
182 DVLOG(0) << "Dropping permission request for " 162 DVLOG(0) << "Dropping permission request for "
183 << static_cast<int>(permission); 163 << static_cast<int>(permission);
184 callback.Run(content::PERMISSION_STATUS_DENIED); 164 callback.Run(content::PERMISSION_STATUS_DENIED);
185 return; 165 return kCancelUnsubscribeNoOp;
186 } 166 }
187 167
188 const GURL& embedding_origin = 168 const GURL& embedding_origin =
189 content::WebContents::FromRenderFrameHost(render_frame_host) 169 content::WebContents::FromRenderFrameHost(render_frame_host)
190 ->GetLastCommittedURL().GetOrigin(); 170 ->GetLastCommittedURL().GetOrigin();
191 171
172 int request_id = kCancelUnsubscribeNoOp;
192 switch (permission) { 173 switch (permission) {
193 case PermissionType::GEOLOCATION: 174 case PermissionType::GEOLOCATION:
175 request_id = AddPendingRequestToMap(render_process_id, render_frame_id,
176 permission, requesting_origin);
194 delegate->RequestGeolocationPermission( 177 delegate->RequestGeolocationPermission(
195 origin, base::Bind(&CallbackPermisisonStatusWrapper, 178 requesting_origin,
196 result_cache_->GetWeakPtr(), callback, permission, 179 base::Bind(&AwPermissionManager::OnRequestResponse,
197 origin, embedding_origin)); 180 weak_ptr_factory_.GetWeakPtr(), request_id,
181 callback, permission,
182 requesting_origin, embedding_origin));
198 break; 183 break;
199 case PermissionType::PROTECTED_MEDIA_IDENTIFIER: 184 case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
185 request_id = AddPendingRequestToMap(render_process_id, render_frame_id,
186 permission, requesting_origin);
200 delegate->RequestProtectedMediaIdentifierPermission( 187 delegate->RequestProtectedMediaIdentifierPermission(
201 origin, base::Bind(&CallbackPermisisonStatusWrapper, 188 requesting_origin,
202 result_cache_->GetWeakPtr(), callback, permission, 189 base::Bind(&AwPermissionManager::OnRequestResponse,
203 origin, embedding_origin)); 190 weak_ptr_factory_.GetWeakPtr(), request_id,
191 callback, permission,
192 requesting_origin, embedding_origin));
204 break; 193 break;
205 case PermissionType::MIDI_SYSEX: 194 case PermissionType::MIDI_SYSEX:
195 request_id = AddPendingRequestToMap(render_process_id, render_frame_id,
196 permission, requesting_origin);
206 delegate->RequestMIDISysexPermission( 197 delegate->RequestMIDISysexPermission(
207 origin, base::Bind(&CallbackPermisisonStatusWrapper, 198 requesting_origin,
208 result_cache_->GetWeakPtr(), callback, permission, 199 base::Bind(&AwPermissionManager::OnRequestResponse,
209 origin, embedding_origin)); 200 weak_ptr_factory_.GetWeakPtr(), request_id,
201 callback, permission,
202 requesting_origin, embedding_origin));
210 break; 203 break;
211 case PermissionType::AUDIO_CAPTURE: 204 case PermissionType::AUDIO_CAPTURE:
212 case PermissionType::VIDEO_CAPTURE: 205 case PermissionType::VIDEO_CAPTURE:
213 case PermissionType::NOTIFICATIONS: 206 case PermissionType::NOTIFICATIONS:
214 case PermissionType::PUSH_MESSAGING: 207 case PermissionType::PUSH_MESSAGING:
215 case PermissionType::DURABLE_STORAGE: 208 case PermissionType::DURABLE_STORAGE:
216 NOTIMPLEMENTED() << "RequestPermission is not implemented for " 209 NOTIMPLEMENTED() << "RequestPermission is not implemented for "
217 << static_cast<int>(permission); 210 << static_cast<int>(permission);
218 callback.Run(content::PERMISSION_STATUS_DENIED); 211 callback.Run(content::PERMISSION_STATUS_DENIED);
219 break; 212 break;
220 case PermissionType::MIDI: 213 case PermissionType::MIDI:
221 callback.Run(content::PERMISSION_STATUS_GRANTED); 214 callback.Run(content::PERMISSION_STATUS_GRANTED);
222 break; 215 break;
223 case PermissionType::NUM: 216 case PermissionType::NUM:
224 NOTREACHED() << "PermissionType::NUM was not expected here."; 217 NOTREACHED() << "PermissionType::NUM was not expected here.";
225 callback.Run(content::PERMISSION_STATUS_DENIED); 218 callback.Run(content::PERMISSION_STATUS_DENIED);
226 break; 219 break;
227 } 220 }
221 return request_id;
228 } 222 }
229 223
230 void AwPermissionManager::CancelPermissionRequest( 224 // static
225 void AwPermissionManager::OnRequestResponse(
226 const base::WeakPtr<AwPermissionManager>& manager,
227 int request_id,
228 const base::Callback<void(PermissionStatus)>& callback,
231 PermissionType permission, 229 PermissionType permission,
232 content::RenderFrameHost* render_frame_host, 230 const GURL& requesting_origin,
233 int request_id, 231 const GURL& embedding_origin,
mlamouri (slow - plz ping) 2015/09/16 14:42:56 Why do you pass |request_id| with all the other va
Lalit Maganti 2015/09/16 16:41:10 Good point. Fixed.
234 const GURL& origin) { 232 bool allowed) {
233 PermissionStatus status = allowed ? content::PERMISSION_STATUS_GRANTED
234 : content::PERMISSION_STATUS_DENIED;
235 if (manager.get()) {
236 manager->pending_requests_.Remove(request_id);
237 manager->result_cache_->SetResult(
238 permission, requesting_origin, embedding_origin, status);
239 }
240 callback.Run(status);
241 }
242
243 int AwPermissionManager::AddPendingRequestToMap(
244 int render_process_id,
245 int render_frame_id,
246 PermissionType permission,
247 const GURL& requesting_origin) {
248 PendingRequest* request = new PendingRequest();
249 request->render_process_id = render_process_id;
250 request->render_frame_id = render_frame_id;
251 request->permission = permission;
252 request->requesting_origin = requesting_origin;
253 return pending_requests_.Add(request);
mlamouri (slow - plz ping) 2015/09/16 14:42:56 Is having that helper method really better than do
Lalit Maganti 2015/09/16 16:41:10 Done.
254 }
255
256 void AwPermissionManager::CancelPermissionRequest(int request_id) {
257 PendingRequest* pending_request = pending_requests_.Lookup(request_id);
258 if (!pending_request)
259 return;
260
261 content::RenderFrameHost* render_frame_host =
262 content::RenderFrameHost::FromID(pending_request->render_process_id,
263 pending_request->render_frame_id);
264 DCHECK(render_frame_host);
265
266 content::WebContents* web_contents =
267 content::WebContents::FromRenderFrameHost(render_frame_host);
268 DCHECK(web_contents);
269
235 // The caller is canceling (presumably) the most recent request. Assuming the 270 // The caller is canceling (presumably) the most recent request. Assuming the
236 // request did not complete, the user did not respond to the requset. 271 // request did not complete, the user did not respond to the requset.
237 // Thus, assume we do not know the result. 272 // Thus, assume we do not know the result.
238 const GURL& embedding_origin = 273 const GURL& embedding_origin = web_contents
239 content::WebContents::FromRenderFrameHost(render_frame_host)
240 ->GetLastCommittedURL().GetOrigin(); 274 ->GetLastCommittedURL().GetOrigin();
241 result_cache_->ClearResult(permission, origin, embedding_origin); 275 result_cache_->ClearResult(
276 pending_request->permission,
277 pending_request->requesting_origin,
278 embedding_origin);
242 279
243 int render_process_id = render_frame_host->GetProcess()->GetID();
244 int render_frame_id = render_frame_host->GetRoutingID();
245 AwBrowserPermissionRequestDelegate* delegate = 280 AwBrowserPermissionRequestDelegate* delegate =
246 AwBrowserPermissionRequestDelegate::FromID(render_process_id, 281 AwBrowserPermissionRequestDelegate::FromID(
247 render_frame_id); 282 pending_request->render_process_id,
248 if (!delegate) 283 pending_request->render_frame_id);
284 if (!delegate) {
285 pending_requests_.Remove(request_id);
249 return; 286 return;
287 }
250 288
251 switch (permission) { 289 switch (pending_request->permission) {
252 case PermissionType::GEOLOCATION: 290 case PermissionType::GEOLOCATION:
253 delegate->CancelGeolocationPermissionRequests(origin); 291 delegate->CancelGeolocationPermissionRequests(
292 pending_request->requesting_origin);
254 break; 293 break;
255 case PermissionType::PROTECTED_MEDIA_IDENTIFIER: 294 case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
256 delegate->CancelProtectedMediaIdentifierPermissionRequests(origin); 295 delegate->CancelProtectedMediaIdentifierPermissionRequests(
296 pending_request->requesting_origin);
257 break; 297 break;
258 case PermissionType::MIDI_SYSEX: 298 case PermissionType::MIDI_SYSEX:
259 delegate->CancelMIDISysexPermissionRequests(origin); 299 delegate->CancelMIDISysexPermissionRequests(
300 pending_request->requesting_origin);
260 break; 301 break;
261 case PermissionType::NOTIFICATIONS: 302 case PermissionType::NOTIFICATIONS:
262 case PermissionType::PUSH_MESSAGING: 303 case PermissionType::PUSH_MESSAGING:
263 case PermissionType::DURABLE_STORAGE: 304 case PermissionType::DURABLE_STORAGE:
264 case PermissionType::AUDIO_CAPTURE: 305 case PermissionType::AUDIO_CAPTURE:
265 case PermissionType::VIDEO_CAPTURE: 306 case PermissionType::VIDEO_CAPTURE:
266 NOTIMPLEMENTED() << "CancelPermission not implemented for " 307 NOTIMPLEMENTED() << "CancelPermission not implemented for "
267 << static_cast<int>(permission); 308 << static_cast<int>(pending_request->permission);
268 break; 309 break;
269 case PermissionType::MIDI: 310 case PermissionType::MIDI:
270 // There is nothing to cancel so this is simply ignored. 311 // There is nothing to cancel so this is simply ignored.
271 break; 312 break;
272 case PermissionType::NUM: 313 case PermissionType::NUM:
273 NOTREACHED() << "PermissionType::NUM was not expected here."; 314 NOTREACHED() << "PermissionType::NUM was not expected here.";
274 break; 315 break;
275 } 316 }
317
318 pending_requests_.Remove(request_id);
276 } 319 }
277 320
278 void AwPermissionManager::ResetPermission(PermissionType permission, 321 void AwPermissionManager::ResetPermission(PermissionType permission,
279 const GURL& requesting_origin, 322 const GURL& requesting_origin,
280 const GURL& embedding_origin) { 323 const GURL& embedding_origin) {
281 result_cache_->ClearResult(permission, requesting_origin, embedding_origin); 324 result_cache_->ClearResult(permission, requesting_origin, embedding_origin);
282 } 325 }
283 326
284 PermissionStatus AwPermissionManager::GetPermissionStatus( 327 PermissionStatus AwPermissionManager::GetPermissionStatus(
285 PermissionType permission, 328 PermissionType permission,
(...skipping 14 matching lines...) Expand all
300 PermissionType permission, 343 PermissionType permission,
301 const GURL& requesting_origin, 344 const GURL& requesting_origin,
302 const GURL& embedding_origin) { 345 const GURL& embedding_origin) {
303 } 346 }
304 347
305 int AwPermissionManager::SubscribePermissionStatusChange( 348 int AwPermissionManager::SubscribePermissionStatusChange(
306 PermissionType permission, 349 PermissionType permission,
307 const GURL& requesting_origin, 350 const GURL& requesting_origin,
308 const GURL& embedding_origin, 351 const GURL& embedding_origin,
309 const base::Callback<void(PermissionStatus)>& callback) { 352 const base::Callback<void(PermissionStatus)>& callback) {
310 return -1; 353 return kCancelUnsubscribeNoOp;
311 } 354 }
312 355
313 void AwPermissionManager::UnsubscribePermissionStatusChange( 356 void AwPermissionManager::UnsubscribePermissionStatusChange(
314 int subscription_id) { 357 int subscription_id) {
315 } 358 }
316 359
317 } // namespace android_webview 360 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698