1 // Copyright 2015 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/shell/browser/layout_test/layout_test_permission_manager.h"
10 #include "base/callback.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/permission_type.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/shell/browser/layout_test/layout_test_content_browser_client.h"
15 #include "content/shell/browser/layout_test/layout_test_notification_manager.h"
19 struct LayoutTestPermissionManager::Subscription
{
20 PermissionDescription permission
;
21 base::Callback
<void(content::PermissionStatus
)> callback
;
22 PermissionStatus current_value
;
25 LayoutTestPermissionManager::PermissionDescription::PermissionDescription(
28 const GURL
& embedding_origin
)
31 embedding_origin(embedding_origin
) {
34 bool LayoutTestPermissionManager::PermissionDescription::operator==(
35 const PermissionDescription
& other
) const {
36 return type
== other
.type
&&
37 origin
== other
.origin
&&
38 embedding_origin
== other
.embedding_origin
;
41 bool LayoutTestPermissionManager::PermissionDescription::operator!=(
42 const PermissionDescription
& other
) const {
43 return !this->operator==(other
);
46 size_t LayoutTestPermissionManager::PermissionDescription::Hash::operator()(
47 const PermissionDescription
& description
) const {
48 size_t hash
= BASE_HASH_NAMESPACE::hash
<int>()(static_cast<int>(
50 hash
+= BASE_HASH_NAMESPACE::hash
<std::string
>()(
51 description
.embedding_origin
.spec());
52 hash
+= BASE_HASH_NAMESPACE::hash
<std::string
>()(
53 description
.origin
.spec());
57 LayoutTestPermissionManager::LayoutTestPermissionManager()
58 : PermissionManager() {
61 LayoutTestPermissionManager::~LayoutTestPermissionManager() {
64 void LayoutTestPermissionManager::RequestPermission(
65 PermissionType permission
,
66 RenderFrameHost
* render_frame_host
,
68 const GURL
& requesting_origin
,
70 const base::Callback
<void(PermissionStatus
)>& callback
) {
71 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
73 callback
.Run(GetPermissionStatus(
74 permission
, requesting_origin
,
75 WebContents::FromRenderFrameHost(render_frame_host
)
76 ->GetLastCommittedURL().GetOrigin()));
79 void LayoutTestPermissionManager::CancelPermissionRequest(
80 PermissionType permission
,
81 RenderFrameHost
* render_frame_host
,
83 const GURL
& requesting_origin
) {
84 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
87 void LayoutTestPermissionManager::ResetPermission(
88 PermissionType permission
,
89 const GURL
& requesting_origin
,
90 const GURL
& embedding_origin
) {
91 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
93 base::AutoLock
lock(permissions_lock_
);
95 auto it
= permissions_
.find(
96 PermissionDescription(permission
, requesting_origin
, embedding_origin
));
97 if (it
== permissions_
.end())
99 permissions_
.erase(it
);;
102 PermissionStatus
LayoutTestPermissionManager::GetPermissionStatus(
103 PermissionType permission
,
104 const GURL
& requesting_origin
,
105 const GURL
& embedding_origin
) {
106 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
) ||
107 BrowserThread::CurrentlyOn(BrowserThread::IO
));
109 base::AutoLock
lock(permissions_lock_
);
111 auto it
= permissions_
.find(
112 PermissionDescription(permission
, requesting_origin
, embedding_origin
));
113 if (it
== permissions_
.end())
114 return PERMISSION_STATUS_DENIED
;
118 void LayoutTestPermissionManager::RegisterPermissionUsage(
119 PermissionType permission
,
120 const GURL
& requesting_origin
,
121 const GURL
& embedding_origin
) {
122 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
125 int LayoutTestPermissionManager::SubscribePermissionStatusChange(
126 PermissionType permission
,
127 const GURL
& requesting_origin
,
128 const GURL
& embedding_origin
,
129 const base::Callback
<void(PermissionStatus
)>& callback
) {
130 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
132 Subscription
* subscription
= new Subscription();
133 subscription
->permission
=
134 PermissionDescription(permission
, requesting_origin
, embedding_origin
);
135 subscription
->callback
= callback
;
136 subscription
->current_value
=
137 GetPermissionStatus(permission
,
138 subscription
->permission
.origin
,
139 subscription
->permission
.embedding_origin
);
141 return subscriptions_
.Add(subscription
);
144 void LayoutTestPermissionManager::UnsubscribePermissionStatusChange(
145 int subscription_id
) {
146 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
148 // Whether |subscription_id| is known will be checked by the Remove() call.
149 subscriptions_
.Remove(subscription_id
);
152 void LayoutTestPermissionManager::SetPermission(PermissionType permission
,
153 PermissionStatus status
,
155 const GURL
& embedding_origin
) {
156 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
158 PermissionDescription
description(permission
, origin
, embedding_origin
);
160 base::AutoLock
lock(permissions_lock_
);
162 auto it
= permissions_
.find(description
);
163 if (it
== permissions_
.end()) {
164 permissions_
.insert(std::pair
<PermissionDescription
, PermissionStatus
>(
165 description
, status
));
170 OnPermissionChanged(description
, status
);
173 void LayoutTestPermissionManager::ResetPermissions() {
174 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
176 base::AutoLock
lock(permissions_lock_
);
177 permissions_
.clear();
180 void LayoutTestPermissionManager::OnPermissionChanged(
181 const PermissionDescription
& permission
,
182 PermissionStatus status
) {
183 std::list
<base::Closure
> callbacks
;
185 for (SubscriptionsMap::iterator
iter(&subscriptions_
);
186 !iter
.IsAtEnd(); iter
.Advance()) {
187 Subscription
* subscription
= iter
.GetCurrentValue();
188 if (subscription
->permission
!= permission
)
191 if (subscription
->current_value
== status
)
194 subscription
->current_value
= status
;
196 // Add the callback to |callbacks| which will be run after the loop to
197 // prevent re-entrance issues.
198 callbacks
.push_back(base::Bind(subscription
->callback
, status
));
201 for (const auto& callback
: callbacks
)
205 } // namespace content