| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "content/public/browser/browser_context.h" | 11 #include "content/public/browser/browser_context.h" |
| 12 #include "content/public/browser/permission_manager.h" | 12 #include "content/public/browser/permission_manager.h" |
| 13 #include "content/public/browser/permission_type.h" | 13 #include "content/public/browser/permission_type.h" |
| 14 #include "url/origin.h" |
| 14 | 15 |
| 15 namespace content { | 16 namespace content { |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 PermissionType PermissionNameToPermissionType(mojom::PermissionName name) { | 20 PermissionType PermissionNameToPermissionType(mojom::PermissionName name) { |
| 20 switch(name) { | 21 switch(name) { |
| 21 case mojom::PermissionName::GEOLOCATION: | 22 case mojom::PermissionName::GEOLOCATION: |
| 22 return PermissionType::GEOLOCATION; | 23 return PermissionType::GEOLOCATION; |
| 23 case mojom::PermissionName::NOTIFICATIONS: | 24 case mojom::PermissionName::NOTIFICATIONS: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 | 67 |
| 67 mojo::Array<mojom::PermissionStatus> result = | 68 mojo::Array<mojom::PermissionStatus> result = |
| 68 mojo::Array<mojom::PermissionStatus>::New(request_count); | 69 mojo::Array<mojom::PermissionStatus>::New(request_count); |
| 69 for (int i = 0; i < request_count; ++i) | 70 for (int i = 0; i < request_count; ++i) |
| 70 result[i] = mojom::PermissionStatus::DENIED; | 71 result[i] = mojom::PermissionStatus::DENIED; |
| 71 callback.Run(std::move(result)); | 72 callback.Run(std::move(result)); |
| 72 } | 73 } |
| 73 | 74 |
| 74 PermissionServiceImpl::PendingSubscription::PendingSubscription( | 75 PermissionServiceImpl::PendingSubscription::PendingSubscription( |
| 75 PermissionType permission, | 76 PermissionType permission, |
| 76 const GURL& origin, | 77 const url::Origin& origin, |
| 77 const PermissionStatusCallback& callback) | 78 const PermissionStatusCallback& callback) |
| 78 : id(-1), | 79 : id(-1), permission(permission), origin(origin), callback(callback) {} |
| 79 permission(permission), | |
| 80 origin(origin), | |
| 81 callback(callback) { | |
| 82 } | |
| 83 | 80 |
| 84 PermissionServiceImpl::PendingSubscription::~PendingSubscription() { | 81 PermissionServiceImpl::PendingSubscription::~PendingSubscription() { |
| 85 if (!callback.is_null()) | 82 if (!callback.is_null()) |
| 86 callback.Run(mojom::PermissionStatus::ASK); | 83 callback.Run(mojom::PermissionStatus::ASK); |
| 87 } | 84 } |
| 88 | 85 |
| 89 PermissionServiceImpl::PermissionServiceImpl( | 86 PermissionServiceImpl::PermissionServiceImpl( |
| 90 PermissionServiceContext* context, | 87 PermissionServiceContext* context, |
| 91 mojo::InterfaceRequest<mojom::PermissionService> request) | 88 mojo::InterfaceRequest<mojom::PermissionService> request) |
| 92 : context_(context), | 89 : context_(context), |
| 93 binding_(this, std::move(request)), | 90 binding_(this, std::move(request)), |
| 94 weak_factory_(this) { | 91 weak_factory_(this) { |
| 95 binding_.set_connection_error_handler( | 92 binding_.set_connection_error_handler( |
| 96 base::Bind(&PermissionServiceImpl::OnConnectionError, | 93 base::Bind(&PermissionServiceImpl::OnConnectionError, |
| 97 base::Unretained(this))); | 94 base::Unretained(this))); |
| 98 } | 95 } |
| 99 | 96 |
| 100 PermissionServiceImpl::~PermissionServiceImpl() { | 97 PermissionServiceImpl::~PermissionServiceImpl() { |
| 101 DCHECK(pending_requests_.IsEmpty()); | 98 DCHECK(pending_requests_.IsEmpty()); |
| 102 } | 99 } |
| 103 | 100 |
| 104 void PermissionServiceImpl::OnConnectionError() { | 101 void PermissionServiceImpl::OnConnectionError() { |
| 105 context_->ServiceHadConnectionError(this); | 102 context_->ServiceHadConnectionError(this); |
| 106 // After that call, |this| will be deleted. | 103 // After that call, |this| will be deleted. |
| 107 } | 104 } |
| 108 | 105 |
| 109 void PermissionServiceImpl::RequestPermission( | 106 void PermissionServiceImpl::RequestPermission( |
| 110 mojom::PermissionName permission, | 107 mojom::PermissionName permission, |
| 111 const mojo::String& origin, | 108 const mojo::String& origin_string, |
| 112 const PermissionStatusCallback& callback) { | 109 const PermissionStatusCallback& callback) { |
| 113 // This condition is valid if the call is coming from a ChildThread instead of | 110 // This condition is valid if the call is coming from a ChildThread instead of |
| 114 // a RenderFrame. Some consumers of the service run in Workers and some in | 111 // a RenderFrame. Some consumers of the service run in Workers and some in |
| 115 // Frames. In the context of a Worker, it is not possible to show a | 112 // Frames. In the context of a Worker, it is not possible to show a |
| 116 // permission prompt because there is no tab. In the context of a Frame, we | 113 // permission prompt because there is no tab. In the context of a Frame, we |
| 117 // can. Even if the call comes from a context where it is not possible to show | 114 // can. Even if the call comes from a context where it is not possible to show |
| 118 // any UI, we want to still return something relevant so the current | 115 // any UI, we want to still return something relevant so the current |
| 119 // permission status is returned. | 116 // permission status is returned. |
| 120 BrowserContext* browser_context = context_->GetBrowserContext(); | 117 BrowserContext* browser_context = context_->GetBrowserContext(); |
| 121 DCHECK(browser_context); | 118 DCHECK(browser_context); |
| 119 url::Origin origin(origin_string.get()); |
| 122 if (!context_->render_frame_host() || | 120 if (!context_->render_frame_host() || |
| 123 !browser_context->GetPermissionManager()) { | 121 !browser_context->GetPermissionManager()) { |
| 124 callback.Run(GetPermissionStatusFromName(permission, GURL(origin.get()))); | 122 callback.Run(GetPermissionStatusFromName(permission, origin)); |
| 125 return; | 123 return; |
| 126 } | 124 } |
| 127 | 125 |
| 128 int pending_request_id = pending_requests_.Add(new PendingRequest( | 126 int pending_request_id = pending_requests_.Add(new PendingRequest( |
| 129 base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1)); | 127 base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1)); |
| 130 int id = browser_context->GetPermissionManager()->RequestPermission( | 128 int id = browser_context->GetPermissionManager()->RequestPermission( |
| 131 PermissionNameToPermissionType(permission), | 129 PermissionNameToPermissionType(permission), context_->render_frame_host(), |
| 132 context_->render_frame_host(), | 130 origin, base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, |
| 133 GURL(origin.get()), | 131 weak_factory_.GetWeakPtr(), pending_request_id)); |
| 134 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, | |
| 135 weak_factory_.GetWeakPtr(), | |
| 136 pending_request_id)); | |
| 137 | 132 |
| 138 // Check if the request still exists. It might have been removed by the | 133 // Check if the request still exists. It might have been removed by the |
| 139 // callback if it was run synchronously. | 134 // callback if it was run synchronously. |
| 140 PendingRequest* pending_request = pending_requests_.Lookup( | 135 PendingRequest* pending_request = pending_requests_.Lookup( |
| 141 pending_request_id); | 136 pending_request_id); |
| 142 if (!pending_request) | 137 if (!pending_request) |
| 143 return; | 138 return; |
| 144 pending_request->id = id; | 139 pending_request->id = id; |
| 145 } | 140 } |
| 146 | 141 |
| 147 void PermissionServiceImpl::OnRequestPermissionResponse( | 142 void PermissionServiceImpl::OnRequestPermissionResponse( |
| 148 int pending_request_id, | 143 int pending_request_id, |
| 149 mojom::PermissionStatus status) { | 144 mojom::PermissionStatus status) { |
| 150 OnRequestPermissionsResponse(pending_request_id, | 145 OnRequestPermissionsResponse(pending_request_id, |
| 151 std::vector<mojom::PermissionStatus>(1, status)); | 146 std::vector<mojom::PermissionStatus>(1, status)); |
| 152 } | 147 } |
| 153 | 148 |
| 154 void PermissionServiceImpl::RequestPermissions( | 149 void PermissionServiceImpl::RequestPermissions( |
| 155 mojo::Array<mojom::PermissionName> permissions, | 150 mojo::Array<mojom::PermissionName> permissions, |
| 156 const mojo::String& origin, | 151 const mojo::String& origin_string, |
| 157 const PermissionsStatusCallback& callback) { | 152 const PermissionsStatusCallback& callback) { |
| 158 if (permissions.is_null()) { | 153 if (permissions.is_null()) { |
| 159 callback.Run(mojo::Array<mojom::PermissionStatus>()); | 154 callback.Run(mojo::Array<mojom::PermissionStatus>()); |
| 160 return; | 155 return; |
| 161 } | 156 } |
| 162 | 157 |
| 163 // This condition is valid if the call is coming from a ChildThread instead of | 158 // This condition is valid if the call is coming from a ChildThread instead of |
| 164 // a RenderFrame. Some consumers of the service run in Workers and some in | 159 // a RenderFrame. Some consumers of the service run in Workers and some in |
| 165 // Frames. In the context of a Worker, it is not possible to show a | 160 // Frames. In the context of a Worker, it is not possible to show a |
| 166 // permission prompt because there is no tab. In the context of a Frame, we | 161 // permission prompt because there is no tab. In the context of a Frame, we |
| 167 // can. Even if the call comes from a context where it is not possible to show | 162 // can. Even if the call comes from a context where it is not possible to show |
| 168 // any UI, we want to still return something relevant so the current | 163 // any UI, we want to still return something relevant so the current |
| 169 // permission status is returned for each permission. | 164 // permission status is returned for each permission. |
| 170 BrowserContext* browser_context = context_->GetBrowserContext(); | 165 BrowserContext* browser_context = context_->GetBrowserContext(); |
| 171 DCHECK(browser_context); | 166 DCHECK(browser_context); |
| 167 const url::Origin origin(origin_string.get()); |
| 172 if (!context_->render_frame_host() || | 168 if (!context_->render_frame_host() || |
| 173 !browser_context->GetPermissionManager()) { | 169 !browser_context->GetPermissionManager()) { |
| 174 mojo::Array<mojom::PermissionStatus> result(permissions.size()); | 170 mojo::Array<mojom::PermissionStatus> result(permissions.size()); |
| 175 for (size_t i = 0; i < permissions.size(); ++i) { | 171 for (size_t i = 0; i < permissions.size(); ++i) { |
| 176 result[i] = | 172 result[i] = GetPermissionStatusFromName(permissions[i], origin); |
| 177 GetPermissionStatusFromName(permissions[i], GURL(origin.get())); | |
| 178 } | 173 } |
| 179 callback.Run(std::move(result)); | 174 callback.Run(std::move(result)); |
| 180 return; | 175 return; |
| 181 } | 176 } |
| 182 | 177 |
| 183 std::vector<PermissionType> types(permissions.size()); | 178 std::vector<PermissionType> types(permissions.size()); |
| 184 for (size_t i = 0; i < types.size(); ++i) | 179 for (size_t i = 0; i < types.size(); ++i) |
| 185 types[i] = PermissionNameToPermissionType(permissions[i]); | 180 types[i] = PermissionNameToPermissionType(permissions[i]); |
| 186 | 181 |
| 187 int pending_request_id = pending_requests_.Add( | 182 int pending_request_id = pending_requests_.Add( |
| 188 new PendingRequest(callback, permissions.size())); | 183 new PendingRequest(callback, permissions.size())); |
| 189 int id = browser_context->GetPermissionManager()->RequestPermissions( | 184 int id = browser_context->GetPermissionManager()->RequestPermissions( |
| 190 types, | 185 types, context_->render_frame_host(), origin, |
| 191 context_->render_frame_host(), | |
| 192 GURL(origin.get()), | |
| 193 base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse, | 186 base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse, |
| 194 weak_factory_.GetWeakPtr(), | 187 weak_factory_.GetWeakPtr(), pending_request_id)); |
| 195 pending_request_id)); | |
| 196 | 188 |
| 197 // Check if the request still exists. It may have been removed by the | 189 // Check if the request still exists. It may have been removed by the |
| 198 // the response callback. | 190 // the response callback. |
| 199 PendingRequest* pending_request = pending_requests_.Lookup( | 191 PendingRequest* pending_request = pending_requests_.Lookup( |
| 200 pending_request_id); | 192 pending_request_id); |
| 201 if (!pending_request) | 193 if (!pending_request) |
| 202 return; | 194 return; |
| 203 pending_request->id = id; | 195 pending_request->id = id; |
| 204 } | 196 } |
| 205 | 197 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 236 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); | 228 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); |
| 237 it.GetCurrentValue()->callback.reset(); | 229 it.GetCurrentValue()->callback.reset(); |
| 238 permission_manager->UnsubscribePermissionStatusChange( | 230 permission_manager->UnsubscribePermissionStatusChange( |
| 239 it.GetCurrentValue()->id); | 231 it.GetCurrentValue()->id); |
| 240 } | 232 } |
| 241 pending_subscriptions_.Clear(); | 233 pending_subscriptions_.Clear(); |
| 242 } | 234 } |
| 243 | 235 |
| 244 void PermissionServiceImpl::HasPermission( | 236 void PermissionServiceImpl::HasPermission( |
| 245 mojom::PermissionName permission, | 237 mojom::PermissionName permission, |
| 246 const mojo::String& origin, | 238 const mojo::String& origin_string, |
| 247 const PermissionStatusCallback& callback) { | 239 const PermissionStatusCallback& callback) { |
| 248 callback.Run(GetPermissionStatusFromName(permission, GURL(origin.get()))); | 240 callback.Run(GetPermissionStatusFromName(permission, |
| 241 url::Origin(origin_string.get()))); |
| 249 } | 242 } |
| 250 | 243 |
| 251 void PermissionServiceImpl::RevokePermission( | 244 void PermissionServiceImpl::RevokePermission( |
| 252 mojom::PermissionName permission, | 245 mojom::PermissionName permission, |
| 253 const mojo::String& origin, | 246 const mojo::String& origin_string, |
| 254 const PermissionStatusCallback& callback) { | 247 const PermissionStatusCallback& callback) { |
| 255 GURL origin_url(origin.get()); | 248 const url::Origin origin(origin_string.get()); |
| 256 PermissionType permission_type = PermissionNameToPermissionType(permission); | 249 PermissionType permission_type = PermissionNameToPermissionType(permission); |
| 257 mojom::PermissionStatus status = | 250 mojom::PermissionStatus status = |
| 258 GetPermissionStatusFromType(permission_type, origin_url); | 251 GetPermissionStatusFromType(permission_type, origin); |
| 259 | 252 |
| 260 // Resetting the permission should only be possible if the permission is | 253 // Resetting the permission should only be possible if the permission is |
| 261 // already granted. | 254 // already granted. |
| 262 if (status != mojom::PermissionStatus::GRANTED) { | 255 if (status != mojom::PermissionStatus::GRANTED) { |
| 263 callback.Run(status); | 256 callback.Run(status); |
| 264 return; | 257 return; |
| 265 } | 258 } |
| 266 | 259 |
| 267 ResetPermissionStatus(permission_type, origin_url); | 260 ResetPermissionStatus(permission_type, origin); |
| 268 | 261 |
| 269 callback.Run(GetPermissionStatusFromType(permission_type, origin_url)); | 262 callback.Run(GetPermissionStatusFromType(permission_type, origin)); |
| 270 } | 263 } |
| 271 | 264 |
| 272 void PermissionServiceImpl::GetNextPermissionChange( | 265 void PermissionServiceImpl::GetNextPermissionChange( |
| 273 mojom::PermissionName permission, | 266 mojom::PermissionName permission, |
| 274 const mojo::String& mojo_origin, | 267 const mojo::String& origin_string, |
| 275 mojom::PermissionStatus last_known_status, | 268 mojom::PermissionStatus last_known_status, |
| 276 const PermissionStatusCallback& callback) { | 269 const PermissionStatusCallback& callback) { |
| 277 GURL origin(mojo_origin.get()); | 270 const url::Origin origin(origin_string.get()); |
| 278 mojom::PermissionStatus current_status = | 271 mojom::PermissionStatus current_status = |
| 279 GetPermissionStatusFromName(permission, origin); | 272 GetPermissionStatusFromName(permission, origin); |
| 280 if (current_status != last_known_status) { | 273 if (current_status != last_known_status) { |
| 281 callback.Run(current_status); | 274 callback.Run(current_status); |
| 282 return; | 275 return; |
| 283 } | 276 } |
| 284 | 277 |
| 285 BrowserContext* browser_context = context_->GetBrowserContext(); | 278 BrowserContext* browser_context = context_->GetBrowserContext(); |
| 286 DCHECK(browser_context); | 279 DCHECK(browser_context); |
| 287 if (!browser_context->GetPermissionManager()) { | 280 if (!browser_context->GetPermissionManager()) { |
| 288 callback.Run(current_status); | 281 callback.Run(current_status); |
| 289 return; | 282 return; |
| 290 } | 283 } |
| 291 | 284 |
| 292 PermissionType permission_type = PermissionNameToPermissionType(permission); | 285 PermissionType permission_type = PermissionNameToPermissionType(permission); |
| 293 | 286 |
| 294 // We need to pass the id of PendingSubscription in pending_subscriptions_ | 287 // We need to pass the id of PendingSubscription in pending_subscriptions_ |
| 295 // to the callback but SubscribePermissionStatusChange() will also return an | 288 // to the callback but SubscribePermissionStatusChange() will also return an |
| 296 // id which is different. | 289 // id which is different. |
| 297 PendingSubscription* subscription = | 290 PendingSubscription* subscription = |
| 298 new PendingSubscription(permission_type, origin, callback); | 291 new PendingSubscription(permission_type, origin, callback); |
| 299 int pending_subscription_id = pending_subscriptions_.Add(subscription); | 292 int pending_subscription_id = pending_subscriptions_.Add(subscription); |
| 300 | 293 |
| 301 GURL embedding_origin = context_->GetEmbeddingOrigin(); | 294 const url::Origin embedding_origin = context_->GetEmbeddingOrigin(); |
| 302 subscription->id = | 295 subscription->id = |
| 303 browser_context->GetPermissionManager()->SubscribePermissionStatusChange( | 296 browser_context->GetPermissionManager()->SubscribePermissionStatusChange( |
| 304 permission_type, | 297 permission_type, origin, |
| 305 origin, | 298 embedding_origin.empty() ? origin : embedding_origin, |
| 306 // If the embedding_origin is empty, we,ll use the |origin| instead. | |
| 307 embedding_origin.is_empty() ? origin : embedding_origin, | |
| 308 base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged, | 299 base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged, |
| 309 weak_factory_.GetWeakPtr(), | 300 weak_factory_.GetWeakPtr(), pending_subscription_id)); |
| 310 pending_subscription_id)); | |
| 311 } | 301 } |
| 312 | 302 |
| 313 mojom::PermissionStatus PermissionServiceImpl::GetPermissionStatusFromName( | 303 mojom::PermissionStatus PermissionServiceImpl::GetPermissionStatusFromName( |
| 314 mojom::PermissionName permission, | 304 mojom::PermissionName permission, |
| 315 const GURL& origin) { | 305 const url::Origin& origin) { |
| 316 return GetPermissionStatusFromType(PermissionNameToPermissionType(permission), | 306 return GetPermissionStatusFromType(PermissionNameToPermissionType(permission), |
| 317 origin); | 307 origin); |
| 318 } | 308 } |
| 319 | 309 |
| 320 mojom::PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType( | 310 mojom::PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType( |
| 321 PermissionType type, | 311 PermissionType type, |
| 322 const GURL& origin) { | 312 const url::Origin& origin) { |
| 323 BrowserContext* browser_context = context_->GetBrowserContext(); | 313 BrowserContext* browser_context = context_->GetBrowserContext(); |
| 324 DCHECK(browser_context); | 314 DCHECK(browser_context); |
| 325 if (!browser_context->GetPermissionManager()) | 315 if (!browser_context->GetPermissionManager()) |
| 326 return mojom::PermissionStatus::DENIED; | 316 return mojom::PermissionStatus::DENIED; |
| 327 | 317 |
| 328 // If the embedding_origin is empty we'll use |origin| instead. | 318 const url::Origin embedding_origin = context_->GetEmbeddingOrigin(); |
| 329 GURL embedding_origin = context_->GetEmbeddingOrigin(); | |
| 330 return browser_context->GetPermissionManager()->GetPermissionStatus( | 319 return browser_context->GetPermissionManager()->GetPermissionStatus( |
| 331 type, origin, embedding_origin.is_empty() ? origin : embedding_origin); | 320 type, origin, embedding_origin.empty() ? origin : embedding_origin); |
| 332 } | 321 } |
| 333 | 322 |
| 334 void PermissionServiceImpl::ResetPermissionStatus(PermissionType type, | 323 void PermissionServiceImpl::ResetPermissionStatus(PermissionType type, |
| 335 const GURL& origin) { | 324 const url::Origin& origin) { |
| 336 BrowserContext* browser_context = context_->GetBrowserContext(); | 325 BrowserContext* browser_context = context_->GetBrowserContext(); |
| 337 DCHECK(browser_context); | 326 DCHECK(browser_context); |
| 338 if (!browser_context->GetPermissionManager()) | 327 if (!browser_context->GetPermissionManager()) |
| 339 return; | 328 return; |
| 340 | 329 |
| 341 // If the embedding_origin is empty we'll use |origin| instead. | 330 const url::Origin embedding_origin = context_->GetEmbeddingOrigin(); |
| 342 GURL embedding_origin = context_->GetEmbeddingOrigin(); | |
| 343 browser_context->GetPermissionManager()->ResetPermission( | 331 browser_context->GetPermissionManager()->ResetPermission( |
| 344 type, origin, embedding_origin.is_empty() ? origin : embedding_origin); | 332 type, origin, embedding_origin.empty() ? origin : embedding_origin); |
| 345 } | 333 } |
| 346 | 334 |
| 347 void PermissionServiceImpl::OnPermissionStatusChanged( | 335 void PermissionServiceImpl::OnPermissionStatusChanged( |
| 348 int pending_subscription_id, | 336 int pending_subscription_id, |
| 349 mojom::PermissionStatus status) { | 337 mojom::PermissionStatus status) { |
| 350 PendingSubscription* subscription = | 338 PendingSubscription* subscription = |
| 351 pending_subscriptions_.Lookup(pending_subscription_id); | 339 pending_subscriptions_.Lookup(pending_subscription_id); |
| 352 | 340 |
| 353 BrowserContext* browser_context = context_->GetBrowserContext(); | 341 BrowserContext* browser_context = context_->GetBrowserContext(); |
| 354 DCHECK(browser_context); | 342 DCHECK(browser_context); |
| 355 if (browser_context->GetPermissionManager()) { | 343 if (browser_context->GetPermissionManager()) { |
| 356 browser_context->GetPermissionManager()->UnsubscribePermissionStatusChange( | 344 browser_context->GetPermissionManager()->UnsubscribePermissionStatusChange( |
| 357 subscription->id); | 345 subscription->id); |
| 358 } | 346 } |
| 359 | 347 |
| 360 PermissionStatusCallback callback = subscription->callback; | 348 PermissionStatusCallback callback = subscription->callback; |
| 361 | 349 |
| 362 subscription->callback.reset(); | 350 subscription->callback.reset(); |
| 363 pending_subscriptions_.Remove(pending_subscription_id); | 351 pending_subscriptions_.Remove(pending_subscription_id); |
| 364 | 352 |
| 365 callback.Run(status); | 353 callback.Run(status); |
| 366 } | 354 } |
| 367 | 355 |
| 368 } // namespace content | 356 } // namespace content |
| OLD | NEW |