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()) { |
| 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 callback.Run(result.Pass()); |
105 return; | 129 return; |
106 } | 130 } |
107 | 131 |
108 BrowserContext* browser_context = context_->GetBrowserContext(); | 132 BrowserContext* browser_context = context_->GetBrowserContext(); |
109 DCHECK(browser_context); | 133 DCHECK(browser_context); |
110 if (!browser_context->GetPermissionManager()) { | 134 if (!browser_context->GetPermissionManager()) { |
111 callback.Run(content::PERMISSION_STATUS_DENIED); | 135 mojo::Array<PermissionStatus> result(permissions.size()); |
| 136 for (size_t i = 0; i < permissions.size(); ++i) |
| 137 result[i] = PERMISSION_STATUS_DENIED; |
| 138 callback.Run(result.Pass()); |
112 return; | 139 return; |
113 } | 140 } |
114 | 141 |
115 PermissionType permission_type = PermissionNameToPermissionType(permission); | 142 std::vector<PermissionType> permission_types; |
| 143 permission_types.reserve(permissions.size()); |
| 144 for (size_t i = 0; i < permissions.size(); ++i) { |
| 145 permission_types.push_back( |
| 146 PermissionNameToPermissionType(permissions[i])); |
| 147 } |
116 int request_id = pending_requests_.Add( | 148 int request_id = pending_requests_.Add( |
117 new PendingRequest(permission_type, GURL(origin), callback)); | 149 new PermissionPendingRequest(callback, permissions.size())); |
118 | 150 |
119 browser_context->GetPermissionManager()->RequestPermission( | 151 browser_context->GetPermissionManager()->RequestPermission( |
120 permission_type, | 152 permission_types, |
121 context_->render_frame_host(), | 153 context_->render_frame_host(), |
122 request_id, | 154 request_id, |
123 GURL(origin), | 155 GURL(origin), |
124 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) | 156 user_gesture, // TODO(mlamouri): should be removed (crbug.com/423770) |
125 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, | 157 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, |
126 weak_factory_.GetWeakPtr(), | 158 weak_factory_.GetWeakPtr(), |
127 request_id)); | 159 request_id)); |
128 } | 160 } |
129 | 161 |
130 void PermissionServiceImpl::OnRequestPermissionResponse( | 162 void PermissionServiceImpl::OnRequestPermissionResponse( |
131 int request_id, | 163 int request_id, |
132 PermissionStatus status) { | 164 const std::vector<PermissionStatus>& status) { |
133 PendingRequest* request = pending_requests_.Lookup(request_id); | 165 PermissionPendingRequest* request = pending_requests_.Lookup(request_id); |
134 PermissionStatusCallback callback(request->callback); | 166 BatchPermissionStatusCallback callback(request->callback()); |
135 request->callback.reset(); | 167 |
| 168 request->callback().reset(); |
136 pending_requests_.Remove(request_id); | 169 pending_requests_.Remove(request_id); |
137 callback.Run(status); | 170 |
| 171 mojo::Array<PermissionStatus> status_array(status.size()); |
| 172 for (size_t i = 0; i < status.size(); i++) |
| 173 status_array[i] = status[i]; |
| 174 callback.Run(status_array.Pass()); |
138 } | 175 } |
139 | 176 |
140 void PermissionServiceImpl::CancelPendingOperations() { | 177 void PermissionServiceImpl::CancelPendingOperations() { |
141 DCHECK(context_->render_frame_host()); | 178 DCHECK(context_->render_frame_host()); |
142 DCHECK(context_->GetBrowserContext()); | 179 DCHECK(context_->GetBrowserContext()); |
143 | 180 |
144 PermissionManager* permission_manager = | 181 PermissionManager* permission_manager = |
145 context_->GetBrowserContext()->GetPermissionManager(); | 182 context_->GetBrowserContext()->GetPermissionManager(); |
146 if (!permission_manager) | 183 if (!permission_manager) |
147 return; | 184 return; |
148 | 185 |
149 // Cancel pending requests. | 186 // Cancel pending requests. |
150 for (RequestsMap::Iterator<PendingRequest> it(&pending_requests_); | 187 for (RequestsMap::Iterator<PermissionPendingRequest> it(&pending_requests_); |
151 !it.IsAtEnd(); it.Advance()) { | 188 !it.IsAtEnd(); it.Advance()) { |
152 permission_manager->CancelPermissionRequest( | 189 permission_manager->CancelPermissionRequest(context_->render_frame_host(), |
153 it.GetCurrentValue()->permission, | 190 it.GetCurrentKey()); |
154 context_->render_frame_host(), | |
155 it.GetCurrentKey(), | |
156 it.GetCurrentValue()->origin); | |
157 } | 191 } |
158 pending_requests_.Clear(); | 192 pending_requests_.Clear(); |
159 | 193 |
160 // Cancel pending subscriptions. | 194 // Cancel pending subscriptions. |
161 for (SubscriptionsMap::Iterator<PendingSubscription> | 195 for (SubscriptionsMap::Iterator<PendingSubscription> |
162 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { | 196 it(&pending_subscriptions_); !it.IsAtEnd(); it.Advance()) { |
163 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( | 197 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( |
164 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); | 198 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); |
165 it.GetCurrentValue()->callback.reset(); | 199 it.GetCurrentValue()->callback.reset(); |
166 permission_manager->UnsubscribePermissionStatusChange( | 200 permission_manager->UnsubscribePermissionStatusChange( |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 | 319 |
286 PermissionStatusCallback callback = subscription->callback; | 320 PermissionStatusCallback callback = subscription->callback; |
287 | 321 |
288 subscription->callback.reset(); | 322 subscription->callback.reset(); |
289 pending_subscriptions_.Remove(pending_subscription_id); | 323 pending_subscriptions_.Remove(pending_subscription_id); |
290 | 324 |
291 callback.Run(status); | 325 callback.Run(status); |
292 } | 326 } |
293 | 327 |
294 } // namespace content | 328 } // namespace content |
OLD | NEW |