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_request.h" | |
8 #include "content/public/browser/browser_context.h" | 9 #include "content/public/browser/browser_context.h" |
9 #include "content/public/browser/permission_manager.h" | 10 #include "content/public/browser/permission_manager.h" |
10 #include "content/public/browser/permission_type.h" | 11 #include "content/public/browser/permission_type.h" |
11 | 12 |
12 namespace content { | 13 namespace content { |
13 | 14 |
14 namespace { | 15 namespace { |
15 | 16 |
16 PermissionType PermissionNameToPermissionType(PermissionName name) { | 17 PermissionType PermissionNameToPermissionType(PermissionName name) { |
17 switch(name) { | 18 switch(name) { |
(...skipping 10 matching lines...) Expand all Loading... | |
28 case PERMISSION_NAME_PROTECTED_MEDIA_IDENTIFIER: | 29 case PERMISSION_NAME_PROTECTED_MEDIA_IDENTIFIER: |
29 return PermissionType::PROTECTED_MEDIA_IDENTIFIER; | 30 return PermissionType::PROTECTED_MEDIA_IDENTIFIER; |
30 case PERMISSION_NAME_DURABLE_STORAGE: | 31 case PERMISSION_NAME_DURABLE_STORAGE: |
31 return PermissionType::DURABLE_STORAGE; | 32 return PermissionType::DURABLE_STORAGE; |
32 } | 33 } |
33 | 34 |
34 NOTREACHED(); | 35 NOTREACHED(); |
35 return PermissionType::NUM; | 36 return PermissionType::NUM; |
36 } | 37 } |
37 | 38 |
39 void PermissionRequestResponseCallbackWrapper( | |
40 const mojo::Callback<void(PermissionStatus)>& callback, | |
41 const mojo::Array<PermissionStatus>& vector) { | |
42 DCHECK(vector.size() == 1); | |
43 callback.Run(vector[0]); | |
44 } | |
45 | |
38 } // anonymous namespace | 46 } // anonymous namespace |
39 | 47 |
40 PermissionServiceImpl::PendingRequest::PendingRequest( | |
41 PermissionType permission, | |
42 const GURL& origin, | |
43 const PermissionStatusCallback& callback) | |
44 : permission(permission), | |
45 origin(origin), | |
46 callback(callback) { | |
47 } | |
48 | |
49 PermissionServiceImpl::PendingRequest::~PendingRequest() { | |
50 if (!callback.is_null()) | |
51 callback.Run(PERMISSION_STATUS_ASK); | |
52 } | |
53 | |
54 PermissionServiceImpl::PendingSubscription::PendingSubscription( | 48 PermissionServiceImpl::PendingSubscription::PendingSubscription( |
55 PermissionType permission, | 49 PermissionType permission, |
56 const GURL& origin, | 50 const GURL& origin, |
57 const PermissionStatusCallback& callback) | 51 const PermissionStatusCallback& callback) |
58 : id(-1), | 52 : id(-1), |
59 permission(permission), | 53 permission(permission), |
60 origin(origin), | 54 origin(origin), |
61 callback(callback) { | 55 callback(callback) { |
62 } | 56 } |
63 | 57 |
(...skipping 20 matching lines...) Expand all Loading... | |
84 void PermissionServiceImpl::OnConnectionError() { | 78 void PermissionServiceImpl::OnConnectionError() { |
85 context_->ServiceHadConnectionError(this); | 79 context_->ServiceHadConnectionError(this); |
86 // After that call, |this| will be deleted. | 80 // After that call, |this| will be deleted. |
87 } | 81 } |
88 | 82 |
89 void PermissionServiceImpl::RequestPermission( | 83 void PermissionServiceImpl::RequestPermission( |
90 PermissionName permission, | 84 PermissionName permission, |
91 const mojo::String& origin, | 85 const mojo::String& origin, |
92 bool user_gesture, | 86 bool user_gesture, |
93 const PermissionStatusCallback& callback) { | 87 const PermissionStatusCallback& callback) { |
88 mojo::Array<PermissionName> permissions = mojo::Array<PermissionName>::New(1); | |
89 permissions[0] = permission; | |
90 | |
91 RequestPermissionInternal( | |
92 permissions.Pass(), | |
93 origin, | |
94 user_gesture, | |
95 base::Bind(&PermissionRequestResponseCallbackWrapper, | |
96 callback)); | |
97 } | |
98 | |
99 void PermissionServiceImpl::RequestBatchPermission( | |
100 mojo::Array<PermissionName> permissions, | |
101 const mojo::String& origin, | |
102 bool user_gesture, | |
103 const BatchPermissionStatusCallback& callback) { | |
104 RequestPermissionInternal(permissions.Pass(), origin, user_gesture, callback); | |
105 } | |
106 | |
107 void PermissionServiceImpl::RequestPermissionInternal( | |
108 mojo::Array<PermissionName> permissions, | |
109 const mojo::String& origin, | |
110 bool user_gesture, | |
111 const BatchPermissionStatusCallback& callback) { | |
112 if (permissions.is_null()) { | |
mlamouri (slow - plz ping)
2015/08/21 10:24:41
When would that happen?
Lalit Maganti
2015/08/21 12:56:00
Compromised renderer process is the only thing I c
| |
113 callback.Run(mojo::Array<PermissionStatus>()); | |
114 return; | |
115 } | |
116 | |
94 // This condition is valid if the call is coming from a ChildThread instead of | 117 // This condition is valid if the call is coming from a ChildThread instead of |
95 // a RenderFrame. Some consumers of the service run in Workers and some in | 118 // a RenderFrame. Some consumers of the service run in Workers and some in |
96 // Frames. In the context of a Worker, it is not possible to show a | 119 // Frames. In the context of a Worker, it is not possible to show a |
97 // permission prompt because there is no tab. In the context of a Frame, we | 120 // permission prompt because there is no tab. In the context of a Frame, we |
98 // can. Even if the call comes from a context where it is not possible to show | 121 // can. Even if the call comes from a context where it is not possible to show |
99 // any UI, we want to still return something relevant so the current | 122 // any UI, we want to still return something relevant so the current |
100 // permission status is returned. | 123 // permission status is returned for each permission. |
101 if (!context_->render_frame_host()) { | 124 if (!context_->render_frame_host()) { |
102 // There is no way to show a UI so the call will simply return the current | 125 mojo::Array<PermissionStatus> result(permissions.size()); |
103 // permission. | 126 for (size_t i = 0; i < permissions.size(); ++i) { |
104 HasPermission(permission, origin, callback); | 127 result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin)); |
128 } | |
mlamouri (slow - plz ping)
2015/08/21 10:24:41
style: remove { }
Lalit Maganti
2015/08/25 16:58:27
Done.
| |
129 callback.Run(result.Pass()); | |
105 return; | 130 return; |
106 } | 131 } |
107 | 132 |
108 BrowserContext* browser_context = context_->GetBrowserContext(); | 133 BrowserContext* browser_context = context_->GetBrowserContext(); |
109 DCHECK(browser_context); | 134 DCHECK(browser_context); |
110 if (!browser_context->GetPermissionManager()) { | 135 if (!browser_context->GetPermissionManager()) { |
111 callback.Run(content::PERMISSION_STATUS_DENIED); | 136 mojo::Array<PermissionStatus> result(permissions.size()); |
137 for (size_t i = 0; i < permissions.size(); ++i) { | |
138 result[i] = PERMISSION_STATUS_DENIED; | |
139 } | |
mlamouri (slow - plz ping)
2015/08/21 10:24:41
ditto
Lalit Maganti
2015/08/25 16:58:27
Done.
| |
140 callback.Run(result.Pass()); | |
112 return; | 141 return; |
113 } | 142 } |
114 | 143 |
115 PermissionType permission_type = PermissionNameToPermissionType(permission); | 144 std::vector<PermissionType> permission_types; |
145 permission_types.reserve(permissions.size()); | |
146 for (size_t i = 0; i < permissions.size(); ++i) { | |
147 permission_types.push_back( | |
148 PermissionNameToPermissionType(permissions[i])); | |
149 } | |
116 int request_id = pending_requests_.Add( | 150 int request_id = pending_requests_.Add( |
117 new PendingRequest(permission_type, GURL(origin), callback)); | 151 new PermissionPendingRequest(callback, permissions.size())); |
118 | 152 |
119 browser_context->GetPermissionManager()->RequestPermission( | 153 browser_context->GetPermissionManager()->RequestPermission( |
120 permission_type, | 154 permission_types, |
121 context_->render_frame_host(), | 155 context_->render_frame_host(), |
122 request_id, | 156 request_id, |
123 GURL(origin), | 157 GURL(origin), |
124 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) | 158 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) |
125 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, | 159 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, |
126 weak_factory_.GetWeakPtr(), | 160 weak_factory_.GetWeakPtr(), |
127 request_id)); | 161 request_id)); |
128 } | 162 } |
129 | 163 |
130 void PermissionServiceImpl::OnRequestPermissionResponse( | 164 void PermissionServiceImpl::OnRequestPermissionResponse( |
131 int request_id, | 165 int request_id, |
132 PermissionStatus status) { | 166 const std::vector<PermissionStatus>& status) { |
133 PendingRequest* request = pending_requests_.Lookup(request_id); | 167 PermissionPendingRequest* request = pending_requests_.Lookup(request_id); |
134 PermissionStatusCallback callback(request->callback); | 168 BatchPermissionStatusCallback callback(request->callback()); |
135 request->callback.reset(); | 169 |
170 request->callback().reset(); | |
136 pending_requests_.Remove(request_id); | 171 pending_requests_.Remove(request_id); |
137 callback.Run(status); | 172 |
173 mojo::Array<PermissionStatus> status_array(status.size()); | |
174 for (size_t i = 0; i < status.size(); i++) | |
175 status_array[i] = status[i]; | |
176 callback.Run(status_array.Pass()); | |
138 } | 177 } |
139 | 178 |
140 void PermissionServiceImpl::CancelPendingOperations() { | 179 void PermissionServiceImpl::CancelPendingOperations() { |
141 DCHECK(context_->render_frame_host()); | 180 DCHECK(context_->render_frame_host()); |
142 DCHECK(context_->GetBrowserContext()); | 181 DCHECK(context_->GetBrowserContext()); |
143 | 182 |
144 PermissionManager* permission_manager = | 183 PermissionManager* permission_manager = |
145 context_->GetBrowserContext()->GetPermissionManager(); | 184 context_->GetBrowserContext()->GetPermissionManager(); |
146 if (!permission_manager) | 185 if (!permission_manager) |
147 return; | 186 return; |
148 | 187 |
149 // Cancel pending requests. | 188 // Cancel pending requests. |
150 for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_); | 189 for (RequestsMap::Iterator<PermissionPendingRequest> it(&pending_requests_); |
151 !it.IsAtEnd(); it.Advance()) { | 190 !it.IsAtEnd(); it.Advance()) { |
152 permission_manager->CancelPermissionRequest( | 191 permission_manager->CancelPermissionRequest(context_->render_frame_host(), |
153 it.GetCurrentValue()->permission, | 192 it.GetCurrentKey()); |
154 context_->render_frame_host(), | |
155 it.GetCurrentKey(), | |
156 it.GetCurrentValue()->origin); | |
157 } | 193 } |
158 pending_requests_.Clear(); | 194 pending_requests_.Clear(); |
159 | 195 |
160 // Cancel pending subscriptions. | 196 // Cancel pending subscriptions. |
161 for (SubscriptionsMap::Iterator<PendingSubscription> | 197 for (SubscriptionsMap::Iterator<PendingSubscription> |
162 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { | 198 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { |
163 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( | 199 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( |
164 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); | 200 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); |
165 it.GetCurrentValue()->callback.reset(); | 201 it.GetCurrentValue()->callback.reset(); |
166 permission_manager->UnsubscribePermissionStatusChange( | 202 permission_manager->UnsubscribePermissionStatusChange( |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 | 321 |
286 PermissionStatusCallback callback = subscription->callback; | 322 PermissionStatusCallback callback = subscription->callback; |
287 | 323 |
288 subscription->callback.reset(); | 324 subscription->callback.reset(); |
289 pending_subscriptions_.Remove(pending_subscription_id); | 325 pending_subscriptions_.Remove(pending_subscription_id); |
290 | 326 |
291 callback.Run(status); | 327 callback.Run(status); |
292 } | 328 } |
293 | 329 |
294 } // namespace content | 330 } // namespace content |
OLD | NEW |