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

Side by Side Diff: content/browser/permissions/permission_service_impl.cc

Issue 1316863010: browser: implement multiple permission requesting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@request-multiple-content
Patch Set: Fix memory leak in permission_manager Created 5 years, 2 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/browser/permissions/permission_service_impl.h" 5 #include "content/browser/permissions/permission_service_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "content/public/browser/browser_context.h" 8 #include "content/public/browser/browser_context.h"
9 #include "content/public/browser/permission_manager.h" 9 #include "content/public/browser/permission_manager.h"
10 #include "content/public/browser/permission_type.h" 10 #include "content/public/browser/permission_type.h"
(...skipping 21 matching lines...) Expand all
32 case PERMISSION_NAME_AUDIO_CAPTURE: 32 case PERMISSION_NAME_AUDIO_CAPTURE:
33 return PermissionType::AUDIO_CAPTURE; 33 return PermissionType::AUDIO_CAPTURE;
34 case PERMISSION_NAME_VIDEO_CAPTURE: 34 case PERMISSION_NAME_VIDEO_CAPTURE:
35 return PermissionType::VIDEO_CAPTURE; 35 return PermissionType::VIDEO_CAPTURE;
36 } 36 }
37 37
38 NOTREACHED(); 38 NOTREACHED();
39 return PermissionType::NUM; 39 return PermissionType::NUM;
40 } 40 }
41 41
42 // This function allows the usage of the the multiple request map
43 // with single requests.
44 void PermissionRequestResponseCallbackWrapper(
45 const mojo::Callback<void(PermissionStatus)>& callback,
46 const mojo::Array<PermissionStatus>& vector) {
47 DCHECK(vector.size() == 1);
mlamouri (slow - plz ping) 2015/09/23 16:37:37 nit: use DCHECK_EQ()
Lalit Maganti 2015/09/24 09:24:11 Done.
48 callback.Run(vector[0]);
49 }
50
42 } // anonymous namespace 51 } // anonymous namespace
43 52
44 PermissionServiceImpl::PendingRequest::PendingRequest( 53 PermissionServiceImpl::PendingRequest::PendingRequest(
45 PermissionType permission, 54 const PermissionsStatusCallback& callback,
46 const GURL& origin, 55 int request_count)
47 const PermissionStatusCallback& callback) 56 : callback(callback),
48 : id(-1), 57 request_count(request_count) {
49 permission(permission),
50 origin(origin),
51 callback(callback) {
52 } 58 }
53 59
54 PermissionServiceImpl::PendingRequest::~PendingRequest() { 60 PermissionServiceImpl::PendingRequest::~PendingRequest() {
55 if (!callback.is_null()) 61 if (!callback.is_null()) {
56 callback.Run(PERMISSION_STATUS_ASK); 62 mojo::Array<PermissionStatus> result =
63 mojo::Array<PermissionStatus>::New(request_count);
64 for (int i = 0; i < request_count; ++i)
65 result[i] = PERMISSION_STATUS_DENIED;
66 callback.Run(result.Pass());
67 }
57 } 68 }
58 69
59 PermissionServiceImpl::PendingSubscription::PendingSubscription( 70 PermissionServiceImpl::PendingSubscription::PendingSubscription(
60 PermissionType permission, 71 PermissionType permission,
61 const GURL& origin, 72 const GURL& origin,
62 const PermissionStatusCallback& callback) 73 const PermissionStatusCallback& callback)
63 : id(-1), 74 : id(-1),
64 permission(permission), 75 permission(permission),
65 origin(origin), 76 origin(origin),
66 callback(callback) { 77 callback(callback) {
(...skipping 29 matching lines...) Expand all
96 const mojo::String& origin, 107 const mojo::String& origin,
97 bool user_gesture, 108 bool user_gesture,
98 const PermissionStatusCallback& callback) { 109 const PermissionStatusCallback& callback) {
99 // This condition is valid if the call is coming from a ChildThread instead of 110 // This condition is valid if the call is coming from a ChildThread instead of
100 // a RenderFrame. Some consumers of the service run in Workers and some in 111 // a RenderFrame. Some consumers of the service run in Workers and some in
101 // Frames. In the context of a Worker, it is not possible to show a 112 // Frames. In the context of a Worker, it is not possible to show a
102 // permission prompt because there is no tab. In the context of a Frame, we 113 // permission prompt because there is no tab. In the context of a Frame, we
103 // can. Even if the call comes from a context where it is not possible to show 114 // can. Even if the call comes from a context where it is not possible to show
104 // any UI, we want to still return something relevant so the current 115 // any UI, we want to still return something relevant so the current
105 // permission status is returned. 116 // permission status is returned.
106 if (!context_->render_frame_host()) { 117 BrowserContext* browser_context = context_->GetBrowserContext();
107 // There is no way to show a UI so the call will simply return the current 118 DCHECK(browser_context);
108 // permission. 119 if (!context_->render_frame_host() ||
109 HasPermission(permission, origin, callback); 120 !browser_context->GetPermissionManager()) {
121 callback.Run(GetPermissionStatusFromName(permission, GURL(origin)));
110 return; 122 return;
111 } 123 }
112 124
113 BrowserContext* browser_context = context_->GetBrowserContext(); 125 int pending_request_id = pending_requests_.Add(new PendingRequest(
114 DCHECK(browser_context); 126 base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1));
115 if (!browser_context->GetPermissionManager()) {
116 callback.Run(content::PERMISSION_STATUS_DENIED);
117 return;
118 }
119
120 PermissionType permission_type = PermissionNameToPermissionType(permission);
121 int pending_request_id = pending_requests_.Add(
122 new PendingRequest(permission_type, GURL(origin), callback));
123
124 int id = browser_context->GetPermissionManager()->RequestPermission( 127 int id = browser_context->GetPermissionManager()->RequestPermission(
125 permission_type, 128 PermissionNameToPermissionType(permission),
126 context_->render_frame_host(), 129 context_->render_frame_host(),
127 GURL(origin), 130 GURL(origin),
128 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) 131 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
129 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, 132 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse,
130 weak_factory_.GetWeakPtr(), 133 weak_factory_.GetWeakPtr(),
131 pending_request_id)); 134 pending_request_id));
132 135
133 // Check if the request still exists. It may have been removed by the 136 // Check if the request still exists. It may have been removed by the
134 // the response callback. 137 // the response callback.
135 PendingRequest* pending_request = pending_requests_.Lookup( 138 PendingRequest* pending_request = pending_requests_.Lookup(
136 pending_request_id); 139 pending_request_id);
137 if (!pending_request) 140 if (!pending_request)
138 return; 141 return;
139 pending_request->id = id; 142 pending_request->id = id;
140 } 143 }
141 144
145 void PermissionServiceImpl::OnRequestPermissionResponse(
146 int pending_request_id,
147 PermissionStatus status) {
148 OnRequestPermissionsResponse(pending_request_id,
149 std::vector<PermissionStatus>(1, status));
150 }
151
142 void PermissionServiceImpl::RequestPermissions( 152 void PermissionServiceImpl::RequestPermissions(
143 mojo::Array<PermissionName> permissions, 153 mojo::Array<PermissionName> permissions,
144 const mojo::String& origin, 154 const mojo::String& origin,
145 bool user_gesture, 155 bool user_gesture,
146 const PermissionsStatusCallback& callback) { 156 const PermissionsStatusCallback& callback) {
147 NOTIMPLEMENTED(); 157 if (permissions.is_null()) {
158 callback.Run(mojo::Array<PermissionStatus>());
159 return;
160 }
148 161
149 // TODO(lalitm,mlamouri): this is returning the current permission statuses 162 // This condition is valid if the call is coming from a ChildThread instead of
150 // in order for the call to successfully return. It will be changed later. 163 // a RenderFrame. Some consumers of the service run in Workers and some in
151 // See https://crbug.com/516626 164 // Frames. In the context of a Worker, it is not possible to show a
152 mojo::Array<PermissionStatus> result(permissions.size()); 165 // permission prompt because there is no tab. In the context of a Frame, we
153 for (size_t i = 0; i < permissions.size(); ++i) 166 // can. Even if the call comes from a context where it is not possible to show
154 result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin)); 167 // any UI, we want to still return something relevant so the current
155 callback.Run(result.Pass()); 168 // permission status is returned for each permission.
169 BrowserContext* browser_context = context_->GetBrowserContext();
170 DCHECK(browser_context);
171 if (!context_->render_frame_host() ||
172 !browser_context->GetPermissionManager()) {
173 mojo::Array<PermissionStatus> result(permissions.size());
174 for (size_t i = 0; i < permissions.size(); ++i)
175 result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin));
176 callback.Run(result.Pass());
177 return;
178 }
179
180 std::vector<PermissionType> types(permissions.size());
181 for (size_t i = 0; i < types.size(); ++i)
182 types[i] = PermissionNameToPermissionType(permissions[i]);
183
184 int pending_request_id = pending_requests_.Add(
185 new PendingRequest(callback, permissions.size()));
186 int id = browser_context->GetPermissionManager()->RequestPermissions(
187 types,
188 context_->render_frame_host(),
189 GURL(origin),
190 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
191 base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse,
192 weak_factory_.GetWeakPtr(),
193 pending_request_id));
194
195 // Check if the request still exists. It may have been removed by the
196 // the response callback.
197 PendingRequest* pending_request = pending_requests_.Lookup(
198 pending_request_id);
199 if (!pending_request)
200 return;
201 pending_request->id = id;
156 } 202 }
157 203
158 void PermissionServiceImpl::OnRequestPermissionResponse( 204 void PermissionServiceImpl::OnRequestPermissionsResponse(
159 int request_id, 205 int pending_request_id,
160 PermissionStatus status) { 206 const std::vector<PermissionStatus>& result) {
161 PendingRequest* request = pending_requests_.Lookup(request_id); 207 PendingRequest* request = pending_requests_.Lookup(pending_request_id);
162 PermissionStatusCallback callback(request->callback); 208 PermissionsStatusCallback callback(request->callback);
163 request->callback.reset(); 209 request->callback.reset();
164 pending_requests_.Remove(request_id); 210 pending_requests_.Remove(pending_request_id);
165 callback.Run(status); 211 callback.Run(mojo::Array<PermissionStatus>::From(result));
166 } 212 }
167 213
168 void PermissionServiceImpl::CancelPendingOperations() { 214 void PermissionServiceImpl::CancelPendingOperations() {
169 DCHECK(context_->GetBrowserContext()); 215 DCHECK(context_->GetBrowserContext());
170 216
171 PermissionManager* permission_manager = 217 PermissionManager* permission_manager =
172 context_->GetBrowserContext()->GetPermissionManager(); 218 context_->GetBrowserContext()->GetPermissionManager();
173 if (!permission_manager) 219 if (!permission_manager)
174 return; 220 return;
175 221
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 355
310 PermissionStatusCallback callback = subscription->callback; 356 PermissionStatusCallback callback = subscription->callback;
311 357
312 subscription->callback.reset(); 358 subscription->callback.reset();
313 pending_subscriptions_.Remove(pending_subscription_id); 359 pending_subscriptions_.Remove(pending_subscription_id);
314 360
315 callback.Run(status); 361 callback.Run(status);
316 } 362 }
317 363
318 } // namespace content 364 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698