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
3 // found in the LICENSE file.
5 #include "content/browser/permissions/permission_service_impl.h"
7 #include "content/public/browser/content_browser_client.h"
13 PermissionType
PermissionNameToPermissionType(PermissionName name
) {
15 case PERMISSION_NAME_GEOLOCATION
:
16 return PERMISSION_GEOLOCATION
;
17 case PERMISSION_NAME_MIDI_SYSEX
:
18 return PERMISSION_MIDI_SYSEX
;
19 case PERMISSION_NAME_NOTIFICATIONS
:
20 return PERMISSION_NOTIFICATIONS
;
21 case PERMISSION_NAME_PROTECTED_MEDIA_IDENTIFIER
:
22 return PERMISSION_PROTECTED_MEDIA_IDENTIFIER
;
26 return PERMISSION_NUM
;
29 } // anonymous namespace
31 PermissionServiceImpl::PendingRequest::PendingRequest(PermissionType permission
,
33 : permission(permission
),
37 PermissionServiceImpl::PermissionServiceImpl(PermissionServiceContext
* context
)
42 PermissionServiceImpl::~PermissionServiceImpl() {
45 void PermissionServiceImpl::OnConnectionError() {
46 context_
->ServiceHadConnectionError(this);
47 // After that call, |this| will be deleted.
50 void PermissionServiceImpl::RequestPermission(
51 PermissionName permission
,
52 const mojo::String
& origin
,
54 const mojo::Callback
<void(PermissionStatus
)>& callback
) {
55 // This condition is valid if the call is coming from a ChildThread instead of
56 // a RenderFrame. Some consumers of the service run in Workers and some in
57 // Frames. In the context of a Worker, it is not possible to show a
58 // permission prompt because there is no tab. In the context of a Frame, we
59 // can. Even if the call comes from a context where it is not possible to show
60 // any UI, we want to still return something relevant so the current
61 // permission status is returned.
62 if (!context_
->web_contents()) {
63 // There is no way to show a UI so the call will simply return the current
65 HasPermission(permission
, origin
, callback
);
69 PermissionType permission_type
= PermissionNameToPermissionType(permission
);
70 int request_id
= pending_requests_
.Add(
71 new PendingRequest(permission_type
, GURL(origin
)));
73 GetContentClient()->browser()->RequestPermission(
75 context_
->web_contents(),
78 user_gesture
, // TODO(mlamouri): should be removed (crbug.com/423770)
79 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse
,
80 weak_factory_
.GetWeakPtr(),
85 void PermissionServiceImpl::OnRequestPermissionResponse(
86 const mojo::Callback
<void(PermissionStatus
)>& callback
,
88 PermissionStatus status
) {
89 pending_requests_
.Remove(request_id
);
91 // TODO(mlamouri): this is not yet returning a tri-state value because it will
92 // require some further changes that will be dealt with in
93 // https://crrev.com/794203004/
94 status
= status
== PERMISSION_STATUS_DENIED
? PERMISSION_STATUS_ASK
: status
;
98 void PermissionServiceImpl::CancelPendingRequests() {
99 DCHECK(context_
->web_contents());
101 for (RequestsMap::Iterator
<PendingRequest
> it(&pending_requests_
);
102 !it
.IsAtEnd(); it
.Advance()) {
103 GetContentClient()->browser()->CancelPermissionRequest(
104 it
.GetCurrentValue()->permission
,
105 context_
->web_contents(),
107 it
.GetCurrentValue()->origin
);
110 pending_requests_
.Clear();
113 void PermissionServiceImpl::HasPermission(
114 PermissionName permission
,
115 const mojo::String
& origin
,
116 const mojo::Callback
<void(PermissionStatus
)>& callback
) {
117 DCHECK(context_
->GetBrowserContext());
119 callback
.Run(GetPermissionStatus(PermissionNameToPermissionType(permission
),
123 void PermissionServiceImpl::RevokePermission(
124 PermissionName permission
,
125 const mojo::String
& origin
,
126 const mojo::Callback
<void(PermissionStatus
)>& callback
) {
127 GURL
origin_url(origin
);
128 PermissionType permission_type
= PermissionNameToPermissionType(permission
);
129 PermissionStatus status
= GetPermissionStatus(permission_type
, origin_url
);
131 // Resetting the permission should only be possible if the permission is
133 if (status
!= PERMISSION_STATUS_GRANTED
) {
134 callback
.Run(status
);
138 ResetPermissionStatus(permission_type
, origin_url
);
140 callback
.Run(GetPermissionStatus(permission_type
, origin_url
));
143 PermissionStatus
PermissionServiceImpl::GetPermissionStatus(PermissionType type
,
145 // If the embedding_origin is empty we'll use |origin| instead.
146 GURL embedding_origin
= context_
->GetEmbeddingOrigin();
147 return GetContentClient()->browser()->GetPermissionStatus(
148 type
, context_
->GetBrowserContext(), origin
,
149 embedding_origin
.is_empty() ? origin
: embedding_origin
);
152 void PermissionServiceImpl::ResetPermissionStatus(PermissionType type
,
154 // If the embedding_origin is empty we'll use |origin| instead.
155 GURL embedding_origin
= context_
->GetEmbeddingOrigin();
156 GetContentClient()->browser()->ResetPermission(
157 type
, context_
->GetBrowserContext(), origin
,
158 embedding_origin
.is_empty() ? origin
: embedding_origin
);
161 } // namespace content