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

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

Issue 1260193009: renderer: implement multiple permission requesting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@permissions-request-multiple
Patch Set: Merge patches Created 5 years, 4 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/browser/permissions/permission_pending_multiple_request.h"
9 #include "content/browser/permissions/permission_pending_single_request.h"
8 #include "content/public/browser/browser_context.h" 10 #include "content/public/browser/browser_context.h"
9 #include "content/public/browser/permission_manager.h" 11 #include "content/public/browser/permission_manager.h"
10 #include "content/public/browser/permission_type.h" 12 #include "content/public/browser/permission_type.h"
11 13
12 namespace content { 14 namespace content {
13 15
14 namespace { 16 namespace {
15 17
16 PermissionType PermissionNameToPermissionType(PermissionName name) { 18 PermissionType PermissionNameToPermissionType(PermissionName name) {
17 switch(name) { 19 switch(name) {
18 case PERMISSION_NAME_GEOLOCATION: 20 case PERMISSION_NAME_GEOLOCATION:
19 return PermissionType::GEOLOCATION; 21 return PermissionType::GEOLOCATION;
20 case PERMISSION_NAME_NOTIFICATIONS: 22 case PERMISSION_NAME_NOTIFICATIONS:
21 return PermissionType::NOTIFICATIONS; 23 return PermissionType::NOTIFICATIONS;
22 case PERMISSION_NAME_PUSH_NOTIFICATIONS: 24 case PERMISSION_NAME_PUSH_NOTIFICATIONS:
23 return PermissionType::PUSH_MESSAGING; 25 return PermissionType::PUSH_MESSAGING;
24 case PERMISSION_NAME_MIDI_SYSEX: 26 case PERMISSION_NAME_MIDI_SYSEX:
25 return PermissionType::MIDI_SYSEX; 27 return PermissionType::MIDI_SYSEX;
26 case PERMISSION_NAME_PROTECTED_MEDIA_IDENTIFIER: 28 case PERMISSION_NAME_PROTECTED_MEDIA_IDENTIFIER:
27 return PermissionType::PROTECTED_MEDIA_IDENTIFIER; 29 return PermissionType::PROTECTED_MEDIA_IDENTIFIER;
28 } 30 }
29 31
30 NOTREACHED(); 32 NOTREACHED();
31 return PermissionType::NUM; 33 return PermissionType::NUM;
32 } 34 }
33 35
34 } // anonymous namespace 36 } // anonymous namespace
35 37
36 PermissionServiceImpl::PendingRequest::PendingRequest(
37 PermissionType permission,
38 const GURL& origin,
39 const PermissionStatusCallback& callback)
40 : permission(permission),
41 origin(origin),
42 callback(callback) {
43 }
44
45 PermissionServiceImpl::PendingRequest::~PendingRequest() {
46 if (!callback.is_null())
47 callback.Run(PERMISSION_STATUS_ASK);
48 }
49
50 PermissionServiceImpl::PendingSubscription::PendingSubscription( 38 PermissionServiceImpl::PendingSubscription::PendingSubscription(
51 PermissionType permission, 39 PermissionType permission,
52 const GURL& origin, 40 const GURL& origin,
53 const PermissionStatusCallback& callback) 41 const PermissionStatusCallback& callback)
54 : id(-1), 42 : id(-1),
55 permission(permission), 43 permission(permission),
56 origin(origin), 44 origin(origin),
57 callback(callback) { 45 callback(callback) {
58 } 46 }
59 47
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 } 90 }
103 91
104 BrowserContext* browser_context = context_->GetBrowserContext(); 92 BrowserContext* browser_context = context_->GetBrowserContext();
105 DCHECK(browser_context); 93 DCHECK(browser_context);
106 if (!browser_context->GetPermissionManager()) { 94 if (!browser_context->GetPermissionManager()) {
107 callback.Run(content::PERMISSION_STATUS_DENIED); 95 callback.Run(content::PERMISSION_STATUS_DENIED);
108 return; 96 return;
109 } 97 }
110 98
111 PermissionType permission_type = PermissionNameToPermissionType(permission); 99 PermissionType permission_type = PermissionNameToPermissionType(permission);
112 int request_id = pending_requests_.Add( 100
113 new PendingRequest(permission_type, GURL(origin), callback)); 101 PermissionPendingSingleRequest* request =
102 new PermissionPendingSingleRequest(
103 permission_type, GURL(origin), callback);
104 int request_id = pending_requests_.Add(request);
114 105
115 browser_context->GetPermissionManager()->RequestPermission( 106 browser_context->GetPermissionManager()->RequestPermission(
116 permission_type, 107 permission_type,
117 context_->render_frame_host(), 108 context_->render_frame_host(),
118 request_id, 109 request_id,
119 GURL(origin), 110 GURL(origin),
120 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) 111 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
121 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, 112 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse,
122 weak_factory_.GetWeakPtr(), 113 weak_factory_.GetWeakPtr(),
123 request_id)); 114 request_id,
115 request));
116 }
117
118 void PermissionServiceImpl::RequestPermissions(
119 mojo::Array<PermissionName> permissions,
120 const mojo::String& origin,
121 bool user_gesture,
122 const PermissionsStatusCallback& callback) {
123 if (permissions.is_null()) {
124 callback.Run(mojo::Array<PermissionStatus>());
125 return;
126 }
127
128 // This condition is valid if the call is coming from a ChildThread instead of
129 // a RenderFrame. Some consumers of the service run in Workers and some in
130 // Frames. In the context of a Worker, it is not possible to show a
131 // permission prompt because there is no tab. In the context of a Frame, we
132 // can. Even if the call comes from a context where it is not possible to show
133 // any UI, we want to still return something relevant so the current
134 // permission status is returned for each permission.
135 if (!context_->render_frame_host()) {
136 mojo::Array<PermissionStatus> result(permissions.size());
137 for (size_t i = 0; i < permissions.size(); ++i) {
138 result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin));
139 }
140 callback.Run(result.Pass());
141 return;
142 }
143
144 BrowserContext* browser_context = context_->GetBrowserContext();
145 DCHECK(browser_context);
146 if (!browser_context->GetPermissionManager()) {
147 mojo::Array<PermissionStatus> result(permissions.size());
148 for (size_t i = 0; i < permissions.size(); ++i) {
149 result[i] = PERMISSION_STATUS_DENIED;
150 }
151 callback.Run(result.Pass());
152 return;
153 }
154
155 std::vector<PermissionType> permission_types;
156 permission_types.reserve(permissions.size());
157 for (size_t i = 0; i < permissions.size(); ++i) {
158 permission_types.push_back(
159 PermissionNameToPermissionType(permissions[i]));
160 }
161 PermissionPendingMultipleRequest* request =
162 new PermissionPendingMultipleRequest(callback, permissions.size());
163 int request_id = pending_requests_.Add(request);
164
165 browser_context->GetPermissionManager()->RequestPermissions(
166 permission_types,
167 context_->render_frame_host(),
168 request_id,
169 GURL(origin),
170 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
171 base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse,
172 weak_factory_.GetWeakPtr(),
173 request_id,
174 request));
124 } 175 }
125 176
126 void PermissionServiceImpl::OnRequestPermissionResponse( 177 void PermissionServiceImpl::OnRequestPermissionResponse(
127 int request_id, 178 int request_id,
179 PermissionPendingSingleRequest* request,
128 PermissionStatus status) { 180 PermissionStatus status) {
129 PendingRequest* request = pending_requests_.Lookup(request_id);
130 PermissionStatusCallback callback(request->callback); 181 PermissionStatusCallback callback(request->callback);
131 request->callback.reset(); 182 request->callback.reset();
132 pending_requests_.Remove(request_id); 183 pending_requests_.Remove(request_id);
184
133 callback.Run(status); 185 callback.Run(status);
134 } 186 }
135 187
188 void PermissionServiceImpl::OnRequestPermissionsResponse(
189 int request_id,
190 PermissionPendingMultipleRequest* request,
191 const std::vector<PermissionStatus>& status) {
192 PermissionsStatusCallback callback(request->callback);
193 request->callback.reset();
194 pending_requests_.Remove(request_id);
195
196 mojo::Array<PermissionStatus> status_array(status.size());
197 for (size_t i = 0; i < status.size(); i++) {
198 status_array[i] = status[i];
199 }
200 callback.Run(status_array.Pass());
201 }
202
136 void PermissionServiceImpl::CancelPendingOperations() { 203 void PermissionServiceImpl::CancelPendingOperations() {
137 DCHECK(context_->render_frame_host()); 204 DCHECK(context_->render_frame_host());
138 DCHECK(context_->GetBrowserContext()); 205 DCHECK(context_->GetBrowserContext());
139 206
140 PermissionManager* permission_manager = 207 PermissionManager* permission_manager =
141 context_->GetBrowserContext()->GetPermissionManager(); 208 context_->GetBrowserContext()->GetPermissionManager();
142 if (!permission_manager) 209 if (!permission_manager)
143 return; 210 return;
144 211
145 // Cancel pending requests. 212 // Cancel pending requests.
146 for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_); 213 for (RequestsMap::Iterator<PermissionPendingRequest> it(&pending_requests_);
147 !it.IsAtEnd(); it.Advance()) { 214 !it.IsAtEnd(); it.Advance()) {
148 permission_manager->CancelPermissionRequest( 215 it.GetCurrentValue()->Cancel(permission_manager,
149 it.GetCurrentValue()->permission, 216 context_->render_frame_host(),
150 context_->render_frame_host(), 217 it.GetCurrentKey());
151 it.GetCurrentKey(),
152 it.GetCurrentValue()->origin);
153 } 218 }
154 pending_requests_.Clear(); 219 pending_requests_.Clear();
155 220
156 // Cancel pending subscriptions. 221 // Cancel pending subscriptions.
157 for (SubscriptionsMap::Iterator<PendingSubscription> 222 for (SubscriptionsMap::Iterator<PendingSubscription>
158 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { 223 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) {
159 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( 224 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType(
160 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); 225 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin));
161 it.GetCurrentValue()->callback.reset(); 226 it.GetCurrentValue()->callback.reset();
162 permission_manager->UnsubscribePermissionStatusChange( 227 permission_manager->UnsubscribePermissionStatusChange(
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 346
282 PermissionStatusCallback callback = subscription->callback; 347 PermissionStatusCallback callback = subscription->callback;
283 348
284 subscription->callback.reset(); 349 subscription->callback.reset();
285 pending_subscriptions_.Remove(pending_subscription_id); 350 pending_subscriptions_.Remove(pending_subscription_id);
286 351
287 callback.Run(status); 352 callback.Run(status);
288 } 353 }
289 354
290 } // namespace content 355 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698