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

Side by Side Diff: chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc

Issue 22694006: Infobar system refactor. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/geolocation/chrome_geolocation_permission_context.h" 5 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 ClosedInfoBarTracker(); 49 ClosedInfoBarTracker();
50 virtual ~ClosedInfoBarTracker(); 50 virtual ~ClosedInfoBarTracker();
51 51
52 // content::NotificationObserver: 52 // content::NotificationObserver:
53 virtual void Observe(int type, 53 virtual void Observe(int type,
54 const content::NotificationSource& source, 54 const content::NotificationSource& source,
55 const content::NotificationDetails& details) OVERRIDE; 55 const content::NotificationDetails& details) OVERRIDE;
56 56
57 size_t size() const { return removed_infobars_.size(); } 57 size_t size() const { return removed_infobars_.size(); }
58 58
59 bool Contains(InfoBarDelegate* infobar) const; 59 bool Contains(InfoBar* infobar) const;
60 void Clear(); 60 void Clear();
61 61
62 private: 62 private:
63 FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests, TabDestroyed); 63 FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests, TabDestroyed);
64 content::NotificationRegistrar registrar_; 64 content::NotificationRegistrar registrar_;
65 std::set<InfoBarDelegate*> removed_infobars_; 65 std::set<InfoBar*> removed_infobars_;
66 }; 66 };
67 67
68 ClosedInfoBarTracker::ClosedInfoBarTracker() { 68 ClosedInfoBarTracker::ClosedInfoBarTracker() {
69 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, 69 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
70 content::NotificationService::AllSources()); 70 content::NotificationService::AllSources());
71 } 71 }
72 72
73 ClosedInfoBarTracker::~ClosedInfoBarTracker() { 73 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
74 } 74 }
75 75
76 void ClosedInfoBarTracker::Observe( 76 void ClosedInfoBarTracker::Observe(
77 int type, 77 int type,
78 const content::NotificationSource& source, 78 const content::NotificationSource& source,
79 const content::NotificationDetails& details) { 79 const content::NotificationDetails& details) {
80 DCHECK(type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED); 80 DCHECK(type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED);
81 removed_infobars_.insert( 81 removed_infobars_.insert(
82 content::Details<InfoBar::RemovedDetails>(details)->first); 82 content::Details<InfoBar::RemovedDetails>(details)->first);
83 } 83 }
84 84
85 bool ClosedInfoBarTracker::Contains(InfoBarDelegate* infobar) const { 85 bool ClosedInfoBarTracker::Contains(InfoBar* infobar) const {
86 return removed_infobars_.count(infobar) != 0; 86 return removed_infobars_.count(infobar) != 0;
87 } 87 }
88 88
89 void ClosedInfoBarTracker::Clear() { 89 void ClosedInfoBarTracker::Clear() {
90 removed_infobars_.clear(); 90 removed_infobars_.clear();
91 } 91 }
92 92
93 93
94 // GeolocationPermissionContextTests ------------------------------------------ 94 // GeolocationPermissionContextTests ------------------------------------------
95 95
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 251 }
252 252
253 // Tests ---------------------------------------------------------------------- 253 // Tests ----------------------------------------------------------------------
254 254
255 TEST_F(GeolocationPermissionContextTests, SinglePermission) { 255 TEST_F(GeolocationPermissionContextTests, SinglePermission) {
256 GURL requesting_frame("http://www.example.com/geolocation"); 256 GURL requesting_frame("http://www.example.com/geolocation");
257 NavigateAndCommit(requesting_frame); 257 NavigateAndCommit(requesting_frame);
258 EXPECT_EQ(0U, infobar_service()->infobar_count()); 258 EXPECT_EQ(0U, infobar_service()->infobar_count());
259 RequestGeolocationPermission(RequestID(0), requesting_frame); 259 RequestGeolocationPermission(RequestID(0), requesting_frame);
260 ASSERT_EQ(1U, infobar_service()->infobar_count()); 260 ASSERT_EQ(1U, infobar_service()->infobar_count());
261 InfoBar* infobar = infobar_service()->infobar_at(0);
261 ConfirmInfoBarDelegate* infobar_delegate = 262 ConfirmInfoBarDelegate* infobar_delegate =
262 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 263 infobar->delegate()->AsConfirmInfoBarDelegate();
263 ASSERT_TRUE(infobar_delegate); 264 ASSERT_TRUE(infobar_delegate);
264 infobar_delegate->Cancel(); 265 infobar_delegate->Cancel();
265 infobar_service()->RemoveInfoBar(infobar_delegate); 266 infobar_service()->RemoveInfoBar(infobar);
266 EXPECT_EQ(1U, closed_infobar_tracker_.size()); 267 EXPECT_EQ(1U, closed_infobar_tracker_.size());
267 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate)); 268 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar));
268 delete infobar_delegate;
269 } 269 }
270 270
271 #if defined(OS_ANDROID) 271 #if defined(OS_ANDROID)
272 TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) { 272 TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) {
273 GURL requesting_frame("http://www.example.com/geolocation"); 273 GURL requesting_frame("http://www.example.com/geolocation");
274 NavigateAndCommit(requesting_frame); 274 NavigateAndCommit(requesting_frame);
275 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true); 275 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
276 EXPECT_EQ(0U, infobar_service()->infobar_count()); 276 EXPECT_EQ(0U, infobar_service()->infobar_count());
277 RequestGeolocationPermission(RequestID(0), requesting_frame); 277 RequestGeolocationPermission(RequestID(0), requesting_frame);
278 EXPECT_EQ(1U, infobar_service()->infobar_count()); 278 EXPECT_EQ(1U, infobar_service()->infobar_count());
279 ConfirmInfoBarDelegate* infobar_delegate_0 = 279 ConfirmInfoBarDelegate* infobar_delegate_0 = infobar_service()->
280 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 280 infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
281 ASSERT_TRUE(infobar_delegate_0); 281 ASSERT_TRUE(infobar_delegate_0);
282 string16 text_0 = infobar_delegate_0->GetButtonLabel( 282 string16 text_0 = infobar_delegate_0->GetButtonLabel(
283 ConfirmInfoBarDelegate::BUTTON_OK); 283 ConfirmInfoBarDelegate::BUTTON_OK);
284 284
285 NavigateAndCommit(requesting_frame); 285 NavigateAndCommit(requesting_frame);
286 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false); 286 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
287 EXPECT_EQ(0U, infobar_service()->infobar_count()); 287 EXPECT_EQ(0U, infobar_service()->infobar_count());
288 RequestGeolocationPermission(RequestID(0), requesting_frame); 288 RequestGeolocationPermission(RequestID(0), requesting_frame);
289 EXPECT_EQ(1U, infobar_service()->infobar_count()); 289 EXPECT_EQ(1U, infobar_service()->infobar_count());
290 ConfirmInfoBarDelegate* infobar_delegate_1 = 290 ConfirmInfoBarDelegate* infobar_delegate_1 = infobar_service()->
291 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 291 infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
292 ASSERT_TRUE(infobar_delegate_1); 292 ASSERT_TRUE(infobar_delegate_1);
293 string16 text_1 = infobar_delegate_1->GetButtonLabel( 293 string16 text_1 = infobar_delegate_1->GetButtonLabel(
294 ConfirmInfoBarDelegate::BUTTON_OK); 294 ConfirmInfoBarDelegate::BUTTON_OK);
295 EXPECT_NE(text_0, text_1); 295 EXPECT_NE(text_0, text_1);
296 296
297 NavigateAndCommit(requesting_frame); 297 NavigateAndCommit(requesting_frame);
298 MockGoogleLocationSettingsHelper::SetLocationStatus(false, false); 298 MockGoogleLocationSettingsHelper::SetLocationStatus(false, false);
299 EXPECT_EQ(0U, infobar_service()->infobar_count()); 299 EXPECT_EQ(0U, infobar_service()->infobar_count());
300 RequestGeolocationPermission(RequestID(0), requesting_frame); 300 RequestGeolocationPermission(RequestID(0), requesting_frame);
301 EXPECT_EQ(0U, infobar_service()->infobar_count()); 301 EXPECT_EQ(0U, infobar_service()->infobar_count());
302 } 302 }
303 303
304 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsEnabled) { 304 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsEnabled) {
305 GURL requesting_frame("http://www.example.com/geolocation"); 305 GURL requesting_frame("http://www.example.com/geolocation");
306 NavigateAndCommit(requesting_frame); 306 NavigateAndCommit(requesting_frame);
307 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true); 307 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
308 EXPECT_EQ(0U, infobar_service()->infobar_count()); 308 EXPECT_EQ(0U, infobar_service()->infobar_count());
309 RequestGeolocationPermission(RequestID(0), requesting_frame); 309 RequestGeolocationPermission(RequestID(0), requesting_frame);
310 EXPECT_EQ(1U, infobar_service()->infobar_count()); 310 EXPECT_EQ(1U, infobar_service()->infobar_count());
311 ConfirmInfoBarDelegate* infobar_delegate = 311 ConfirmInfoBarDelegate* infobar_delegate = infobar_service()->
312 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 312 infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
313 ASSERT_TRUE(infobar_delegate); 313 ASSERT_TRUE(infobar_delegate);
314 infobar_delegate->Accept(); 314 infobar_delegate->Accept();
315 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW); 315 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
316 CheckPermissionMessageSent(0, true); 316 CheckPermissionMessageSent(0, true);
317 } 317 }
318 318
319 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsDisabled) { 319 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsDisabled) {
320 GURL requesting_frame("http://www.example.com/geolocation"); 320 GURL requesting_frame("http://www.example.com/geolocation");
321 NavigateAndCommit(requesting_frame); 321 NavigateAndCommit(requesting_frame);
322 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false); 322 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
323 EXPECT_EQ(0U, infobar_service()->infobar_count()); 323 EXPECT_EQ(0U, infobar_service()->infobar_count());
324 RequestGeolocationPermission(RequestID(0), requesting_frame); 324 RequestGeolocationPermission(RequestID(0), requesting_frame);
325 EXPECT_EQ(1U, infobar_service()->infobar_count()); 325 EXPECT_EQ(1U, infobar_service()->infobar_count());
326 ConfirmInfoBarDelegate* infobar_delegate = 326 ConfirmInfoBarDelegate* infobar_delegate = infobar_service()->
327 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 327 infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
328 ASSERT_TRUE(infobar_delegate); 328 ASSERT_TRUE(infobar_delegate);
329 infobar_delegate->Accept(); 329 infobar_delegate->Accept();
330 EXPECT_TRUE( 330 EXPECT_TRUE(
331 MockGoogleLocationSettingsHelper::WasGoogleLocationSettingsCalled()); 331 MockGoogleLocationSettingsHelper::WasGoogleLocationSettingsCalled());
332 } 332 }
333 #endif 333 #endif
334 334
335 TEST_F(GeolocationPermissionContextTests, QueuedPermission) { 335 TEST_F(GeolocationPermissionContextTests, QueuedPermission) {
336 GURL requesting_frame_0("http://www.example.com/geolocation"); 336 GURL requesting_frame_0("http://www.example.com/geolocation");
337 GURL requesting_frame_1("http://www.example-2.com/geolocation"); 337 GURL requesting_frame_1("http://www.example-2.com/geolocation");
338 EXPECT_EQ(CONTENT_SETTING_ASK, 338 EXPECT_EQ(CONTENT_SETTING_ASK,
339 profile()->GetHostContentSettingsMap()->GetContentSetting( 339 profile()->GetHostContentSettingsMap()->GetContentSetting(
340 requesting_frame_0, requesting_frame_0, 340 requesting_frame_0, requesting_frame_0,
341 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); 341 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
342 EXPECT_EQ(CONTENT_SETTING_ASK, 342 EXPECT_EQ(CONTENT_SETTING_ASK,
343 profile()->GetHostContentSettingsMap()->GetContentSetting( 343 profile()->GetHostContentSettingsMap()->GetContentSetting(
344 requesting_frame_1, requesting_frame_0, 344 requesting_frame_1, requesting_frame_0,
345 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); 345 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
346 346
347 NavigateAndCommit(requesting_frame_0); 347 NavigateAndCommit(requesting_frame_0);
348 EXPECT_EQ(0U, infobar_service()->infobar_count()); 348 EXPECT_EQ(0U, infobar_service()->infobar_count());
349 // Request permission for two frames. 349 // Request permission for two frames.
350 RequestGeolocationPermission(RequestID(0), requesting_frame_0); 350 RequestGeolocationPermission(RequestID(0), requesting_frame_0);
351 RequestGeolocationPermission(RequestID(1), requesting_frame_1); 351 RequestGeolocationPermission(RequestID(1), requesting_frame_1);
352 // Ensure only one infobar is created. 352 // Ensure only one infobar is created.
353 ASSERT_EQ(1U, infobar_service()->infobar_count()); 353 ASSERT_EQ(1U, infobar_service()->infobar_count());
354 InfoBar* infobar_0 = infobar_service()->infobar_at(0);
354 ConfirmInfoBarDelegate* infobar_delegate_0 = 355 ConfirmInfoBarDelegate* infobar_delegate_0 =
355 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 356 infobar_0->delegate()->AsConfirmInfoBarDelegate();
356 ASSERT_TRUE(infobar_delegate_0); 357 ASSERT_TRUE(infobar_delegate_0);
357 string16 text_0 = infobar_delegate_0->GetMessageText(); 358 string16 text_0 = infobar_delegate_0->GetMessageText();
358 359
359 // Accept the first frame. 360 // Accept the first frame.
360 infobar_delegate_0->Accept(); 361 infobar_delegate_0->Accept();
361 CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW); 362 CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW);
362 CheckPermissionMessageSent(0, true); 363 CheckPermissionMessageSent(0, true);
363 364
364 infobar_service()->RemoveInfoBar(infobar_delegate_0); 365 infobar_service()->RemoveInfoBar(infobar_0);
365 EXPECT_EQ(1U, closed_infobar_tracker_.size()); 366 EXPECT_EQ(1U, closed_infobar_tracker_.size());
366 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0)); 367 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
367 closed_infobar_tracker_.Clear(); 368 closed_infobar_tracker_.Clear();
368 delete infobar_delegate_0;
369 // Now we should have a new infobar for the second frame. 369 // Now we should have a new infobar for the second frame.
370 ASSERT_EQ(1U, infobar_service()->infobar_count()); 370 ASSERT_EQ(1U, infobar_service()->infobar_count());
371 371
372 InfoBar* infobar_1 = infobar_service()->infobar_at(0);
372 ConfirmInfoBarDelegate* infobar_delegate_1 = 373 ConfirmInfoBarDelegate* infobar_delegate_1 =
373 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 374 infobar_1->delegate()->AsConfirmInfoBarDelegate();
374 ASSERT_TRUE(infobar_delegate_1); 375 ASSERT_TRUE(infobar_delegate_1);
375 string16 text_1 = infobar_delegate_1->GetMessageText(); 376 string16 text_1 = infobar_delegate_1->GetMessageText();
376 EXPECT_NE(text_0, text_1); 377 EXPECT_NE(text_0, text_1);
377 378
378 // Cancel (block) this frame. 379 // Cancel (block) this frame.
379 infobar_delegate_1->Cancel(); 380 infobar_delegate_1->Cancel();
380 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_BLOCK); 381 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_BLOCK);
381 CheckPermissionMessageSent(1, false); 382 CheckPermissionMessageSent(1, false);
382 infobar_service()->RemoveInfoBar(infobar_delegate_1); 383 infobar_service()->RemoveInfoBar(infobar_1);
383 EXPECT_EQ(1U, closed_infobar_tracker_.size()); 384 EXPECT_EQ(1U, closed_infobar_tracker_.size());
384 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1)); 385 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1));
385 delete infobar_delegate_1;
386 EXPECT_EQ(0U, infobar_service()->infobar_count()); 386 EXPECT_EQ(0U, infobar_service()->infobar_count());
387 // Ensure the persisted permissions are ok. 387 // Ensure the persisted permissions are ok.
388 EXPECT_EQ(CONTENT_SETTING_ALLOW, 388 EXPECT_EQ(CONTENT_SETTING_ALLOW,
389 profile()->GetHostContentSettingsMap()->GetContentSetting( 389 profile()->GetHostContentSettingsMap()->GetContentSetting(
390 requesting_frame_0, requesting_frame_0, 390 requesting_frame_0, requesting_frame_0,
391 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); 391 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
392 392
393 EXPECT_EQ(CONTENT_SETTING_BLOCK, 393 EXPECT_EQ(CONTENT_SETTING_BLOCK,
394 profile()->GetHostContentSettingsMap()->GetContentSetting( 394 profile()->GetHostContentSettingsMap()->GetContentSetting(
395 requesting_frame_1, requesting_frame_0, 395 requesting_frame_1, requesting_frame_0,
396 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); 396 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
397 } 397 }
398 398
399 TEST_F(GeolocationPermissionContextTests, HashIsIgnored) { 399 TEST_F(GeolocationPermissionContextTests, HashIsIgnored) {
400 GURL url_a("http://www.example.com/geolocation#a"); 400 GURL url_a("http://www.example.com/geolocation#a");
401 GURL url_b("http://www.example.com/geolocation#b"); 401 GURL url_b("http://www.example.com/geolocation#b");
402 402
403 // Navigate to the first url and check permission is requested. 403 // Navigate to the first url and check permission is requested.
404 NavigateAndCommit(url_a); 404 NavigateAndCommit(url_a);
405 EXPECT_EQ(0U, infobar_service()->infobar_count()); 405 EXPECT_EQ(0U, infobar_service()->infobar_count());
406 RequestGeolocationPermission(RequestID(0), url_a); 406 RequestGeolocationPermission(RequestID(0), url_a);
407 ASSERT_EQ(1U, infobar_service()->infobar_count()); 407 ASSERT_EQ(1U, infobar_service()->infobar_count());
408 InfoBar* infobar = infobar_service()->infobar_at(0);
408 ConfirmInfoBarDelegate* infobar_delegate = 409 ConfirmInfoBarDelegate* infobar_delegate =
409 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 410 infobar->delegate()->AsConfirmInfoBarDelegate();
410 ASSERT_TRUE(infobar_delegate); 411 ASSERT_TRUE(infobar_delegate);
411 412
412 // Change the hash, we'll still be on the same page. 413 // Change the hash, we'll still be on the same page.
413 NavigateAndCommit(url_b); 414 NavigateAndCommit(url_b);
414 415
415 // Accept. 416 // Accept.
416 infobar_delegate->Accept(); 417 infobar_delegate->Accept();
417 CheckTabContentsState(url_a, CONTENT_SETTING_ALLOW); 418 CheckTabContentsState(url_a, CONTENT_SETTING_ALLOW);
418 CheckTabContentsState(url_b, CONTENT_SETTING_ALLOW); 419 CheckTabContentsState(url_b, CONTENT_SETTING_ALLOW);
419 CheckPermissionMessageSent(0, true); 420 CheckPermissionMessageSent(0, true);
420 421
421 // Cleanup. 422 // Cleanup.
422 infobar_service()->RemoveInfoBar(infobar_delegate); 423 infobar_service()->RemoveInfoBar(infobar);
423 EXPECT_EQ(1U, closed_infobar_tracker_.size()); 424 EXPECT_EQ(1U, closed_infobar_tracker_.size());
424 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate)); 425 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar));
425 closed_infobar_tracker_.Clear();
426 delete infobar_delegate;
427 } 426 }
428 427
429 TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) { 428 TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) {
430 GURL requesting_frame("file://example/geolocation.html"); 429 GURL requesting_frame("file://example/geolocation.html");
431 NavigateAndCommit(requesting_frame); 430 NavigateAndCommit(requesting_frame);
432 EXPECT_EQ(0U, infobar_service()->infobar_count()); 431 EXPECT_EQ(0U, infobar_service()->infobar_count());
433 RequestGeolocationPermission(RequestID(0), requesting_frame); 432 RequestGeolocationPermission(RequestID(0), requesting_frame);
434 EXPECT_EQ(1U, infobar_service()->infobar_count()); 433 EXPECT_EQ(1U, infobar_service()->infobar_count());
434 InfoBar* infobar = infobar_service()->infobar_at(0);
435 ConfirmInfoBarDelegate* infobar_delegate = 435 ConfirmInfoBarDelegate* infobar_delegate =
436 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 436 infobar->delegate()->AsConfirmInfoBarDelegate();
437 ASSERT_TRUE(infobar_delegate); 437 ASSERT_TRUE(infobar_delegate);
438 // Accept the frame. 438 // Accept the frame.
439 infobar_delegate->Accept(); 439 infobar_delegate->Accept();
440 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW); 440 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
441 CheckPermissionMessageSent(0, true); 441 CheckPermissionMessageSent(0, true);
442 infobar_service()->RemoveInfoBar(infobar_delegate); 442 infobar_service()->RemoveInfoBar(infobar);
443 delete infobar_delegate;
444 443
445 // Make sure the setting is not stored. 444 // Make sure the setting is not stored.
446 EXPECT_EQ(CONTENT_SETTING_ASK, 445 EXPECT_EQ(CONTENT_SETTING_ASK,
447 profile()->GetHostContentSettingsMap()->GetContentSetting( 446 profile()->GetHostContentSettingsMap()->GetContentSetting(
448 requesting_frame, 447 requesting_frame,
449 requesting_frame, 448 requesting_frame,
450 CONTENT_SETTINGS_TYPE_GEOLOCATION, 449 CONTENT_SETTINGS_TYPE_GEOLOCATION,
451 std::string())); 450 std::string()));
452 } 451 }
453 452
(...skipping 10 matching lines...) Expand all
464 requesting_frame_1, requesting_frame_0, 463 requesting_frame_1, requesting_frame_0,
465 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); 464 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
466 465
467 NavigateAndCommit(requesting_frame_0); 466 NavigateAndCommit(requesting_frame_0);
468 EXPECT_EQ(0U, infobar_service()->infobar_count()); 467 EXPECT_EQ(0U, infobar_service()->infobar_count());
469 // Request permission for two frames. 468 // Request permission for two frames.
470 RequestGeolocationPermission(RequestID(0), requesting_frame_0); 469 RequestGeolocationPermission(RequestID(0), requesting_frame_0);
471 RequestGeolocationPermission(RequestID(1), requesting_frame_1); 470 RequestGeolocationPermission(RequestID(1), requesting_frame_1);
472 ASSERT_EQ(1U, infobar_service()->infobar_count()); 471 ASSERT_EQ(1U, infobar_service()->infobar_count());
473 472
473 InfoBar* infobar_0 = infobar_service()->infobar_at(0);
474 ConfirmInfoBarDelegate* infobar_delegate_0 = 474 ConfirmInfoBarDelegate* infobar_delegate_0 =
475 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 475 infobar_0->delegate()->AsConfirmInfoBarDelegate();
476 ASSERT_TRUE(infobar_delegate_0); 476 ASSERT_TRUE(infobar_delegate_0);
477 string16 text_0 = infobar_delegate_0->GetMessageText(); 477 string16 text_0 = infobar_delegate_0->GetMessageText();
478 478
479 // Simulate the frame going away, ensure the infobar for this frame 479 // Simulate the frame going away, ensure the infobar for this frame
480 // is removed and the next pending infobar is created. 480 // is removed and the next pending infobar is created.
481 CancelGeolocationPermissionRequest(RequestID(0), requesting_frame_0); 481 CancelGeolocationPermissionRequest(RequestID(0), requesting_frame_0);
482 EXPECT_EQ(1U, closed_infobar_tracker_.size()); 482 EXPECT_EQ(1U, closed_infobar_tracker_.size());
483 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0)); 483 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
484 closed_infobar_tracker_.Clear(); 484 closed_infobar_tracker_.Clear();
485 delete infobar_delegate_0;
486 ASSERT_EQ(1U, infobar_service()->infobar_count()); 485 ASSERT_EQ(1U, infobar_service()->infobar_count());
487 486
487 InfoBar* infobar_1 = infobar_service()->infobar_at(0);
488 ConfirmInfoBarDelegate* infobar_delegate_1 = 488 ConfirmInfoBarDelegate* infobar_delegate_1 =
489 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 489 infobar_1->delegate()->AsConfirmInfoBarDelegate();
490 ASSERT_TRUE(infobar_delegate_1); 490 ASSERT_TRUE(infobar_delegate_1);
491 string16 text_1 = infobar_delegate_1->GetMessageText(); 491 string16 text_1 = infobar_delegate_1->GetMessageText();
492 EXPECT_NE(text_0, text_1); 492 EXPECT_NE(text_0, text_1);
493 493
494 // Allow this frame. 494 // Allow this frame.
495 infobar_delegate_1->Accept(); 495 infobar_delegate_1->Accept();
496 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW); 496 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW);
497 CheckPermissionMessageSent(1, true); 497 CheckPermissionMessageSent(1, true);
498 infobar_service()->RemoveInfoBar(infobar_delegate_1); 498 infobar_service()->RemoveInfoBar(infobar_1);
499 EXPECT_EQ(1U, closed_infobar_tracker_.size()); 499 EXPECT_EQ(1U, closed_infobar_tracker_.size());
500 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1)); 500 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1));
501 delete infobar_delegate_1;
502 EXPECT_EQ(0U, infobar_service()->infobar_count()); 501 EXPECT_EQ(0U, infobar_service()->infobar_count());
503 // Ensure the persisted permissions are ok. 502 // Ensure the persisted permissions are ok.
504 EXPECT_EQ(CONTENT_SETTING_ASK, 503 EXPECT_EQ(CONTENT_SETTING_ASK,
505 profile()->GetHostContentSettingsMap()->GetContentSetting( 504 profile()->GetHostContentSettingsMap()->GetContentSetting(
506 requesting_frame_0, requesting_frame_0, 505 requesting_frame_0, requesting_frame_0,
507 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); 506 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
508 507
509 EXPECT_EQ(CONTENT_SETTING_ALLOW, 508 EXPECT_EQ(CONTENT_SETTING_ALLOW,
510 profile()->GetHostContentSettingsMap()->GetContentSetting( 509 profile()->GetHostContentSettingsMap()->GetContentSetting(
511 requesting_frame_1, requesting_frame_0, 510 requesting_frame_1, requesting_frame_0,
(...skipping 20 matching lines...) Expand all
532 EXPECT_EQ(0U, infobar_service()->infobar_count()); 531 EXPECT_EQ(0U, infobar_service()->infobar_count());
533 RequestGeolocationPermission(RequestID(0), url_a); 532 RequestGeolocationPermission(RequestID(0), url_a);
534 ASSERT_EQ(1U, infobar_service()->infobar_count()); 533 ASSERT_EQ(1U, infobar_service()->infobar_count());
535 534
536 RequestGeolocationPermission(RequestIDForTab(0, 0), url_b); 535 RequestGeolocationPermission(RequestIDForTab(0, 0), url_b);
537 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); 536 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
538 537
539 RequestGeolocationPermission(RequestIDForTab(1, 0), url_a); 538 RequestGeolocationPermission(RequestIDForTab(1, 0), url_a);
540 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count()); 539 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
541 540
542 ConfirmInfoBarDelegate* removed_infobar = 541 InfoBar* removed_infobar = infobar_service_for_tab(1)->infobar_at(0);
543 infobar_service_for_tab(1)->infobar_at(0)->AsConfirmInfoBarDelegate();
544 542
545 // Accept the first tab. 543 // Accept the first tab.
544 InfoBar* infobar_0 = infobar_service()->infobar_at(0);
546 ConfirmInfoBarDelegate* infobar_delegate_0 = 545 ConfirmInfoBarDelegate* infobar_delegate_0 =
547 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate(); 546 infobar_0->delegate()->AsConfirmInfoBarDelegate();
548 ASSERT_TRUE(infobar_delegate_0); 547 ASSERT_TRUE(infobar_delegate_0);
549 infobar_delegate_0->Accept(); 548 infobar_delegate_0->Accept();
550 CheckPermissionMessageSent(0, true); 549 CheckPermissionMessageSent(0, true);
551 infobar_service()->RemoveInfoBar(infobar_delegate_0); 550 infobar_service()->RemoveInfoBar(infobar_0);
552 EXPECT_EQ(2U, closed_infobar_tracker_.size()); 551 EXPECT_EQ(2U, closed_infobar_tracker_.size());
553 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0)); 552 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
554 delete infobar_delegate_0;
555 // Now the infobar for the tab with the same origin should have gone. 553 // Now the infobar for the tab with the same origin should have gone.
556 EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count()); 554 EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count());
557 CheckPermissionMessageSentForTab(1, 0, true); 555 CheckPermissionMessageSentForTab(1, 0, true);
558 EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar)); 556 EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
559 closed_infobar_tracker_.Clear(); 557 closed_infobar_tracker_.Clear();
560 // Destroy the infobar that has just been removed.
561 delete removed_infobar;
562 558
563 // But the other tab should still have the info bar... 559 // But the other tab should still have the info bar...
564 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); 560 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
561 InfoBar* infobar_1 = infobar_service_for_tab(0)->infobar_at(0);
565 ConfirmInfoBarDelegate* infobar_delegate_1 = 562 ConfirmInfoBarDelegate* infobar_delegate_1 =
566 infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate(); 563 infobar_1->delegate()->AsConfirmInfoBarDelegate();
564 ASSERT_TRUE(infobar_delegate_1);
567 infobar_delegate_1->Cancel(); 565 infobar_delegate_1->Cancel();
568 infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_1); 566 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1);
569 EXPECT_EQ(1U, closed_infobar_tracker_.size()); 567 EXPECT_EQ(1U, closed_infobar_tracker_.size());
570 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1)); 568 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1));
571 delete infobar_delegate_1;
572 } 569 }
573 570
574 TEST_F(GeolocationPermissionContextTests, QueuedOriginMultipleTabs) { 571 TEST_F(GeolocationPermissionContextTests, QueuedOriginMultipleTabs) {
575 GURL url_a("http://www.example.com/geolocation"); 572 GURL url_a("http://www.example.com/geolocation");
576 GURL url_b("http://www.example-2.com/geolocation"); 573 GURL url_b("http://www.example-2.com/geolocation");
577 NavigateAndCommit(url_a); 574 NavigateAndCommit(url_a);
578 AddNewTab(url_a); 575 AddNewTab(url_a);
579 576
580 EXPECT_EQ(0U, infobar_service()->infobar_count()); 577 EXPECT_EQ(0U, infobar_service()->infobar_count());
581 RequestGeolocationPermission(RequestID(0), url_a); 578 RequestGeolocationPermission(RequestID(0), url_a);
582 ASSERT_EQ(1U, infobar_service()->infobar_count()); 579 ASSERT_EQ(1U, infobar_service()->infobar_count());
583 580
584 RequestGeolocationPermission(RequestIDForTab(0, 0), url_a); 581 RequestGeolocationPermission(RequestIDForTab(0, 0), url_a);
585 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); 582 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
586 583
587 RequestGeolocationPermission(RequestIDForTab(0, 1), url_b); 584 RequestGeolocationPermission(RequestIDForTab(0, 1), url_b);
588 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); 585 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
589 586
590 ConfirmInfoBarDelegate* removed_infobar = 587 InfoBar* removed_infobar = infobar_service()->infobar_at(0);
591 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
592 588
593 // Accept the second tab. 589 // Accept the second tab.
590 InfoBar* infobar_0 = infobar_service_for_tab(0)->infobar_at(0);
594 ConfirmInfoBarDelegate* infobar_delegate_0 = 591 ConfirmInfoBarDelegate* infobar_delegate_0 =
595 infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate(); 592 infobar_0->delegate()->AsConfirmInfoBarDelegate();
596 ASSERT_TRUE(infobar_delegate_0); 593 ASSERT_TRUE(infobar_delegate_0);
597 infobar_delegate_0->Accept(); 594 infobar_delegate_0->Accept();
598 CheckPermissionMessageSentForTab(0, 0, true); 595 CheckPermissionMessageSentForTab(0, 0, true);
599 infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_0); 596 infobar_service_for_tab(0)->RemoveInfoBar(infobar_0);
600 EXPECT_EQ(2U, closed_infobar_tracker_.size()); 597 EXPECT_EQ(2U, closed_infobar_tracker_.size());
601 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0)); 598 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
602 delete infobar_delegate_0;
603 // Now the infobar for the tab with the same origin should have gone. 599 // Now the infobar for the tab with the same origin should have gone.
604 EXPECT_EQ(0U, infobar_service()->infobar_count()); 600 EXPECT_EQ(0U, infobar_service()->infobar_count());
605 CheckPermissionMessageSent(0, true); 601 CheckPermissionMessageSent(0, true);
606 EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar)); 602 EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
607 closed_infobar_tracker_.Clear(); 603 closed_infobar_tracker_.Clear();
608 delete removed_infobar;
609 604
610 // And we should have the queued infobar displayed now. 605 // And we should have the queued infobar displayed now.
611 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); 606 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
612 607
613 // Accept the second infobar. 608 // Accept the second infobar.
609 InfoBar* infobar_1 = infobar_service_for_tab(0)->infobar_at(0);
614 ConfirmInfoBarDelegate* infobar_delegate_1 = 610 ConfirmInfoBarDelegate* infobar_delegate_1 =
615 infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate(); 611 infobar_1->delegate()->AsConfirmInfoBarDelegate();
616 ASSERT_TRUE(infobar_delegate_1); 612 ASSERT_TRUE(infobar_delegate_1);
617 infobar_delegate_1->Accept(); 613 infobar_delegate_1->Accept();
618 CheckPermissionMessageSentForTab(0, 1, true); 614 CheckPermissionMessageSentForTab(0, 1, true);
619 infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_1); 615 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1);
620 EXPECT_EQ(1U, closed_infobar_tracker_.size()); 616 EXPECT_EQ(1U, closed_infobar_tracker_.size());
621 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1)); 617 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1));
622 delete infobar_delegate_1;
623 } 618 }
624 619
625 TEST_F(GeolocationPermissionContextTests, TabDestroyed) { 620 TEST_F(GeolocationPermissionContextTests, TabDestroyed) {
626 GURL requesting_frame_0("http://www.example.com/geolocation"); 621 GURL requesting_frame_0("http://www.example.com/geolocation");
627 GURL requesting_frame_1("http://www.example-2.com/geolocation"); 622 GURL requesting_frame_1("http://www.example-2.com/geolocation");
628 EXPECT_EQ(CONTENT_SETTING_ASK, 623 EXPECT_EQ(CONTENT_SETTING_ASK,
629 profile()->GetHostContentSettingsMap()->GetContentSetting( 624 profile()->GetHostContentSettingsMap()->GetContentSetting(
630 requesting_frame_0, requesting_frame_0, 625 requesting_frame_0, requesting_frame_0,
631 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); 626 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
632 627
633 EXPECT_EQ(CONTENT_SETTING_ASK, 628 EXPECT_EQ(CONTENT_SETTING_ASK,
634 profile()->GetHostContentSettingsMap()->GetContentSetting( 629 profile()->GetHostContentSettingsMap()->GetContentSetting(
635 requesting_frame_1, requesting_frame_0, 630 requesting_frame_1, requesting_frame_0,
636 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); 631 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
637 632
638 NavigateAndCommit(requesting_frame_0); 633 NavigateAndCommit(requesting_frame_0);
639 EXPECT_EQ(0U, infobar_service()->infobar_count()); 634 EXPECT_EQ(0U, infobar_service()->infobar_count());
640 // Request permission for two frames. 635 // Request permission for two frames.
641 RequestGeolocationPermission(RequestID(0), requesting_frame_0); 636 RequestGeolocationPermission(RequestID(0), requesting_frame_0);
642 RequestGeolocationPermission(RequestID(1), requesting_frame_1); 637 RequestGeolocationPermission(RequestID(1), requesting_frame_1);
643 // Ensure only one infobar is created. 638 // Ensure only one infobar is created.
644 ASSERT_EQ(1U, infobar_service()->infobar_count()); 639 ASSERT_EQ(1U, infobar_service()->infobar_count());
645 InfoBarDelegate* infobar = infobar_service()->infobar_at(0); 640 InfoBar* infobar = infobar_service()->infobar_at(0);
646 641
647 // Delete the tab contents. 642 // Delete the tab contents.
648 DeleteContents(); 643 DeleteContents();
649 delete infobar;
650 644
651 // During contents destruction, the infobar will have been closed, and the 645 // During contents destruction, the infobar will have been closed, and the
652 // pending request should have been cleared without an infobar being created. 646 // pending request should have been cleared without an infobar being created.
653 ASSERT_EQ(1U, closed_infobar_tracker_.size()); 647 ASSERT_EQ(1U, closed_infobar_tracker_.size());
654 ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar)); 648 ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar));
655 } 649 }
656 650
657 TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) { 651 TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) {
658 GURL requesting_frame_0("http://www.example.com/geolocation"); 652 GURL requesting_frame_0("http://www.example.com/geolocation");
659 GURL requesting_frame_1("http://www.example-2.com/geolocation"); 653 GURL requesting_frame_1("http://www.example-2.com/geolocation");
660 NavigateAndCommit(requesting_frame_0); 654 NavigateAndCommit(requesting_frame_0);
661 NavigateAndCommit(requesting_frame_1); 655 NavigateAndCommit(requesting_frame_1);
662 EXPECT_EQ(0U, infobar_service()->infobar_count()); 656 EXPECT_EQ(0U, infobar_service()->infobar_count());
663 // Go back: navigate to a pending entry before requesting geolocation 657 // Go back: navigate to a pending entry before requesting geolocation
664 // permission. 658 // permission.
665 web_contents()->GetController().GoBack(); 659 web_contents()->GetController().GoBack();
666 // Request permission for the committed frame (not the pending one). 660 // Request permission for the committed frame (not the pending one).
667 RequestGeolocationPermission(RequestID(0), requesting_frame_1); 661 RequestGeolocationPermission(RequestID(0), requesting_frame_1);
668 // Ensure the infobar is created. 662 // Ensure the infobar is created.
669 ASSERT_EQ(1U, infobar_service()->infobar_count()); 663 ASSERT_EQ(1U, infobar_service()->infobar_count());
670 InfoBarDelegate* infobar_delegate = infobar_service()->infobar_at(0); 664 InfoBarDelegate* infobar_delegate =
665 infobar_service()->infobar_at(0)->delegate();
671 ASSERT_TRUE(infobar_delegate); 666 ASSERT_TRUE(infobar_delegate);
672 // Ensure the infobar wouldn't expire for a navigation to the committed entry. 667 // Ensure the infobar wouldn't expire for a navigation to the committed entry.
673 content::LoadCommittedDetails details; 668 content::LoadCommittedDetails details;
674 details.entry = web_contents()->GetController().GetLastCommittedEntry(); 669 details.entry = web_contents()->GetController().GetLastCommittedEntry();
675 EXPECT_FALSE(infobar_delegate->ShouldExpire(details)); 670 EXPECT_FALSE(infobar_delegate->ShouldExpire(details));
676 // Ensure the infobar will expire when we commit the pending navigation. 671 // Ensure the infobar will expire when we commit the pending navigation.
677 details.entry = web_contents()->GetController().GetActiveEntry(); 672 details.entry = web_contents()->GetController().GetActiveEntry();
678 EXPECT_TRUE(infobar_delegate->ShouldExpire(details)); 673 EXPECT_TRUE(infobar_delegate->ShouldExpire(details));
679 674
680 // Delete the tab contents. 675 // Delete the tab contents.
681 DeleteContents(); 676 DeleteContents();
682 delete infobar_delegate;
683 } 677 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/theme_installed_infobar_delegate.cc ('k') | chrome/browser/geolocation/geolocation_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698