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

Side by Side Diff: chrome/browser/favicon/favicon_handler_unittest.cc

Issue 330603004: Rename FaviconBitmapXxx to FaviconRawBitmapXxx (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix android Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « chrome/browser/favicon/favicon_handler.cc ('k') | chrome/browser/favicon/favicon_service.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/memory/scoped_ptr.h" 5 #include "base/memory/scoped_ptr.h"
6 #include "chrome/browser/favicon/favicon_handler.h" 6 #include "chrome/browser/favicon/favicon_handler.h"
7 #include "chrome/browser/favicon/favicon_service.h" 7 #include "chrome/browser/favicon/favicon_service.h"
8 #include "chrome/browser/favicon/favicon_service_factory.h" 8 #include "chrome/browser/favicon/favicon_service_factory.h"
9 #include "chrome/browser/history/history_service_factory.h" 9 #include "chrome/browser/history/history_service_factory.h"
10 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/profiles/profile.h"
(...skipping 24 matching lines...) Expand all
35 } 35 }
36 } 36 }
37 37
38 // Fill the given data buffer with valid png data. 38 // Fill the given data buffer with valid png data.
39 void FillBitmap(int w, int h, std::vector<unsigned char>* output) { 39 void FillBitmap(int w, int h, std::vector<unsigned char>* output) {
40 SkBitmap bitmap; 40 SkBitmap bitmap;
41 FillDataToBitmap(w, h, &bitmap); 41 FillDataToBitmap(w, h, &bitmap);
42 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, output); 42 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, output);
43 } 43 }
44 44
45 void SetFaviconBitmapResult( 45 void SetFaviconRawBitmapResult(
46 const GURL& icon_url, 46 const GURL& icon_url,
47 favicon_base::IconType icon_type, 47 favicon_base::IconType icon_type,
48 bool expired, 48 bool expired,
49 std::vector<favicon_base::FaviconBitmapResult>* favicon_bitmap_results) { 49 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
50 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); 50 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes());
51 FillBitmap(gfx::kFaviconSize, gfx::kFaviconSize, &data->data()); 51 FillBitmap(gfx::kFaviconSize, gfx::kFaviconSize, &data->data());
52 favicon_base::FaviconBitmapResult bitmap_result; 52 favicon_base::FaviconRawBitmapResult bitmap_result;
53 bitmap_result.expired = expired; 53 bitmap_result.expired = expired;
54 bitmap_result.bitmap_data = data; 54 bitmap_result.bitmap_data = data;
55 // Use a pixel size other than (0,0) as (0,0) has a special meaning. 55 // Use a pixel size other than (0,0) as (0,0) has a special meaning.
56 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); 56 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
57 bitmap_result.icon_type = icon_type; 57 bitmap_result.icon_type = icon_type;
58 bitmap_result.icon_url = icon_url; 58 bitmap_result.icon_url = icon_url;
59 59
60 favicon_bitmap_results->push_back(bitmap_result); 60 favicon_bitmap_results->push_back(bitmap_result);
61 } 61 }
62 62
63 void SetFaviconBitmapResult( 63 void SetFaviconRawBitmapResult(
64 const GURL& icon_url, 64 const GURL& icon_url,
65 std::vector<favicon_base::FaviconBitmapResult>* favicon_bitmap_results) { 65 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) {
66 SetFaviconBitmapResult(icon_url, 66 SetFaviconRawBitmapResult(icon_url,
67 favicon_base::FAVICON, 67 favicon_base::FAVICON,
68 false /* expired */, 68 false /* expired */,
69 favicon_bitmap_results); 69 favicon_bitmap_results);
70 } 70 }
71 71
72 // This class is used to save the download request for verifying with test case. 72 // This class is used to save the download request for verifying with test case.
73 // It also will be used to invoke the onDidDownload callback. 73 // It also will be used to invoke the onDidDownload callback.
74 class DownloadHandler { 74 class DownloadHandler {
75 public: 75 public:
76 explicit DownloadHandler(TestFaviconHandler* favicon_helper) 76 explicit DownloadHandler(TestFaviconHandler* favicon_helper)
77 : favicon_helper_(favicon_helper), 77 : favicon_helper_(favicon_helper),
78 failed_(false) { 78 failed_(false) {
79 } 79 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 156 }
157 157
158 virtual ~HistoryRequestHandler() {} 158 virtual ~HistoryRequestHandler() {}
159 void InvokeCallback(); 159 void InvokeCallback();
160 160
161 const GURL page_url_; 161 const GURL page_url_;
162 const GURL icon_url_; 162 const GURL icon_url_;
163 const int icon_type_; 163 const int icon_type_;
164 const std::vector<unsigned char> bitmap_data_; 164 const std::vector<unsigned char> bitmap_data_;
165 const gfx::Size size_; 165 const gfx::Size size_;
166 std::vector<favicon_base::FaviconBitmapResult> history_results_; 166 std::vector<favicon_base::FaviconRawBitmapResult> history_results_;
167 favicon_base::FaviconResultsCallback callback_; 167 favicon_base::FaviconResultsCallback callback_;
168 168
169 private: 169 private:
170 DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler); 170 DISALLOW_COPY_AND_ASSIGN(HistoryRequestHandler);
171 }; 171 };
172 172
173 } // namespace 173 } // namespace
174 174
175 class TestFaviconClient : public FaviconClient { 175 class TestFaviconClient : public FaviconClient {
176 public: 176 public:
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 page_url, &client, &driver, FaviconHandler::FAVICON, false); 486 page_url, &client, &driver, FaviconHandler::FAVICON, false);
487 487
488 helper.FetchFavicon(page_url); 488 helper.FetchFavicon(page_url);
489 HistoryRequestHandler* history_handler = helper.history_handler(); 489 HistoryRequestHandler* history_handler = helper.history_handler();
490 // Ensure the data given to history is correct. 490 // Ensure the data given to history is correct.
491 ASSERT_TRUE(history_handler); 491 ASSERT_TRUE(history_handler);
492 EXPECT_EQ(page_url, history_handler->page_url_); 492 EXPECT_EQ(page_url, history_handler->page_url_);
493 EXPECT_EQ(GURL(), history_handler->icon_url_); 493 EXPECT_EQ(GURL(), history_handler->icon_url_);
494 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); 494 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
495 495
496 SetFaviconBitmapResult(icon_url, &history_handler->history_results_); 496 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
497 497
498 // Send history response. 498 // Send history response.
499 history_handler->InvokeCallback(); 499 history_handler->InvokeCallback();
500 // Verify FaviconHandler status 500 // Verify FaviconHandler status
501 EXPECT_TRUE(driver.GetActiveFaviconValidity()); 501 EXPECT_TRUE(driver.GetActiveFaviconValidity());
502 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); 502 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
503 503
504 // Simulates update favicon url. 504 // Simulates update favicon url.
505 std::vector<FaviconURL> urls; 505 std::vector<FaviconURL> urls;
506 urls.push_back( 506 urls.push_back(
(...skipping 21 matching lines...) Expand all
528 528
529 helper.FetchFavicon(page_url); 529 helper.FetchFavicon(page_url);
530 HistoryRequestHandler* history_handler = helper.history_handler(); 530 HistoryRequestHandler* history_handler = helper.history_handler();
531 // Ensure the data given to history is correct. 531 // Ensure the data given to history is correct.
532 ASSERT_TRUE(history_handler); 532 ASSERT_TRUE(history_handler);
533 EXPECT_EQ(page_url, history_handler->page_url_); 533 EXPECT_EQ(page_url, history_handler->page_url_);
534 EXPECT_EQ(GURL(), history_handler->icon_url_); 534 EXPECT_EQ(GURL(), history_handler->icon_url_);
535 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); 535 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
536 536
537 // Set icon data expired 537 // Set icon data expired
538 SetFaviconBitmapResult(icon_url, 538 SetFaviconRawBitmapResult(icon_url,
539 favicon_base::FAVICON, 539 favicon_base::FAVICON,
540 true /* expired */, 540 true /* expired */,
541 &history_handler->history_results_); 541 &history_handler->history_results_);
542 // Send history response. 542 // Send history response.
543 history_handler->InvokeCallback(); 543 history_handler->InvokeCallback();
544 // Verify FaviconHandler status 544 // Verify FaviconHandler status
545 EXPECT_TRUE(driver.GetActiveFaviconValidity()); 545 EXPECT_TRUE(driver.GetActiveFaviconValidity());
546 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); 546 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
547 547
548 // Simulates update favicon url. 548 // Simulates update favicon url.
549 std::vector<FaviconURL> urls; 549 std::vector<FaviconURL> urls;
550 urls.push_back( 550 urls.push_back(
551 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>())); 551 FaviconURL(icon_url, favicon_base::FAVICON, std::vector<gfx::Size>()));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
597 597
598 helper.FetchFavicon(page_url); 598 helper.FetchFavicon(page_url);
599 HistoryRequestHandler* history_handler = helper.history_handler(); 599 HistoryRequestHandler* history_handler = helper.history_handler();
600 // Ensure the data given to history is correct. 600 // Ensure the data given to history is correct.
601 ASSERT_TRUE(history_handler); 601 ASSERT_TRUE(history_handler);
602 EXPECT_EQ(page_url, history_handler->page_url_); 602 EXPECT_EQ(page_url, history_handler->page_url_);
603 EXPECT_EQ(GURL(), history_handler->icon_url_); 603 EXPECT_EQ(GURL(), history_handler->icon_url_);
604 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); 604 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
605 605
606 // Set valid icon data. 606 // Set valid icon data.
607 SetFaviconBitmapResult(icon_url, &history_handler->history_results_); 607 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
608 608
609 // Send history response. 609 // Send history response.
610 history_handler->InvokeCallback(); 610 history_handler->InvokeCallback();
611 // Verify FaviconHandler status. 611 // Verify FaviconHandler status.
612 EXPECT_TRUE(driver.GetActiveFaviconValidity()); 612 EXPECT_TRUE(driver.GetActiveFaviconValidity());
613 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); 613 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
614 614
615 // Reset the history_handler to verify whether new icon is requested from 615 // Reset the history_handler to verify whether new icon is requested from
616 // history. 616 // history.
617 helper.set_history_handler(NULL); 617 helper.set_history_handler(NULL);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 678
679 helper.FetchFavicon(page_url); 679 helper.FetchFavicon(page_url);
680 HistoryRequestHandler* history_handler = helper.history_handler(); 680 HistoryRequestHandler* history_handler = helper.history_handler();
681 // Ensure the data given to history is correct. 681 // Ensure the data given to history is correct.
682 ASSERT_TRUE(history_handler); 682 ASSERT_TRUE(history_handler);
683 EXPECT_EQ(page_url, history_handler->page_url_); 683 EXPECT_EQ(page_url, history_handler->page_url_);
684 EXPECT_EQ(GURL(), history_handler->icon_url_); 684 EXPECT_EQ(GURL(), history_handler->icon_url_);
685 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); 685 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
686 686
687 // Set non empty but invalid data. 687 // Set non empty but invalid data.
688 favicon_base::FaviconBitmapResult bitmap_result; 688 favicon_base::FaviconRawBitmapResult bitmap_result;
689 bitmap_result.expired = false; 689 bitmap_result.expired = false;
690 // Empty bitmap data is invalid. 690 // Empty bitmap data is invalid.
691 bitmap_result.bitmap_data = new base::RefCountedBytes(); 691 bitmap_result.bitmap_data = new base::RefCountedBytes();
692 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); 692 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
693 bitmap_result.icon_type = favicon_base::FAVICON; 693 bitmap_result.icon_type = favicon_base::FAVICON;
694 bitmap_result.icon_url = icon_url; 694 bitmap_result.icon_url = icon_url;
695 history_handler->history_results_.clear(); 695 history_handler->history_results_.clear();
696 history_handler->history_results_.push_back(bitmap_result); 696 history_handler->history_results_.push_back(bitmap_result);
697 697
698 // Send history response. 698 // Send history response.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 page_url, &client, &driver, FaviconHandler::FAVICON, false); 749 page_url, &client, &driver, FaviconHandler::FAVICON, false);
750 750
751 helper.FetchFavicon(page_url); 751 helper.FetchFavicon(page_url);
752 HistoryRequestHandler* history_handler = helper.history_handler(); 752 HistoryRequestHandler* history_handler = helper.history_handler();
753 // Ensure the data given to history is correct. 753 // Ensure the data given to history is correct.
754 ASSERT_TRUE(history_handler); 754 ASSERT_TRUE(history_handler);
755 EXPECT_EQ(page_url, history_handler->page_url_); 755 EXPECT_EQ(page_url, history_handler->page_url_);
756 EXPECT_EQ(GURL(), history_handler->icon_url_); 756 EXPECT_EQ(GURL(), history_handler->icon_url_);
757 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); 757 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
758 758
759 SetFaviconBitmapResult(icon_url, &history_handler->history_results_); 759 SetFaviconRawBitmapResult(icon_url, &history_handler->history_results_);
760 760
761 // Send history response. 761 // Send history response.
762 history_handler->InvokeCallback(); 762 history_handler->InvokeCallback();
763 // Verify FaviconHandler status. 763 // Verify FaviconHandler status.
764 EXPECT_TRUE(driver.GetActiveFaviconValidity()); 764 EXPECT_TRUE(driver.GetActiveFaviconValidity());
765 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL()); 765 EXPECT_EQ(icon_url, driver.GetActiveFaviconURL());
766 766
767 // Reset the history_handler to verify whether new icon is requested from 767 // Reset the history_handler to verify whether new icon is requested from
768 // history. 768 // history.
769 helper.set_history_handler(NULL); 769 helper.set_history_handler(NULL);
(...skipping 11 matching lines...) Expand all
781 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type); 781 ASSERT_EQ(favicon_base::FAVICON, helper.current_candidate()->icon_type);
782 782
783 // Favicon should be requested from history. 783 // Favicon should be requested from history.
784 history_handler = helper.history_handler(); 784 history_handler = helper.history_handler();
785 ASSERT_TRUE(history_handler); 785 ASSERT_TRUE(history_handler);
786 EXPECT_EQ(new_icon_url, history_handler->icon_url_); 786 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
787 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_); 787 EXPECT_EQ(favicon_base::FAVICON, history_handler->icon_type_);
788 EXPECT_EQ(page_url, history_handler->page_url_); 788 EXPECT_EQ(page_url, history_handler->page_url_);
789 789
790 // Simulate find icon. 790 // Simulate find icon.
791 SetFaviconBitmapResult(new_icon_url, &history_handler->history_results_); 791 SetFaviconRawBitmapResult(new_icon_url, &history_handler->history_results_);
792 history_handler->InvokeCallback(); 792 history_handler->InvokeCallback();
793 793
794 // Shouldn't request download favicon 794 // Shouldn't request download favicon
795 EXPECT_FALSE(helper.download_handler()->HasDownload()); 795 EXPECT_FALSE(helper.download_handler()->HasDownload());
796 796
797 // Verify the favicon status. 797 // Verify the favicon status.
798 EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL()); 798 EXPECT_EQ(new_icon_url, driver.GetActiveFaviconURL());
799 EXPECT_TRUE(driver.GetActiveFaviconValidity()); 799 EXPECT_TRUE(driver.GetActiveFaviconValidity());
800 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty()); 800 EXPECT_FALSE(driver.GetActiveFaviconImage().IsEmpty());
801 } 801 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 history_handler = helper.history_handler(); 884 history_handler = helper.history_handler();
885 ASSERT_TRUE(history_handler); 885 ASSERT_TRUE(history_handler);
886 EXPECT_EQ(new_icon_url, history_handler->icon_url_); 886 EXPECT_EQ(new_icon_url, history_handler->icon_url_);
887 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_); 887 EXPECT_EQ(favicon_base::TOUCH_ICON, history_handler->icon_type_);
888 EXPECT_EQ(page_url, history_handler->page_url_); 888 EXPECT_EQ(page_url, history_handler->page_url_);
889 889
890 // Reset download handler 890 // Reset download handler
891 download_handler->Reset(); 891 download_handler->Reset();
892 892
893 // Simulates getting a expired icon from history. 893 // Simulates getting a expired icon from history.
894 SetFaviconBitmapResult(new_icon_url, 894 SetFaviconRawBitmapResult(new_icon_url,
895 favicon_base::TOUCH_ICON, 895 favicon_base::TOUCH_ICON,
896 true /* expired */, 896 true /* expired */,
897 &history_handler->history_results_); 897 &history_handler->history_results_);
898 history_handler->InvokeCallback(); 898 history_handler->InvokeCallback();
899 899
900 // Verify the download request. 900 // Verify the download request.
901 EXPECT_TRUE(helper.download_handler()->HasDownload()); 901 EXPECT_TRUE(helper.download_handler()->HasDownload());
902 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl()); 902 EXPECT_EQ(new_icon_url, download_handler->GetImageUrl());
903 903
904 helper.set_history_handler(NULL); 904 helper.set_history_handler(NULL);
905 905
906 // Simulates icon being downloaded. 906 // Simulates icon being downloaded.
907 download_handler->InvokeCallback(); 907 download_handler->InvokeCallback();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 download_handler->InvokeCallback(); 1012 download_handler->InvokeCallback();
1013 // The downloaded icon should be thrown away as there is favicon update. 1013 // The downloaded icon should be thrown away as there is favicon update.
1014 EXPECT_FALSE(helper.history_handler()); 1014 EXPECT_FALSE(helper.history_handler());
1015 1015
1016 download_handler->Reset(); 1016 download_handler->Reset();
1017 1017
1018 // Simulates getting the icon from history. 1018 // Simulates getting the icon from history.
1019 scoped_ptr<HistoryRequestHandler> handler; 1019 scoped_ptr<HistoryRequestHandler> handler;
1020 handler.reset(new HistoryRequestHandler( 1020 handler.reset(new HistoryRequestHandler(
1021 page_url, latest_icon_url, favicon_base::TOUCH_ICON, callback)); 1021 page_url, latest_icon_url, favicon_base::TOUCH_ICON, callback));
1022 SetFaviconBitmapResult(latest_icon_url, 1022 SetFaviconRawBitmapResult(latest_icon_url,
1023 favicon_base::TOUCH_ICON, 1023 favicon_base::TOUCH_ICON,
1024 false /* expired */, 1024 false /* expired */,
1025 &handler->history_results_); 1025 &handler->history_results_);
1026 handler->InvokeCallback(); 1026 handler->InvokeCallback();
1027 1027
1028 // No download request. 1028 // No download request.
1029 EXPECT_FALSE(download_handler->HasDownload()); 1029 EXPECT_FALSE(download_handler->HasDownload());
1030 } 1030 }
1031 1031
1032 #if !defined(OS_ANDROID) 1032 #if !defined(OS_ANDROID)
1033 1033
1034 // Test the favicon which is selected when the web page provides several 1034 // Test the favicon which is selected when the web page provides several
1035 // favicons and none of the favicons are cached in history. 1035 // favicons and none of the favicons are cached in history.
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0); 1481 download_id = favicon_tab_helper->StartDownload(missing_icon_url, 0);
1482 EXPECT_NE(0, download_id); 1482 EXPECT_NE(0, download_id);
1483 // Report download success with HTTP 200 status. 1483 // Report download success with HTTP 200 status.
1484 favicon_tab_helper->DidDownloadFavicon(download_id, 200, missing_icon_url, 1484 favicon_tab_helper->DidDownloadFavicon(download_id, 200, missing_icon_url,
1485 empty_icons, empty_icon_sizes); 1485 empty_icons, empty_icon_sizes);
1486 // Icon is not marked as UnableToDownload as HTTP status is not 404. 1486 // Icon is not marked as UnableToDownload as HTTP status is not 404.
1487 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url)); 1487 EXPECT_FALSE(favicon_service->WasUnableToDownloadFavicon(missing_icon_url));
1488 } 1488 }
1489 1489
1490 } // namespace. 1490 } // namespace.
OLDNEW
« no previous file with comments | « chrome/browser/favicon/favicon_handler.cc ('k') | chrome/browser/favicon/favicon_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698