Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: content/browser/permissions/permission_service_impl.cc

Issue 1771743002: Move geolocation and permission mojoms into WebKit/public/platform. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 14
15 using blink::mojom::PermissionName;
16 using blink::mojom::PermissionStatus;
17
15 namespace content { 18 namespace content {
16 19
17 namespace { 20 namespace {
18 21
19 PermissionType PermissionNameToPermissionType(mojom::PermissionName name) { 22 PermissionType PermissionNameToPermissionType(PermissionName name) {
20 switch(name) { 23 switch(name) {
21 case mojom::PermissionName::GEOLOCATION: 24 case PermissionName::GEOLOCATION:
22 return PermissionType::GEOLOCATION; 25 return PermissionType::GEOLOCATION;
23 case mojom::PermissionName::NOTIFICATIONS: 26 case PermissionName::NOTIFICATIONS:
24 return PermissionType::NOTIFICATIONS; 27 return PermissionType::NOTIFICATIONS;
25 case mojom::PermissionName::PUSH_NOTIFICATIONS: 28 case PermissionName::PUSH_NOTIFICATIONS:
26 return PermissionType::PUSH_MESSAGING; 29 return PermissionType::PUSH_MESSAGING;
27 case mojom::PermissionName::MIDI: 30 case PermissionName::MIDI:
28 return PermissionType::MIDI; 31 return PermissionType::MIDI;
29 case mojom::PermissionName::MIDI_SYSEX: 32 case PermissionName::MIDI_SYSEX:
30 return PermissionType::MIDI_SYSEX; 33 return PermissionType::MIDI_SYSEX;
31 case mojom::PermissionName::PROTECTED_MEDIA_IDENTIFIER: 34 case PermissionName::PROTECTED_MEDIA_IDENTIFIER:
32 return PermissionType::PROTECTED_MEDIA_IDENTIFIER; 35 return PermissionType::PROTECTED_MEDIA_IDENTIFIER;
33 case mojom::PermissionName::DURABLE_STORAGE: 36 case PermissionName::DURABLE_STORAGE:
34 return PermissionType::DURABLE_STORAGE; 37 return PermissionType::DURABLE_STORAGE;
35 case mojom::PermissionName::AUDIO_CAPTURE: 38 case PermissionName::AUDIO_CAPTURE:
36 return PermissionType::AUDIO_CAPTURE; 39 return PermissionType::AUDIO_CAPTURE;
37 case mojom::PermissionName::VIDEO_CAPTURE: 40 case PermissionName::VIDEO_CAPTURE:
38 return PermissionType::VIDEO_CAPTURE; 41 return PermissionType::VIDEO_CAPTURE;
39 case mojom::PermissionName::BACKGROUND_SYNC: 42 case PermissionName::BACKGROUND_SYNC:
40 return PermissionType::BACKGROUND_SYNC; 43 return PermissionType::BACKGROUND_SYNC;
41 } 44 }
42 45
43 NOTREACHED(); 46 NOTREACHED();
44 return PermissionType::NUM; 47 return PermissionType::NUM;
45 } 48 }
46 49
47 // This function allows the usage of the the multiple request map 50 // This function allows the usage of the the multiple request map
48 // with single requests. 51 // with single requests.
49 void PermissionRequestResponseCallbackWrapper( 52 void PermissionRequestResponseCallbackWrapper(
50 const mojo::Callback<void(mojom::PermissionStatus)>& callback, 53 const mojo::Callback<void(PermissionStatus)>& callback,
51 const mojo::Array<mojom::PermissionStatus>& vector) { 54 const mojo::Array<PermissionStatus>& vector) {
52 DCHECK_EQ(vector.size(), 1ul); 55 DCHECK_EQ(vector.size(), 1ul);
53 callback.Run(vector[0]); 56 callback.Run(vector[0]);
54 } 57 }
55 58
56 } // anonymous namespace 59 } // anonymous namespace
57 60
58 PermissionServiceImpl::PendingRequest::PendingRequest( 61 PermissionServiceImpl::PendingRequest::PendingRequest(
59 const PermissionsStatusCallback& callback, 62 const PermissionsStatusCallback& callback,
60 int request_count) 63 int request_count)
61 : callback(callback), 64 : callback(callback),
62 request_count(request_count) { 65 request_count(request_count) {
63 } 66 }
64 67
65 PermissionServiceImpl::PendingRequest::~PendingRequest() { 68 PermissionServiceImpl::PendingRequest::~PendingRequest() {
66 if (callback.is_null()) 69 if (callback.is_null())
67 return; 70 return;
68 71
69 mojo::Array<mojom::PermissionStatus> result = 72 mojo::Array<PermissionStatus> result =
70 mojo::Array<mojom::PermissionStatus>::New(request_count); 73 mojo::Array<PermissionStatus>::New(request_count);
71 for (int i = 0; i < request_count; ++i) 74 for (int i = 0; i < request_count; ++i)
72 result[i] = mojom::PermissionStatus::DENIED; 75 result[i] = PermissionStatus::DENIED;
73 callback.Run(std::move(result)); 76 callback.Run(std::move(result));
74 } 77 }
75 78
76 PermissionServiceImpl::PendingSubscription::PendingSubscription( 79 PermissionServiceImpl::PendingSubscription::PendingSubscription(
77 PermissionType permission, 80 PermissionType permission,
78 const GURL& origin, 81 const GURL& origin,
79 const PermissionStatusCallback& callback) 82 const PermissionStatusCallback& callback)
80 : id(-1), 83 : id(-1),
81 permission(permission), 84 permission(permission),
82 origin(origin), 85 origin(origin),
83 callback(callback) { 86 callback(callback) {
84 } 87 }
85 88
86 PermissionServiceImpl::PendingSubscription::~PendingSubscription() { 89 PermissionServiceImpl::PendingSubscription::~PendingSubscription() {
87 if (!callback.is_null()) 90 if (!callback.is_null())
88 callback.Run(mojom::PermissionStatus::ASK); 91 callback.Run(PermissionStatus::ASK);
89 } 92 }
90 93
91 PermissionServiceImpl::PermissionServiceImpl( 94 PermissionServiceImpl::PermissionServiceImpl(
92 PermissionServiceContext* context, 95 PermissionServiceContext* context,
93 mojo::InterfaceRequest<mojom::PermissionService> request) 96 mojo::InterfaceRequest<blink::mojom::PermissionService> request)
94 : context_(context), 97 : context_(context),
95 binding_(this, std::move(request)), 98 binding_(this, std::move(request)),
96 weak_factory_(this) { 99 weak_factory_(this) {
97 binding_.set_connection_error_handler( 100 binding_.set_connection_error_handler(
98 base::Bind(&PermissionServiceImpl::OnConnectionError, 101 base::Bind(&PermissionServiceImpl::OnConnectionError,
99 base::Unretained(this))); 102 base::Unretained(this)));
100 } 103 }
101 104
102 PermissionServiceImpl::~PermissionServiceImpl() { 105 PermissionServiceImpl::~PermissionServiceImpl() {
103 DCHECK(pending_requests_.IsEmpty()); 106 DCHECK(pending_requests_.IsEmpty());
104 } 107 }
105 108
106 void PermissionServiceImpl::OnConnectionError() { 109 void PermissionServiceImpl::OnConnectionError() {
107 context_->ServiceHadConnectionError(this); 110 context_->ServiceHadConnectionError(this);
108 // After that call, |this| will be deleted. 111 // After that call, |this| will be deleted.
109 } 112 }
110 113
111 void PermissionServiceImpl::RequestPermission( 114 void PermissionServiceImpl::RequestPermission(
112 mojom::PermissionName permission, 115 PermissionName permission,
113 const mojo::String& origin, 116 const mojo::String& origin,
114 const PermissionStatusCallback& callback) { 117 const PermissionStatusCallback& callback) {
115 // This condition is valid if the call is coming from a ChildThread instead of 118 // This condition is valid if the call is coming from a ChildThread instead of
116 // a RenderFrame. Some consumers of the service run in Workers and some in 119 // a RenderFrame. Some consumers of the service run in Workers and some in
117 // Frames. In the context of a Worker, it is not possible to show a 120 // Frames. In the context of a Worker, it is not possible to show a
118 // permission prompt because there is no tab. In the context of a Frame, we 121 // permission prompt because there is no tab. In the context of a Frame, we
119 // can. Even if the call comes from a context where it is not possible to show 122 // can. Even if the call comes from a context where it is not possible to show
120 // any UI, we want to still return something relevant so the current 123 // any UI, we want to still return something relevant so the current
121 // permission status is returned. 124 // permission status is returned.
122 BrowserContext* browser_context = context_->GetBrowserContext(); 125 BrowserContext* browser_context = context_->GetBrowserContext();
(...skipping 18 matching lines...) Expand all
141 // callback if it was run synchronously. 144 // callback if it was run synchronously.
142 PendingRequest* pending_request = pending_requests_.Lookup( 145 PendingRequest* pending_request = pending_requests_.Lookup(
143 pending_request_id); 146 pending_request_id);
144 if (!pending_request) 147 if (!pending_request)
145 return; 148 return;
146 pending_request->id = id; 149 pending_request->id = id;
147 } 150 }
148 151
149 void PermissionServiceImpl::OnRequestPermissionResponse( 152 void PermissionServiceImpl::OnRequestPermissionResponse(
150 int pending_request_id, 153 int pending_request_id,
151 mojom::PermissionStatus status) { 154 PermissionStatus status) {
152 OnRequestPermissionsResponse(pending_request_id, 155 OnRequestPermissionsResponse(pending_request_id,
153 std::vector<mojom::PermissionStatus>(1, status)); 156 std::vector<PermissionStatus>(1, status));
154 } 157 }
155 158
156 void PermissionServiceImpl::RequestPermissions( 159 void PermissionServiceImpl::RequestPermissions(
157 mojo::Array<mojom::PermissionName> permissions, 160 mojo::Array<PermissionName> permissions,
158 const mojo::String& origin, 161 const mojo::String& origin,
159 const PermissionsStatusCallback& callback) { 162 const PermissionsStatusCallback& callback) {
160 if (permissions.is_null()) { 163 if (permissions.is_null()) {
161 callback.Run(mojo::Array<mojom::PermissionStatus>()); 164 callback.Run(mojo::Array<PermissionStatus>());
162 return; 165 return;
163 } 166 }
164 167
165 // This condition is valid if the call is coming from a ChildThread instead of 168 // This condition is valid if the call is coming from a ChildThread instead of
166 // a RenderFrame. Some consumers of the service run in Workers and some in 169 // a RenderFrame. Some consumers of the service run in Workers and some in
167 // Frames. In the context of a Worker, it is not possible to show a 170 // Frames. In the context of a Worker, it is not possible to show a
168 // permission prompt because there is no tab. In the context of a Frame, we 171 // permission prompt because there is no tab. In the context of a Frame, we
169 // can. Even if the call comes from a context where it is not possible to show 172 // can. Even if the call comes from a context where it is not possible to show
170 // any UI, we want to still return something relevant so the current 173 // any UI, we want to still return something relevant so the current
171 // permission status is returned for each permission. 174 // permission status is returned for each permission.
172 BrowserContext* browser_context = context_->GetBrowserContext(); 175 BrowserContext* browser_context = context_->GetBrowserContext();
173 DCHECK(browser_context); 176 DCHECK(browser_context);
174 if (!context_->render_frame_host() || 177 if (!context_->render_frame_host() ||
175 !browser_context->GetPermissionManager()) { 178 !browser_context->GetPermissionManager()) {
176 mojo::Array<mojom::PermissionStatus> result(permissions.size()); 179 mojo::Array<PermissionStatus> result(permissions.size());
177 for (size_t i = 0; i < permissions.size(); ++i) { 180 for (size_t i = 0; i < permissions.size(); ++i) {
178 result[i] = 181 result[i] =
179 GetPermissionStatusFromName(permissions[i], GURL(origin.get())); 182 GetPermissionStatusFromName(permissions[i], GURL(origin.get()));
180 } 183 }
181 callback.Run(std::move(result)); 184 callback.Run(std::move(result));
182 return; 185 return;
183 } 186 }
184 187
185 std::vector<PermissionType> types(permissions.size()); 188 std::vector<PermissionType> types(permissions.size());
186 for (size_t i = 0; i < types.size(); ++i) 189 for (size_t i = 0; i < types.size(); ++i)
(...skipping 13 matching lines...) Expand all
200 // the response callback. 203 // the response callback.
201 PendingRequest* pending_request = pending_requests_.Lookup( 204 PendingRequest* pending_request = pending_requests_.Lookup(
202 pending_request_id); 205 pending_request_id);
203 if (!pending_request) 206 if (!pending_request)
204 return; 207 return;
205 pending_request->id = id; 208 pending_request->id = id;
206 } 209 }
207 210
208 void PermissionServiceImpl::OnRequestPermissionsResponse( 211 void PermissionServiceImpl::OnRequestPermissionsResponse(
209 int pending_request_id, 212 int pending_request_id,
210 const std::vector<mojom::PermissionStatus>& result) { 213 const std::vector<PermissionStatus>& result) {
211 PendingRequest* request = pending_requests_.Lookup(pending_request_id); 214 PendingRequest* request = pending_requests_.Lookup(pending_request_id);
212 PermissionsStatusCallback callback(request->callback); 215 PermissionsStatusCallback callback(request->callback);
213 request->callback.reset(); 216 request->callback.reset();
214 pending_requests_.Remove(pending_request_id); 217 pending_requests_.Remove(pending_request_id);
215 callback.Run(mojo::Array<mojom::PermissionStatus>::From(result)); 218 callback.Run(mojo::Array<PermissionStatus>::From(result));
216 } 219 }
217 220
218 void PermissionServiceImpl::CancelPendingOperations() { 221 void PermissionServiceImpl::CancelPendingOperations() {
219 DCHECK(context_->GetBrowserContext()); 222 DCHECK(context_->GetBrowserContext());
220 223
221 PermissionManager* permission_manager = 224 PermissionManager* permission_manager =
222 context_->GetBrowserContext()->GetPermissionManager(); 225 context_->GetBrowserContext()->GetPermissionManager();
223 if (!permission_manager) 226 if (!permission_manager)
224 return; 227 return;
225 228
(...skipping 11 matching lines...) Expand all
237 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( 240 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType(
238 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); 241 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin));
239 it.GetCurrentValue()->callback.reset(); 242 it.GetCurrentValue()->callback.reset();
240 permission_manager->UnsubscribePermissionStatusChange( 243 permission_manager->UnsubscribePermissionStatusChange(
241 it.GetCurrentValue()->id); 244 it.GetCurrentValue()->id);
242 } 245 }
243 pending_subscriptions_.Clear(); 246 pending_subscriptions_.Clear();
244 } 247 }
245 248
246 void PermissionServiceImpl::HasPermission( 249 void PermissionServiceImpl::HasPermission(
247 mojom::PermissionName permission, 250 PermissionName permission,
248 const mojo::String& origin, 251 const mojo::String& origin,
249 const PermissionStatusCallback& callback) { 252 const PermissionStatusCallback& callback) {
250 callback.Run(GetPermissionStatusFromName(permission, GURL(origin.get()))); 253 callback.Run(GetPermissionStatusFromName(permission, GURL(origin.get())));
251 } 254 }
252 255
253 void PermissionServiceImpl::RevokePermission( 256 void PermissionServiceImpl::RevokePermission(
254 mojom::PermissionName permission, 257 PermissionName permission,
255 const mojo::String& origin, 258 const mojo::String& origin,
256 const PermissionStatusCallback& callback) { 259 const PermissionStatusCallback& callback) {
257 GURL origin_url(origin.get()); 260 GURL origin_url(origin.get());
258 PermissionType permission_type = PermissionNameToPermissionType(permission); 261 PermissionType permission_type = PermissionNameToPermissionType(permission);
259 mojom::PermissionStatus status = 262 PermissionStatus status =
260 GetPermissionStatusFromType(permission_type, origin_url); 263 GetPermissionStatusFromType(permission_type, origin_url);
261 264
262 // Resetting the permission should only be possible if the permission is 265 // Resetting the permission should only be possible if the permission is
263 // already granted. 266 // already granted.
264 if (status != mojom::PermissionStatus::GRANTED) { 267 if (status != PermissionStatus::GRANTED) {
265 callback.Run(status); 268 callback.Run(status);
266 return; 269 return;
267 } 270 }
268 271
269 ResetPermissionStatus(permission_type, origin_url); 272 ResetPermissionStatus(permission_type, origin_url);
270 273
271 callback.Run(GetPermissionStatusFromType(permission_type, origin_url)); 274 callback.Run(GetPermissionStatusFromType(permission_type, origin_url));
272 } 275 }
273 276
274 void PermissionServiceImpl::GetNextPermissionChange( 277 void PermissionServiceImpl::GetNextPermissionChange(
275 mojom::PermissionName permission, 278 PermissionName permission,
276 const mojo::String& mojo_origin, 279 const mojo::String& mojo_origin,
277 mojom::PermissionStatus last_known_status, 280 PermissionStatus last_known_status,
278 const PermissionStatusCallback& callback) { 281 const PermissionStatusCallback& callback) {
279 GURL origin(mojo_origin.get()); 282 GURL origin(mojo_origin.get());
280 mojom::PermissionStatus current_status = 283 PermissionStatus current_status =
281 GetPermissionStatusFromName(permission, origin); 284 GetPermissionStatusFromName(permission, origin);
282 if (current_status != last_known_status) { 285 if (current_status != last_known_status) {
283 callback.Run(current_status); 286 callback.Run(current_status);
284 return; 287 return;
285 } 288 }
286 289
287 BrowserContext* browser_context = context_->GetBrowserContext(); 290 BrowserContext* browser_context = context_->GetBrowserContext();
288 DCHECK(browser_context); 291 DCHECK(browser_context);
289 if (!browser_context->GetPermissionManager()) { 292 if (!browser_context->GetPermissionManager()) {
290 callback.Run(current_status); 293 callback.Run(current_status);
(...skipping 14 matching lines...) Expand all
305 browser_context->GetPermissionManager()->SubscribePermissionStatusChange( 308 browser_context->GetPermissionManager()->SubscribePermissionStatusChange(
306 permission_type, 309 permission_type,
307 origin, 310 origin,
308 // If the embedding_origin is empty, we,ll use the |origin| instead. 311 // If the embedding_origin is empty, we,ll use the |origin| instead.
309 embedding_origin.is_empty() ? origin : embedding_origin, 312 embedding_origin.is_empty() ? origin : embedding_origin,
310 base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged, 313 base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged,
311 weak_factory_.GetWeakPtr(), 314 weak_factory_.GetWeakPtr(),
312 pending_subscription_id)); 315 pending_subscription_id));
313 } 316 }
314 317
315 mojom::PermissionStatus PermissionServiceImpl::GetPermissionStatusFromName( 318 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromName(
316 mojom::PermissionName permission, 319 PermissionName permission,
317 const GURL& origin) { 320 const GURL& origin) {
318 return GetPermissionStatusFromType(PermissionNameToPermissionType(permission), 321 return GetPermissionStatusFromType(PermissionNameToPermissionType(permission),
319 origin); 322 origin);
320 } 323 }
321 324
322 mojom::PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType( 325 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType(
323 PermissionType type, 326 PermissionType type,
324 const GURL& origin) { 327 const GURL& origin) {
325 BrowserContext* browser_context = context_->GetBrowserContext(); 328 BrowserContext* browser_context = context_->GetBrowserContext();
326 DCHECK(browser_context); 329 DCHECK(browser_context);
327 if (!browser_context->GetPermissionManager()) 330 if (!browser_context->GetPermissionManager())
328 return mojom::PermissionStatus::DENIED; 331 return PermissionStatus::DENIED;
329 332
330 // If the embedding_origin is empty we'll use |origin| instead. 333 // If the embedding_origin is empty we'll use |origin| instead.
331 GURL embedding_origin = context_->GetEmbeddingOrigin(); 334 GURL embedding_origin = context_->GetEmbeddingOrigin();
332 return browser_context->GetPermissionManager()->GetPermissionStatus( 335 return browser_context->GetPermissionManager()->GetPermissionStatus(
333 type, origin, embedding_origin.is_empty() ? origin : embedding_origin); 336 type, origin, embedding_origin.is_empty() ? origin : embedding_origin);
334 } 337 }
335 338
336 void PermissionServiceImpl::ResetPermissionStatus(PermissionType type, 339 void PermissionServiceImpl::ResetPermissionStatus(PermissionType type,
337 const GURL& origin) { 340 const GURL& origin) {
338 BrowserContext* browser_context = context_->GetBrowserContext(); 341 BrowserContext* browser_context = context_->GetBrowserContext();
339 DCHECK(browser_context); 342 DCHECK(browser_context);
340 if (!browser_context->GetPermissionManager()) 343 if (!browser_context->GetPermissionManager())
341 return; 344 return;
342 345
343 // If the embedding_origin is empty we'll use |origin| instead. 346 // If the embedding_origin is empty we'll use |origin| instead.
344 GURL embedding_origin = context_->GetEmbeddingOrigin(); 347 GURL embedding_origin = context_->GetEmbeddingOrigin();
345 browser_context->GetPermissionManager()->ResetPermission( 348 browser_context->GetPermissionManager()->ResetPermission(
346 type, origin, embedding_origin.is_empty() ? origin : embedding_origin); 349 type, origin, embedding_origin.is_empty() ? origin : embedding_origin);
347 } 350 }
348 351
349 void PermissionServiceImpl::OnPermissionStatusChanged( 352 void PermissionServiceImpl::OnPermissionStatusChanged(
350 int pending_subscription_id, 353 int pending_subscription_id,
351 mojom::PermissionStatus status) { 354 PermissionStatus status) {
352 PendingSubscription* subscription = 355 PendingSubscription* subscription =
353 pending_subscriptions_.Lookup(pending_subscription_id); 356 pending_subscriptions_.Lookup(pending_subscription_id);
354 357
355 BrowserContext* browser_context = context_->GetBrowserContext(); 358 BrowserContext* browser_context = context_->GetBrowserContext();
356 DCHECK(browser_context); 359 DCHECK(browser_context);
357 if (browser_context->GetPermissionManager()) { 360 if (browser_context->GetPermissionManager()) {
358 browser_context->GetPermissionManager()->UnsubscribePermissionStatusChange( 361 browser_context->GetPermissionManager()->UnsubscribePermissionStatusChange(
359 subscription->id); 362 subscription->id);
360 } 363 }
361 364
362 PermissionStatusCallback callback = subscription->callback; 365 PermissionStatusCallback callback = subscription->callback;
363 366
364 subscription->callback.reset(); 367 subscription->callback.reset();
365 pending_subscriptions_.Remove(pending_subscription_id); 368 pending_subscriptions_.Remove(pending_subscription_id);
366 369
367 callback.Run(status); 370 callback.Run(status);
368 } 371 }
369 372
370 } // namespace content 373 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/permissions/permission_service_impl.h ('k') | content/browser/push_messaging/push_messaging_message_filter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698