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

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: Rebase on top of other change 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_request.h"
8 #include "content/public/browser/browser_context.h" 9 #include "content/public/browser/browser_context.h"
9 #include "content/public/browser/permission_manager.h" 10 #include "content/public/browser/permission_manager.h"
10 #include "content/public/browser/permission_type.h" 11 #include "content/public/browser/permission_type.h"
11 12
12 namespace content { 13 namespace content {
13 14
14 namespace { 15 namespace {
15 16
16 PermissionType PermissionNameToPermissionType(PermissionName name) { 17 PermissionType PermissionNameToPermissionType(PermissionName name) {
17 switch(name) { 18 switch(name) {
(...skipping 10 matching lines...) Expand all
28 case PERMISSION_NAME_PROTECTED_MEDIA_IDENTIFIER: 29 case PERMISSION_NAME_PROTECTED_MEDIA_IDENTIFIER:
29 return PermissionType::PROTECTED_MEDIA_IDENTIFIER; 30 return PermissionType::PROTECTED_MEDIA_IDENTIFIER;
30 case PERMISSION_NAME_DURABLE_STORAGE: 31 case PERMISSION_NAME_DURABLE_STORAGE:
31 return PermissionType::DURABLE_STORAGE; 32 return PermissionType::DURABLE_STORAGE;
32 } 33 }
33 34
34 NOTREACHED(); 35 NOTREACHED();
35 return PermissionType::NUM; 36 return PermissionType::NUM;
36 } 37 }
37 38
39 void PermissionRequestResponseCallbackWrapper(
40 const mojo::Callback<void(PermissionStatus)>& callback,
41 const mojo::Array<PermissionStatus>& vector) {
42 DCHECK(vector.size() == 1);
43 callback.Run(vector[0]);
44 }
45
38 } // anonymous namespace 46 } // anonymous namespace
39 47
40 PermissionServiceImpl::PendingRequest::PendingRequest(
41 PermissionType permission,
42 const GURL& origin,
43 const PermissionStatusCallback& callback)
44 : permission(permission),
45 origin(origin),
46 callback(callback) {
47 }
48
49 PermissionServiceImpl::PendingRequest::~PendingRequest() {
50 if (!callback.is_null())
51 callback.Run(PERMISSION_STATUS_ASK);
52 }
53
54 PermissionServiceImpl::PendingSubscription::PendingSubscription( 48 PermissionServiceImpl::PendingSubscription::PendingSubscription(
55 PermissionType permission, 49 PermissionType permission,
56 const GURL& origin, 50 const GURL& origin,
57 const PermissionStatusCallback& callback) 51 const PermissionStatusCallback& callback)
58 : id(-1), 52 : id(-1),
59 permission(permission), 53 permission(permission),
60 origin(origin), 54 origin(origin),
61 callback(callback) { 55 callback(callback) {
62 } 56 }
63 57
(...skipping 20 matching lines...) Expand all
84 void PermissionServiceImpl::OnConnectionError() { 78 void PermissionServiceImpl::OnConnectionError() {
85 context_->ServiceHadConnectionError(this); 79 context_->ServiceHadConnectionError(this);
86 // After that call, |this| will be deleted. 80 // After that call, |this| will be deleted.
87 } 81 }
88 82
89 void PermissionServiceImpl::RequestPermission( 83 void PermissionServiceImpl::RequestPermission(
90 PermissionName permission, 84 PermissionName permission,
91 const mojo::String& origin, 85 const mojo::String& origin,
92 bool user_gesture, 86 bool user_gesture,
93 const PermissionStatusCallback& callback) { 87 const PermissionStatusCallback& callback) {
88 mojo::Array<PermissionName> permissions = mojo::Array<PermissionName>::New(1);
89 permissions[0] = permission;
90
91 RequestPermissionInternal(
92 permissions.Pass(),
93 origin,
94 user_gesture,
95 base::Bind(&PermissionRequestResponseCallbackWrapper,
96 callback));
97 }
98
99 void PermissionServiceImpl::RequestBatchPermission(
100 mojo::Array<PermissionName> permissions,
101 const mojo::String& origin,
102 bool user_gesture,
103 const BatchPermissionStatusCallback& callback) {
104 RequestPermissionInternal(permissions.Pass(), origin, user_gesture, callback);
105 }
106
107 void PermissionServiceImpl::RequestPermissionInternal(
108 mojo::Array<PermissionName> permissions,
109 const mojo::String& origin,
110 bool user_gesture,
111 const BatchPermissionStatusCallback& callback) {
112 if (permissions.is_null()) {
mlamouri (slow - plz ping) 2015/08/21 10:24:41 When would that happen?
Lalit Maganti 2015/08/21 12:56:00 Compromised renderer process is the only thing I c
113 callback.Run(mojo::Array<PermissionStatus>());
114 return;
115 }
116
94 // This condition is valid if the call is coming from a ChildThread instead of 117 // This condition is valid if the call is coming from a ChildThread instead of
95 // a RenderFrame. Some consumers of the service run in Workers and some in 118 // a RenderFrame. Some consumers of the service run in Workers and some in
96 // Frames. In the context of a Worker, it is not possible to show a 119 // Frames. In the context of a Worker, it is not possible to show a
97 // permission prompt because there is no tab. In the context of a Frame, we 120 // permission prompt because there is no tab. In the context of a Frame, we
98 // can. Even if the call comes from a context where it is not possible to show 121 // can. Even if the call comes from a context where it is not possible to show
99 // any UI, we want to still return something relevant so the current 122 // any UI, we want to still return something relevant so the current
100 // permission status is returned. 123 // permission status is returned for each permission.
101 if (!context_->render_frame_host()) { 124 if (!context_->render_frame_host()) {
102 // There is no way to show a UI so the call will simply return the current 125 mojo::Array<PermissionStatus> result(permissions.size());
103 // permission. 126 for (size_t i = 0; i < permissions.size(); ++i) {
104 HasPermission(permission, origin, callback); 127 result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin));
128 }
mlamouri (slow - plz ping) 2015/08/21 10:24:41 style: remove { }
Lalit Maganti 2015/08/25 16:58:27 Done.
129 callback.Run(result.Pass());
105 return; 130 return;
106 } 131 }
107 132
108 BrowserContext* browser_context = context_->GetBrowserContext(); 133 BrowserContext* browser_context = context_->GetBrowserContext();
109 DCHECK(browser_context); 134 DCHECK(browser_context);
110 if (!browser_context->GetPermissionManager()) { 135 if (!browser_context->GetPermissionManager()) {
111 callback.Run(content::PERMISSION_STATUS_DENIED); 136 mojo::Array<PermissionStatus> result(permissions.size());
137 for (size_t i = 0; i < permissions.size(); ++i) {
138 result[i] = PERMISSION_STATUS_DENIED;
139 }
mlamouri (slow - plz ping) 2015/08/21 10:24:41 ditto
Lalit Maganti 2015/08/25 16:58:27 Done.
140 callback.Run(result.Pass());
112 return; 141 return;
113 } 142 }
114 143
115 PermissionType permission_type = PermissionNameToPermissionType(permission); 144 std::vector<PermissionType> permission_types;
145 permission_types.reserve(permissions.size());
146 for (size_t i = 0; i < permissions.size(); ++i) {
147 permission_types.push_back(
148 PermissionNameToPermissionType(permissions[i]));
149 }
116 int request_id = pending_requests_.Add( 150 int request_id = pending_requests_.Add(
117 new PendingRequest(permission_type, GURL(origin), callback)); 151 new PermissionPendingRequest(callback, permissions.size()));
118 152
119 browser_context->GetPermissionManager()->RequestPermission( 153 browser_context->GetPermissionManager()->RequestPermission(
120 permission_type, 154 permission_types,
121 context_->render_frame_host(), 155 context_->render_frame_host(),
122 request_id, 156 request_id,
123 GURL(origin), 157 GURL(origin),
124 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) 158 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
125 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, 159 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse,
126 weak_factory_.GetWeakPtr(), 160 weak_factory_.GetWeakPtr(),
127 request_id)); 161 request_id));
128 } 162 }
129 163
130 void PermissionServiceImpl::OnRequestPermissionResponse( 164 void PermissionServiceImpl::OnRequestPermissionResponse(
131 int request_id, 165 int request_id,
132 PermissionStatus status) { 166 const std::vector<PermissionStatus>& status) {
133 PendingRequest* request = pending_requests_.Lookup(request_id); 167 PermissionPendingRequest* request = pending_requests_.Lookup(request_id);
134 PermissionStatusCallback callback(request->callback); 168 BatchPermissionStatusCallback callback(request->callback());
135 request->callback.reset(); 169
170 request->callback().reset();
136 pending_requests_.Remove(request_id); 171 pending_requests_.Remove(request_id);
137 callback.Run(status); 172
173 mojo::Array<PermissionStatus> status_array(status.size());
174 for (size_t i = 0; i < status.size(); i++)
175 status_array[i] = status[i];
176 callback.Run(status_array.Pass());
138 } 177 }
139 178
140 void PermissionServiceImpl::CancelPendingOperations() { 179 void PermissionServiceImpl::CancelPendingOperations() {
141 DCHECK(context_->render_frame_host()); 180 DCHECK(context_->render_frame_host());
142 DCHECK(context_->GetBrowserContext()); 181 DCHECK(context_->GetBrowserContext());
143 182
144 PermissionManager* permission_manager = 183 PermissionManager* permission_manager =
145 context_->GetBrowserContext()->GetPermissionManager(); 184 context_->GetBrowserContext()->GetPermissionManager();
146 if (!permission_manager) 185 if (!permission_manager)
147 return; 186 return;
148 187
149 // Cancel pending requests. 188 // Cancel pending requests.
150 for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_); 189 for (RequestsMap::Iterator<PermissionPendingRequest> it(&pending_requests_);
151 !it.IsAtEnd(); it.Advance()) { 190 !it.IsAtEnd(); it.Advance()) {
152 permission_manager->CancelPermissionRequest( 191 permission_manager->CancelPermissionRequest(context_->render_frame_host(),
153 it.GetCurrentValue()->permission, 192 it.GetCurrentKey());
154 context_->render_frame_host(),
155 it.GetCurrentKey(),
156 it.GetCurrentValue()->origin);
157 } 193 }
158 pending_requests_.Clear(); 194 pending_requests_.Clear();
159 195
160 // Cancel pending subscriptions. 196 // Cancel pending subscriptions.
161 for (SubscriptionsMap::Iterator<PendingSubscription> 197 for (SubscriptionsMap::Iterator<PendingSubscription>
162 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { 198 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) {
163 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( 199 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType(
164 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); 200 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin));
165 it.GetCurrentValue()->callback.reset(); 201 it.GetCurrentValue()->callback.reset();
166 permission_manager->UnsubscribePermissionStatusChange( 202 permission_manager->UnsubscribePermissionStatusChange(
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 321
286 PermissionStatusCallback callback = subscription->callback; 322 PermissionStatusCallback callback = subscription->callback;
287 323
288 subscription->callback.reset(); 324 subscription->callback.reset();
289 pending_subscriptions_.Remove(pending_subscription_id); 325 pending_subscriptions_.Remove(pending_subscription_id);
290 326
291 callback.Run(status); 327 callback.Run(status);
292 } 328 }
293 329
294 } // namespace content 330 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698