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 18 matching lines...) Expand all Loading... | |
29 | 29 |
30 NOTREACHED(); | 30 NOTREACHED(); |
31 return PermissionType::NUM; | 31 return PermissionType::NUM; |
32 } | 32 } |
33 | 33 |
34 } // anonymous namespace | 34 } // anonymous namespace |
35 | 35 |
36 PermissionServiceImpl::PendingRequest::PendingRequest( | 36 PermissionServiceImpl::PendingRequest::PendingRequest( |
37 PermissionType permission, | 37 PermissionType permission, |
38 const GURL& origin, | 38 const GURL& origin, |
39 const mojo::Callback<void(PermissionStatus)>& callback) | 39 const PermissionStatusCallback& callback) |
40 : permission(permission), | 40 : permission(permission), |
41 origin(origin), | 41 origin(origin), |
42 callback(callback) { | 42 callback(callback) { |
43 } | 43 } |
44 | 44 |
45 PermissionServiceImpl::PendingRequest::~PendingRequest() { | 45 PermissionServiceImpl::PendingRequest::~PendingRequest() { |
46 if (!callback.is_null()) { | 46 if (!callback.is_null()) { |
47 callback.Run(PERMISSION_STATUS_ASK); | 47 callback.Run(PERMISSION_STATUS_ASK); |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 PermissionServiceImpl::PendingSubscription::PendingSubscription( | |
52 PermissionType permission, | |
53 const GURL& origin, | |
54 const PermissionStatusCallback& callback) | |
55 : permission(permission), | |
56 origin(origin), | |
57 callback(callback) { | |
58 } | |
59 | |
60 PermissionServiceImpl::PendingSubscription::~PendingSubscription() { | |
61 DCHECK(callback.is_null()); | |
62 } | |
63 | |
51 PermissionServiceImpl::PermissionServiceImpl(PermissionServiceContext* context) | 64 PermissionServiceImpl::PermissionServiceImpl(PermissionServiceContext* context) |
52 : context_(context), | 65 : context_(context), |
53 weak_factory_(this) { | 66 weak_factory_(this) { |
54 } | 67 } |
55 | 68 |
56 PermissionServiceImpl::~PermissionServiceImpl() { | 69 PermissionServiceImpl::~PermissionServiceImpl() { |
70 DCHECK(pending_requests_.IsEmpty()); | |
71 DCHECK(pending_subscriptions_.IsEmpty()); | |
57 } | 72 } |
58 | 73 |
59 void PermissionServiceImpl::OnConnectionError() { | 74 void PermissionServiceImpl::OnConnectionError() { |
60 context_->ServiceHadConnectionError(this); | 75 context_->ServiceHadConnectionError(this); |
61 // After that call, |this| will be deleted. | 76 // After that call, |this| will be deleted. |
62 } | 77 } |
63 | 78 |
64 void PermissionServiceImpl::RequestPermission( | 79 void PermissionServiceImpl::RequestPermission( |
65 PermissionName permission, | 80 PermissionName permission, |
66 const mojo::String& origin, | 81 const mojo::String& origin, |
67 bool user_gesture, | 82 bool user_gesture, |
68 const mojo::Callback<void(PermissionStatus)>& callback) { | 83 const PermissionStatusCallback& callback) { |
69 // This condition is valid if the call is coming from a ChildThread instead of | 84 // This condition is valid if the call is coming from a ChildThread instead of |
70 // a RenderFrame. Some consumers of the service run in Workers and some in | 85 // a RenderFrame. Some consumers of the service run in Workers and some in |
71 // Frames. In the context of a Worker, it is not possible to show a | 86 // Frames. In the context of a Worker, it is not possible to show a |
72 // permission prompt because there is no tab. In the context of a Frame, we | 87 // permission prompt because there is no tab. In the context of a Frame, we |
73 // can. Even if the call comes from a context where it is not possible to show | 88 // can. Even if the call comes from a context where it is not possible to show |
74 // any UI, we want to still return something relevant so the current | 89 // any UI, we want to still return something relevant so the current |
75 // permission status is returned. | 90 // permission status is returned. |
76 if (!context_->web_contents()) { | 91 if (!context_->web_contents()) { |
77 // There is no way to show a UI so the call will simply return the current | 92 // There is no way to show a UI so the call will simply return the current |
78 // permission. | 93 // permission. |
(...skipping 20 matching lines...) Expand all Loading... | |
99 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) | 114 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) |
100 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, | 115 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, |
101 weak_factory_.GetWeakPtr(), | 116 weak_factory_.GetWeakPtr(), |
102 request_id)); | 117 request_id)); |
103 } | 118 } |
104 | 119 |
105 void PermissionServiceImpl::OnRequestPermissionResponse( | 120 void PermissionServiceImpl::OnRequestPermissionResponse( |
106 int request_id, | 121 int request_id, |
107 PermissionStatus status) { | 122 PermissionStatus status) { |
108 PendingRequest* request = pending_requests_.Lookup(request_id); | 123 PendingRequest* request = pending_requests_.Lookup(request_id); |
109 mojo::Callback<void(PermissionStatus)> callback(request->callback); | 124 PermissionStatusCallback callback(request->callback); |
110 request->callback.reset(); | 125 request->callback.reset(); |
111 pending_requests_.Remove(request_id); | 126 pending_requests_.Remove(request_id); |
112 callback.Run(status); | 127 callback.Run(status); |
113 } | 128 } |
114 | 129 |
115 void PermissionServiceImpl::CancelPendingRequests() { | 130 void PermissionServiceImpl::CancelPendingOperations() { |
116 DCHECK(context_->web_contents()); | 131 DCHECK(context_->web_contents()); |
117 DCHECK(context_->GetBrowserContext()); | 132 DCHECK(context_->GetBrowserContext()); |
118 | 133 |
119 PermissionManager* permission_manager = | 134 PermissionManager* permission_manager = |
120 context_->GetBrowserContext()->GetPermissionManager(); | 135 context_->GetBrowserContext()->GetPermissionManager(); |
121 if (!permission_manager) | 136 if (!permission_manager) |
122 return; | 137 return; |
123 | 138 |
139 // Cancel pending requests. | |
124 for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_); | 140 for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_); |
125 !it.IsAtEnd(); it.Advance()) { | 141 !it.IsAtEnd(); it.Advance()) { |
126 permission_manager->CancelPermissionRequest( | 142 permission_manager->CancelPermissionRequest( |
127 it.GetCurrentValue()->permission, | 143 it.GetCurrentValue()->permission, |
128 context_->web_contents(), | 144 context_->web_contents(), |
129 it.GetCurrentKey(), | 145 it.GetCurrentKey(), |
130 it.GetCurrentValue()->origin); | 146 it.GetCurrentValue()->origin); |
131 } | 147 } |
148 pending_requests_.Clear(); | |
132 | 149 |
133 pending_requests_.Clear(); | 150 // Cancel pending subscriptions. |
151 for (SubscriptionsMap::Iterator<PendingSubscription> | |
152 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { | |
153 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( | |
154 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); | |
155 it.GetCurrentValue()->callback.reset(); | |
156 permission_manager->UnsubscribePermissionStatusChange(it.GetCurrentKey()); | |
157 } | |
158 pending_subscriptions_.Clear(); | |
134 } | 159 } |
135 | 160 |
136 void PermissionServiceImpl::HasPermission( | 161 void PermissionServiceImpl::HasPermission( |
137 PermissionName permission, | 162 PermissionName permission, |
138 const mojo::String& origin, | 163 const mojo::String& origin, |
139 const mojo::Callback<void(PermissionStatus)>& callback) { | 164 const PermissionStatusCallback& callback) { |
140 DCHECK(context_->GetBrowserContext()); | |
141 | |
142 callback.Run(GetPermissionStatusFromName(permission, GURL(origin))); | 165 callback.Run(GetPermissionStatusFromName(permission, GURL(origin))); |
143 } | 166 } |
144 | 167 |
145 void PermissionServiceImpl::RevokePermission( | 168 void PermissionServiceImpl::RevokePermission( |
146 PermissionName permission, | 169 PermissionName permission, |
147 const mojo::String& origin, | 170 const mojo::String& origin, |
148 const mojo::Callback<void(PermissionStatus)>& callback) { | 171 const PermissionStatusCallback& callback) { |
149 GURL origin_url(origin); | 172 GURL origin_url(origin); |
150 PermissionType permission_type = PermissionNameToPermissionType(permission); | 173 PermissionType permission_type = PermissionNameToPermissionType(permission); |
151 PermissionStatus status = GetPermissionStatusFromType(permission_type, | 174 PermissionStatus status = GetPermissionStatusFromType(permission_type, |
152 origin_url); | 175 origin_url); |
153 | 176 |
154 // Resetting the permission should only be possible if the permission is | 177 // Resetting the permission should only be possible if the permission is |
155 // already granted. | 178 // already granted. |
156 if (status != PERMISSION_STATUS_GRANTED) { | 179 if (status != PERMISSION_STATUS_GRANTED) { |
157 callback.Run(status); | 180 callback.Run(status); |
158 return; | 181 return; |
159 } | 182 } |
160 | 183 |
161 ResetPermissionStatus(permission_type, origin_url); | 184 ResetPermissionStatus(permission_type, origin_url); |
162 | 185 |
163 callback.Run(GetPermissionStatusFromType(permission_type, origin_url)); | 186 callback.Run(GetPermissionStatusFromType(permission_type, origin_url)); |
164 } | 187 } |
165 | 188 |
166 void PermissionServiceImpl::GetNextPermissionChange( | 189 void PermissionServiceImpl::GetNextPermissionChange( |
167 PermissionName permission, | 190 PermissionName permission, |
168 const mojo::String& origin, | 191 const mojo::String& mojo_origin, |
169 PermissionStatus last_known_status, | 192 PermissionStatus last_known_status, |
170 const mojo::Callback<void(PermissionStatus)>& callback) { | 193 const PermissionStatusCallback& callback) { |
194 GURL origin(mojo_origin); | |
171 PermissionStatus current_status = | 195 PermissionStatus current_status = |
172 GetPermissionStatusFromName(permission, GURL(origin)); | 196 GetPermissionStatusFromName(permission, origin); |
173 if (current_status != last_known_status) { | 197 if (current_status != last_known_status) { |
174 callback.Run(current_status); | 198 callback.Run(current_status); |
175 return; | 199 return; |
176 } | 200 } |
177 | 201 |
178 BrowserContext* browser_context = context_->GetBrowserContext(); | 202 BrowserContext* browser_context = context_->GetBrowserContext(); |
179 DCHECK(browser_context); | 203 DCHECK(browser_context); |
180 if (!browser_context->GetPermissionManager()) { | 204 if (!browser_context->GetPermissionManager()) { |
181 callback.Run(current_status); | 205 callback.Run(current_status); |
182 return; | 206 return; |
183 } | 207 } |
184 | 208 |
185 int* subscription_id = new int(); | 209 int* subscription_id = new int(); |
210 PermissionType permission_type = PermissionNameToPermissionType(permission); | |
186 | 211 |
187 GURL embedding_origin = context_->GetEmbeddingOrigin(); | 212 GURL embedding_origin = context_->GetEmbeddingOrigin(); |
188 *subscription_id = | 213 *subscription_id = |
189 browser_context->GetPermissionManager()->SubscribePermissionStatusChange( | 214 browser_context->GetPermissionManager()->SubscribePermissionStatusChange( |
190 PermissionNameToPermissionType(permission), | 215 permission_type, |
191 GURL(origin), | 216 origin, |
192 // If the embedding_origin is empty, we,ll use the |origin| instead. | 217 // If the embedding_origin is empty, we,ll use the |origin| instead. |
193 embedding_origin.is_empty() ? GURL(origin) : embedding_origin, | 218 embedding_origin.is_empty() ? origin : embedding_origin, |
194 base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged, | 219 base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged, |
195 weak_factory_.GetWeakPtr(), | 220 weak_factory_.GetWeakPtr(), |
196 callback, | |
197 base::Owned(subscription_id))); | 221 base::Owned(subscription_id))); |
222 | |
223 pending_subscriptions_.AddWithID( | |
224 new PendingSubscription(permission_type, origin, callback), | |
225 *subscription_id); | |
198 } | 226 } |
199 | 227 |
200 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromName( | 228 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromName( |
201 PermissionName permission, const GURL& origin) { | 229 PermissionName permission, const GURL& origin) { |
202 return GetPermissionStatusFromType(PermissionNameToPermissionType(permission), | 230 return GetPermissionStatusFromType(PermissionNameToPermissionType(permission), |
203 origin); | 231 origin); |
204 } | 232 } |
205 | 233 |
206 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType( | 234 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType( |
207 PermissionType type, const GURL& origin) { | 235 PermissionType type, const GURL& origin) { |
(...skipping 15 matching lines...) Expand all Loading... | |
223 if (!browser_context->GetPermissionManager()) | 251 if (!browser_context->GetPermissionManager()) |
224 return; | 252 return; |
225 | 253 |
226 // If the embedding_origin is empty we'll use |origin| instead. | 254 // If the embedding_origin is empty we'll use |origin| instead. |
227 GURL embedding_origin = context_->GetEmbeddingOrigin(); | 255 GURL embedding_origin = context_->GetEmbeddingOrigin(); |
228 browser_context->GetPermissionManager()->ResetPermission( | 256 browser_context->GetPermissionManager()->ResetPermission( |
229 type, origin, embedding_origin.is_empty() ? origin : embedding_origin); | 257 type, origin, embedding_origin.is_empty() ? origin : embedding_origin); |
230 } | 258 } |
231 | 259 |
232 void PermissionServiceImpl::OnPermissionStatusChanged( | 260 void PermissionServiceImpl::OnPermissionStatusChanged( |
233 const mojo::Callback<void(PermissionStatus)>& callback, | |
234 const int* subscription_id, | 261 const int* subscription_id, |
whywhat
2015/04/01 18:41:17
why const int* ??
| |
235 PermissionStatus status) { | 262 PermissionStatus status) { |
236 callback.Run(status); | 263 PendingSubscription* subscription = |
264 pending_subscriptions_.Lookup(*subscription_id); | |
265 | |
266 subscription->callback.Run(status); | |
237 | 267 |
238 BrowserContext* browser_context = context_->GetBrowserContext(); | 268 BrowserContext* browser_context = context_->GetBrowserContext(); |
239 DCHECK(browser_context); | 269 DCHECK(browser_context); |
240 if (!browser_context->GetPermissionManager()) | 270 if (!browser_context->GetPermissionManager()) |
241 return; | 271 return; |
242 browser_context->GetPermissionManager()->UnsubscribePermissionStatusChange( | 272 browser_context->GetPermissionManager()->UnsubscribePermissionStatusChange( |
243 *subscription_id); | 273 *subscription_id); |
274 | |
275 subscription->callback.reset(); | |
276 pending_subscriptions_.Remove(*subscription_id); | |
244 } | 277 } |
245 | 278 |
246 } // namespace content | 279 } // namespace content |
OLD | NEW |