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

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: Rebase on master 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_EQ(1ul, vector.size());
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(PermissionManager::kNoPendingOperation), 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 might have been removed by the 136 // Check if the request still exists. It might have been removed by the
134 // callback if it was run synchronously. 137 // callback if it was run synchronously.
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 // TODO(lalitm,mlamouri): this is returning the current permission statuses 157 if (permissions.is_null()) {
148 // in order for the call to successfully return. It will be changed later. 158 callback.Run(mojo::Array<PermissionStatus>());
149 // See https://crbug.com/516626 159 return;
150 mojo::Array<PermissionStatus> result(permissions.size()); 160 }
151 for (size_t i = 0; i < permissions.size(); ++i) 161
152 result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin)); 162 // This condition is valid if the call is coming from a ChildThread instead of
153 callback.Run(result.Pass()); 163 // a RenderFrame. Some consumers of the service run in Workers and some in
164 // Frames. In the context of a Worker, it is not possible to show a
165 // permission prompt because there is no tab. In the context of a Frame, we
166 // can. Even if the call comes from a context where it is not possible to show
167 // any UI, we want to still return something relevant so the current
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;
154 } 202 }
155 203
156 void PermissionServiceImpl::OnRequestPermissionResponse( 204 void PermissionServiceImpl::OnRequestPermissionsResponse(
157 int request_id, 205 int pending_request_id,
158 PermissionStatus status) { 206 const std::vector<PermissionStatus>& result) {
159 PendingRequest* request = pending_requests_.Lookup(request_id); 207 PendingRequest* request = pending_requests_.Lookup(pending_request_id);
160 PermissionStatusCallback callback(request->callback); 208 PermissionsStatusCallback callback(request->callback);
161 request->callback.reset(); 209 request->callback.reset();
162 pending_requests_.Remove(request_id); 210 pending_requests_.Remove(pending_request_id);
163 callback.Run(status); 211 callback.Run(mojo::Array<PermissionStatus>::From(result));
164 } 212 }
165 213
166 void PermissionServiceImpl::CancelPendingOperations() { 214 void PermissionServiceImpl::CancelPendingOperations() {
167 DCHECK(context_->render_frame_host());
168 DCHECK(context_->GetBrowserContext()); 215 DCHECK(context_->GetBrowserContext());
169 216
170 PermissionManager* permission_manager = 217 PermissionManager* permission_manager =
171 context_->GetBrowserContext()->GetPermissionManager(); 218 context_->GetBrowserContext()->GetPermissionManager();
172 if (!permission_manager) 219 if (!permission_manager)
173 return; 220 return;
174 221
175 // Cancel pending requests. 222 // Cancel pending requests.
176 for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_); 223 for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_);
177 !it.IsAtEnd(); it.Advance()) { 224 !it.IsAtEnd(); it.Advance()) {
178 permission_manager->CancelPermissionRequest( 225 permission_manager->CancelPermissionRequest(
179 it.GetCurrentValue()->permission, 226 it.GetCurrentValue()->id);
180 context_->render_frame_host(),
181 it.GetCurrentKey(),
182 it.GetCurrentValue()->origin);
183 } 227 }
184 pending_requests_.Clear(); 228 pending_requests_.Clear();
185 229
186 // Cancel pending subscriptions. 230 // Cancel pending subscriptions.
187 for (SubscriptionsMap::Iterator<PendingSubscription> 231 for (SubscriptionsMap::Iterator<PendingSubscription>
188 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { 232 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) {
189 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( 233 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType(
190 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); 234 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin));
191 it.GetCurrentValue()->callback.reset(); 235 it.GetCurrentValue()->callback.reset();
192 permission_manager->UnsubscribePermissionStatusChange( 236 permission_manager->UnsubscribePermissionStatusChange(
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 355
312 PermissionStatusCallback callback = subscription->callback; 356 PermissionStatusCallback callback = subscription->callback;
313 357
314 subscription->callback.reset(); 358 subscription->callback.reset();
315 pending_subscriptions_.Remove(pending_subscription_id); 359 pending_subscriptions_.Remove(pending_subscription_id);
316 360
317 callback.Run(status); 361 callback.Run(status);
318 } 362 }
319 363
320 } // namespace content 364 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/permissions/permission_service_impl.h ('k') | content/public/browser/permission_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698