| Index: content/browser/permissions/permission_service_impl.cc
|
| diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc
|
| index 4d16c06c43b172a8543422b6e13e349370b7ab37..32c7c3a361697f45d322b8fd6e5f73d31e176f17 100644
|
| --- a/content/browser/permissions/permission_service_impl.cc
|
| +++ b/content/browser/permissions/permission_service_impl.cc
|
| @@ -39,21 +39,33 @@ PermissionType PermissionNameToPermissionType(PermissionName name) {
|
| return PermissionType::NUM;
|
| }
|
|
|
| +// This function allows the usage of the the multiple request map
|
| +// with single requests.
|
| +void PermissionRequestResponseCallbackWrapper(
|
| + const mojo::Callback<void(PermissionStatus)>& callback,
|
| + const mojo::Array<PermissionStatus>& vector) {
|
| + DCHECK_EQ(vector.size(), 1ul);
|
| + callback.Run(vector[0]);
|
| +}
|
| +
|
| } // anonymous namespace
|
|
|
| PermissionServiceImpl::PendingRequest::PendingRequest(
|
| - PermissionType permission,
|
| - const GURL& origin,
|
| - const PermissionStatusCallback& callback)
|
| - : id(PermissionManager::kNoPendingOperation),
|
| - permission(permission),
|
| - origin(origin),
|
| - callback(callback) {
|
| + const PermissionsStatusCallback& callback,
|
| + int request_count)
|
| + : callback(callback),
|
| + request_count(request_count) {
|
| }
|
|
|
| PermissionServiceImpl::PendingRequest::~PendingRequest() {
|
| - if (!callback.is_null())
|
| - callback.Run(PERMISSION_STATUS_ASK);
|
| + if (callback.is_null())
|
| + return;
|
| +
|
| + mojo::Array<PermissionStatus> result =
|
| + mojo::Array<PermissionStatus>::New(request_count);
|
| + for (int i = 0; i < request_count; ++i)
|
| + result[i] = PERMISSION_STATUS_DENIED;
|
| + callback.Run(result.Pass());
|
| }
|
|
|
| PermissionServiceImpl::PendingSubscription::PendingSubscription(
|
| @@ -103,26 +115,18 @@ void PermissionServiceImpl::RequestPermission(
|
| // can. Even if the call comes from a context where it is not possible to show
|
| // any UI, we want to still return something relevant so the current
|
| // permission status is returned.
|
| - if (!context_->render_frame_host()) {
|
| - // There is no way to show a UI so the call will simply return the current
|
| - // permission.
|
| - HasPermission(permission, origin, callback);
|
| - return;
|
| - }
|
| -
|
| BrowserContext* browser_context = context_->GetBrowserContext();
|
| DCHECK(browser_context);
|
| - if (!browser_context->GetPermissionManager()) {
|
| - callback.Run(content::PERMISSION_STATUS_DENIED);
|
| + if (!context_->render_frame_host() ||
|
| + !browser_context->GetPermissionManager()) {
|
| + callback.Run(GetPermissionStatusFromName(permission, GURL(origin)));
|
| return;
|
| }
|
|
|
| - PermissionType permission_type = PermissionNameToPermissionType(permission);
|
| - int pending_request_id = pending_requests_.Add(
|
| - new PendingRequest(permission_type, GURL(origin), callback));
|
| -
|
| + int pending_request_id = pending_requests_.Add(new PendingRequest(
|
| + base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1));
|
| int id = browser_context->GetPermissionManager()->RequestPermission(
|
| - permission_type,
|
| + PermissionNameToPermissionType(permission),
|
| context_->render_frame_host(),
|
| GURL(origin),
|
| user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
|
| @@ -139,28 +143,73 @@ void PermissionServiceImpl::RequestPermission(
|
| pending_request->id = id;
|
| }
|
|
|
| +void PermissionServiceImpl::OnRequestPermissionResponse(
|
| + int pending_request_id,
|
| + PermissionStatus status) {
|
| + OnRequestPermissionsResponse(pending_request_id,
|
| + std::vector<PermissionStatus>(1, status));
|
| +}
|
| +
|
| void PermissionServiceImpl::RequestPermissions(
|
| mojo::Array<PermissionName> permissions,
|
| const mojo::String& origin,
|
| bool user_gesture,
|
| const PermissionsStatusCallback& callback) {
|
| - // TODO(lalitm,mlamouri): this is returning the current permission statuses
|
| - // in order for the call to successfully return. It will be changed later.
|
| - // See https://crbug.com/516626
|
| - mojo::Array<PermissionStatus> result(permissions.size());
|
| - for (size_t i = 0; i < permissions.size(); ++i)
|
| - result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin));
|
| - callback.Run(result.Pass());
|
| + if (permissions.is_null()) {
|
| + callback.Run(mojo::Array<PermissionStatus>());
|
| + return;
|
| + }
|
| +
|
| + // This condition is valid if the call is coming from a ChildThread instead of
|
| + // a RenderFrame. Some consumers of the service run in Workers and some in
|
| + // Frames. In the context of a Worker, it is not possible to show a
|
| + // permission prompt because there is no tab. In the context of a Frame, we
|
| + // can. Even if the call comes from a context where it is not possible to show
|
| + // any UI, we want to still return something relevant so the current
|
| + // permission status is returned for each permission.
|
| + BrowserContext* browser_context = context_->GetBrowserContext();
|
| + DCHECK(browser_context);
|
| + if (!context_->render_frame_host() ||
|
| + !browser_context->GetPermissionManager()) {
|
| + mojo::Array<PermissionStatus> result(permissions.size());
|
| + for (size_t i = 0; i < permissions.size(); ++i)
|
| + result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin));
|
| + callback.Run(result.Pass());
|
| + return;
|
| + }
|
| +
|
| + std::vector<PermissionType> types(permissions.size());
|
| + for (size_t i = 0; i < types.size(); ++i)
|
| + types[i] = PermissionNameToPermissionType(permissions[i]);
|
| +
|
| + int pending_request_id = pending_requests_.Add(
|
| + new PendingRequest(callback, permissions.size()));
|
| + int id = browser_context->GetPermissionManager()->RequestPermissions(
|
| + types,
|
| + context_->render_frame_host(),
|
| + GURL(origin),
|
| + user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770)
|
| + base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse,
|
| + weak_factory_.GetWeakPtr(),
|
| + pending_request_id));
|
| +
|
| + // Check if the request still exists. It may have been removed by the
|
| + // the response callback.
|
| + PendingRequest* pending_request = pending_requests_.Lookup(
|
| + pending_request_id);
|
| + if (!pending_request)
|
| + return;
|
| + pending_request->id = id;
|
| }
|
|
|
| -void PermissionServiceImpl::OnRequestPermissionResponse(
|
| - int request_id,
|
| - PermissionStatus status) {
|
| - PendingRequest* request = pending_requests_.Lookup(request_id);
|
| - PermissionStatusCallback callback(request->callback);
|
| +void PermissionServiceImpl::OnRequestPermissionsResponse(
|
| + int pending_request_id,
|
| + const std::vector<PermissionStatus>& result) {
|
| + PendingRequest* request = pending_requests_.Lookup(pending_request_id);
|
| + PermissionsStatusCallback callback(request->callback);
|
| request->callback.reset();
|
| - pending_requests_.Remove(request_id);
|
| - callback.Run(status);
|
| + pending_requests_.Remove(pending_request_id);
|
| + callback.Run(mojo::Array<PermissionStatus>::From(result));
|
| }
|
|
|
| void PermissionServiceImpl::CancelPendingOperations() {
|
|
|