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