OLD | NEW |
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 Loading... |
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(vector.size(), 1ul); |
| 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 return; |
| 63 |
| 64 mojo::Array<PermissionStatus> result = |
| 65 mojo::Array<PermissionStatus>::New(request_count); |
| 66 for (int i = 0; i < request_count; ++i) |
| 67 result[i] = PERMISSION_STATUS_DENIED; |
| 68 callback.Run(result.Pass()); |
57 } | 69 } |
58 | 70 |
59 PermissionServiceImpl::PendingSubscription::PendingSubscription( | 71 PermissionServiceImpl::PendingSubscription::PendingSubscription( |
60 PermissionType permission, | 72 PermissionType permission, |
61 const GURL& origin, | 73 const GURL& origin, |
62 const PermissionStatusCallback& callback) | 74 const PermissionStatusCallback& callback) |
63 : id(-1), | 75 : id(-1), |
64 permission(permission), | 76 permission(permission), |
65 origin(origin), | 77 origin(origin), |
66 callback(callback) { | 78 callback(callback) { |
(...skipping 29 matching lines...) Expand all Loading... |
96 const mojo::String& origin, | 108 const mojo::String& origin, |
97 bool user_gesture, | 109 bool user_gesture, |
98 const PermissionStatusCallback& callback) { | 110 const PermissionStatusCallback& callback) { |
99 // This condition is valid if the call is coming from a ChildThread instead of | 111 // 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 | 112 // 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 | 113 // 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 | 114 // 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 | 115 // 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 | 116 // any UI, we want to still return something relevant so the current |
105 // permission status is returned. | 117 // permission status is returned. |
106 if (!context_->render_frame_host()) { | 118 BrowserContext* browser_context = context_->GetBrowserContext(); |
107 // There is no way to show a UI so the call will simply return the current | 119 DCHECK(browser_context); |
108 // permission. | 120 if (!context_->render_frame_host() || |
109 HasPermission(permission, origin, callback); | 121 !browser_context->GetPermissionManager()) { |
| 122 callback.Run(GetPermissionStatusFromName(permission, GURL(origin))); |
110 return; | 123 return; |
111 } | 124 } |
112 | 125 |
113 BrowserContext* browser_context = context_->GetBrowserContext(); | 126 int pending_request_id = pending_requests_.Add(new PendingRequest( |
114 DCHECK(browser_context); | 127 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( | 128 int id = browser_context->GetPermissionManager()->RequestPermission( |
125 permission_type, | 129 PermissionNameToPermissionType(permission), |
126 context_->render_frame_host(), | 130 context_->render_frame_host(), |
127 GURL(origin), | 131 GURL(origin), |
128 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) | 132 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) |
129 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, | 133 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, |
130 weak_factory_.GetWeakPtr(), | 134 weak_factory_.GetWeakPtr(), |
131 pending_request_id)); | 135 pending_request_id)); |
132 | 136 |
133 // Check if the request still exists. It might have been removed by the | 137 // Check if the request still exists. It might have been removed by the |
134 // callback if it was run synchronously. | 138 // callback if it was run synchronously. |
135 PendingRequest* pending_request = pending_requests_.Lookup( | 139 PendingRequest* pending_request = pending_requests_.Lookup( |
136 pending_request_id); | 140 pending_request_id); |
137 if (!pending_request) | 141 if (!pending_request) |
138 return; | 142 return; |
139 pending_request->id = id; | 143 pending_request->id = id; |
140 } | 144 } |
141 | 145 |
| 146 void PermissionServiceImpl::OnRequestPermissionResponse( |
| 147 int pending_request_id, |
| 148 PermissionStatus status) { |
| 149 OnRequestPermissionsResponse(pending_request_id, |
| 150 std::vector<PermissionStatus>(1, status)); |
| 151 } |
| 152 |
142 void PermissionServiceImpl::RequestPermissions( | 153 void PermissionServiceImpl::RequestPermissions( |
143 mojo::Array<PermissionName> permissions, | 154 mojo::Array<PermissionName> permissions, |
144 const mojo::String& origin, | 155 const mojo::String& origin, |
145 bool user_gesture, | 156 bool user_gesture, |
146 const PermissionsStatusCallback& callback) { | 157 const PermissionsStatusCallback& callback) { |
147 // TODO(lalitm,mlamouri): this is returning the current permission statuses | 158 if (permissions.is_null()) { |
148 // in order for the call to successfully return. It will be changed later. | 159 callback.Run(mojo::Array<PermissionStatus>()); |
149 // See https://crbug.com/516626 | 160 return; |
150 mojo::Array<PermissionStatus> result(permissions.size()); | 161 } |
151 for (size_t i = 0; i < permissions.size(); ++i) | 162 |
152 result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin)); | 163 // This condition is valid if the call is coming from a ChildThread instead of |
153 callback.Run(result.Pass()); | 164 // a RenderFrame. Some consumers of the service run in Workers and some in |
| 165 // Frames. In the context of a Worker, it is not possible to show a |
| 166 // permission prompt because there is no tab. In the context of a Frame, we |
| 167 // can. Even if the call comes from a context where it is not possible to show |
| 168 // any UI, we want to still return something relevant so the current |
| 169 // permission status is returned for each permission. |
| 170 BrowserContext* browser_context = context_->GetBrowserContext(); |
| 171 DCHECK(browser_context); |
| 172 if (!context_->render_frame_host() || |
| 173 !browser_context->GetPermissionManager()) { |
| 174 mojo::Array<PermissionStatus> result(permissions.size()); |
| 175 for (size_t i = 0; i < permissions.size(); ++i) |
| 176 result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin)); |
| 177 callback.Run(result.Pass()); |
| 178 return; |
| 179 } |
| 180 |
| 181 std::vector<PermissionType> types(permissions.size()); |
| 182 for (size_t i = 0; i < types.size(); ++i) |
| 183 types[i] = PermissionNameToPermissionType(permissions[i]); |
| 184 |
| 185 int pending_request_id = pending_requests_.Add( |
| 186 new PendingRequest(callback, permissions.size())); |
| 187 int id = browser_context->GetPermissionManager()->RequestPermissions( |
| 188 types, |
| 189 context_->render_frame_host(), |
| 190 GURL(origin), |
| 191 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) |
| 192 base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse, |
| 193 weak_factory_.GetWeakPtr(), |
| 194 pending_request_id)); |
| 195 |
| 196 // Check if the request still exists. It may have been removed by the |
| 197 // the response callback. |
| 198 PendingRequest* pending_request = pending_requests_.Lookup( |
| 199 pending_request_id); |
| 200 if (!pending_request) |
| 201 return; |
| 202 pending_request->id = id; |
154 } | 203 } |
155 | 204 |
156 void PermissionServiceImpl::OnRequestPermissionResponse( | 205 void PermissionServiceImpl::OnRequestPermissionsResponse( |
157 int request_id, | 206 int pending_request_id, |
158 PermissionStatus status) { | 207 const std::vector<PermissionStatus>& result) { |
159 PendingRequest* request = pending_requests_.Lookup(request_id); | 208 PendingRequest* request = pending_requests_.Lookup(pending_request_id); |
160 PermissionStatusCallback callback(request->callback); | 209 PermissionsStatusCallback callback(request->callback); |
161 request->callback.reset(); | 210 request->callback.reset(); |
162 pending_requests_.Remove(request_id); | 211 pending_requests_.Remove(pending_request_id); |
163 callback.Run(status); | 212 callback.Run(mojo::Array<PermissionStatus>::From(result)); |
164 } | 213 } |
165 | 214 |
166 void PermissionServiceImpl::CancelPendingOperations() { | 215 void PermissionServiceImpl::CancelPendingOperations() { |
167 DCHECK(context_->GetBrowserContext()); | 216 DCHECK(context_->GetBrowserContext()); |
168 | 217 |
169 PermissionManager* permission_manager = | 218 PermissionManager* permission_manager = |
170 context_->GetBrowserContext()->GetPermissionManager(); | 219 context_->GetBrowserContext()->GetPermissionManager(); |
171 if (!permission_manager) | 220 if (!permission_manager) |
172 return; | 221 return; |
173 | 222 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 | 356 |
308 PermissionStatusCallback callback = subscription->callback; | 357 PermissionStatusCallback callback = subscription->callback; |
309 | 358 |
310 subscription->callback.reset(); | 359 subscription->callback.reset(); |
311 pending_subscriptions_.Remove(pending_subscription_id); | 360 pending_subscriptions_.Remove(pending_subscription_id); |
312 | 361 |
313 callback.Run(status); | 362 callback.Run(status); |
314 } | 363 } |
315 | 364 |
316 } // namespace content | 365 } // namespace content |
OLD | NEW |