OLD | NEW |
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 "components/favicon/core/favicon_handler.h" | 5 #include "components/favicon/core/favicon_handler.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <memory> | 10 #include <memory> |
11 #include <set> | 11 #include <set> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
17 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
18 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 19 #include "base/test/histogram_tester.h" |
19 #include "components/favicon/core/favicon_driver.h" | 20 #include "components/favicon/core/favicon_driver.h" |
20 #include "components/favicon/core/test/mock_favicon_service.h" | 21 #include "components/favicon/core/test/mock_favicon_service.h" |
21 #include "testing/gmock/include/gmock/gmock.h" | 22 #include "testing/gmock/include/gmock/gmock.h" |
22 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
23 #include "third_party/skia/include/core/SkBitmap.h" | 24 #include "third_party/skia/include/core/SkBitmap.h" |
24 #include "ui/base/layout.h" | 25 #include "ui/base/layout.h" |
25 #include "ui/gfx/codec/png_codec.h" | 26 #include "ui/gfx/codec/png_codec.h" |
26 #include "ui/gfx/favicon_size.h" | 27 #include "ui/gfx/favicon_size.h" |
27 #include "ui/gfx/image/image.h" | 28 #include "ui/gfx/image/image.h" |
28 | 29 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 std::vector<unsigned char> FillBitmapWithEdgeSize(int size) { | 72 std::vector<unsigned char> FillBitmapWithEdgeSize(int size) { |
72 SkBitmap bitmap = CreateBitmapWithEdgeSize(size); | 73 SkBitmap bitmap = CreateBitmapWithEdgeSize(size); |
73 std::vector<unsigned char> output; | 74 std::vector<unsigned char> output; |
74 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &output); | 75 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &output); |
75 return output; | 76 return output; |
76 } | 77 } |
77 | 78 |
78 std::vector<FaviconRawBitmapResult> CreateRawBitmapResult( | 79 std::vector<FaviconRawBitmapResult> CreateRawBitmapResult( |
79 const GURL& icon_url, | 80 const GURL& icon_url, |
80 favicon_base::IconType icon_type = FAVICON, | 81 favicon_base::IconType icon_type = FAVICON, |
81 bool expired = false) { | 82 bool expired = false, |
| 83 int edge_size = gfx::kFaviconSize) { |
82 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); | 84 scoped_refptr<base::RefCountedBytes> data(new base::RefCountedBytes()); |
83 data->data() = FillBitmapWithEdgeSize(gfx::kFaviconSize); | 85 data->data() = FillBitmapWithEdgeSize(edge_size); |
84 FaviconRawBitmapResult bitmap_result; | 86 FaviconRawBitmapResult bitmap_result; |
85 bitmap_result.expired = expired; | 87 bitmap_result.expired = expired; |
86 bitmap_result.bitmap_data = data; | 88 bitmap_result.bitmap_data = data; |
87 // Use a pixel size other than (0,0) as (0,0) has a special meaning. | 89 // Use a pixel size other than (0,0) as (0,0) has a special meaning. |
88 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); | 90 bitmap_result.pixel_size = gfx::Size(edge_size, edge_size); |
89 bitmap_result.icon_type = icon_type; | 91 bitmap_result.icon_type = icon_type; |
90 bitmap_result.icon_url = icon_url; | 92 bitmap_result.icon_url = icon_url; |
91 return {bitmap_result}; | 93 return {bitmap_result}; |
92 } | 94 } |
93 | 95 |
94 // Fake that implements the calls to FaviconHalder::Delegate's DownloadImage(), | 96 // Fake that implements the calls to FaviconHandler::Delegate's DownloadImage(), |
95 // delegated to this class through MockDelegate. | 97 // delegated to this class through MockDelegate. |
96 class FakeImageDownloader { | 98 class FakeImageDownloader { |
97 public: | 99 public: |
98 struct Response { | 100 struct Response { |
99 int http_status_code = 404; | 101 int http_status_code = 404; |
100 BitmapVector bitmaps; | 102 BitmapVector bitmaps; |
101 SizeVector original_bitmap_sizes; | 103 SizeVector original_bitmap_sizes; |
102 }; | 104 }; |
103 | 105 |
104 FakeImageDownloader() : next_download_id_(1) {} | 106 FakeImageDownloader() : next_download_id_(1) {} |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 } | 377 } |
376 | 378 |
377 base::MessageLoopForUI message_loop_; | 379 base::MessageLoopForUI message_loop_; |
378 std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors> | 380 std::unique_ptr<ui::test::ScopedSetSupportedScaleFactors> |
379 scoped_set_supported_scale_factors_; | 381 scoped_set_supported_scale_factors_; |
380 testing::NiceMock<MockFaviconServiceWithFake> favicon_service_; | 382 testing::NiceMock<MockFaviconServiceWithFake> favicon_service_; |
381 testing::NiceMock<MockDelegate> delegate_; | 383 testing::NiceMock<MockDelegate> delegate_; |
382 }; | 384 }; |
383 | 385 |
384 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { | 386 TEST_F(FaviconHandlerTest, GetFaviconFromHistory) { |
| 387 base::HistogramTester histogram_tester; |
385 const GURL kIconURL("http://www.google.com/favicon"); | 388 const GURL kIconURL("http://www.google.com/favicon"); |
386 | 389 |
387 favicon_service_.fake()->Store(kPageURL, kIconURL, | 390 favicon_service_.fake()->Store(kPageURL, kIconURL, |
388 CreateRawBitmapResult(kIconURL)); | 391 CreateRawBitmapResult(kIconURL)); |
389 | 392 |
390 EXPECT_CALL(delegate_, OnFaviconUpdated( | 393 EXPECT_CALL(delegate_, OnFaviconUpdated( |
391 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, | 394 kPageURL, FaviconDriverObserver::NON_TOUCH_16_DIP, |
392 kIconURL, /*icon_url_changed=*/true, _)); | 395 kIconURL, /*icon_url_changed=*/true, _)); |
393 | 396 |
394 RunHandlerWithSimpleFaviconCandidates({kIconURL}); | 397 RunHandlerWithSimpleFaviconCandidates({kIconURL}); |
395 EXPECT_THAT(delegate_.downloads(), IsEmpty()); | 398 EXPECT_THAT(delegate_.downloads(), IsEmpty()); |
| 399 EXPECT_THAT( |
| 400 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), |
| 401 IsEmpty()); |
| 402 EXPECT_THAT( |
| 403 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), |
| 404 IsEmpty()); |
396 } | 405 } |
397 | 406 |
398 // Test that UpdateFaviconsAndFetch() is called with the appropriate parameters | 407 // Test that UpdateFaviconsAndFetch() is called with the appropriate parameters |
399 // when there is data in the database for neither the page URL nor the icon URL. | 408 // when there is data in the database for neither the page URL nor the icon URL. |
400 TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetch) { | 409 TEST_F(FaviconHandlerTest, UpdateFaviconMappingsAndFetch) { |
401 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( | 410 EXPECT_CALL(favicon_service_, UpdateFaviconMappingsAndFetch( |
402 kPageURL, URLVector{kIconURL16x16}, FAVICON, | 411 kPageURL, URLVector{kIconURL16x16}, FAVICON, |
403 /*desired_size_in_dip=*/16, _, _)); | 412 /*desired_size_in_dip=*/16, _, _)); |
404 | 413 |
405 RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); | 414 RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 | 537 |
529 RunHandlerWithSimpleFaviconCandidates({kNewIconURL}); | 538 RunHandlerWithSimpleFaviconCandidates({kNewIconURL}); |
530 EXPECT_THAT(delegate_.downloads(), ElementsAre(kNewIconURL)); | 539 EXPECT_THAT(delegate_.downloads(), ElementsAre(kNewIconURL)); |
531 } | 540 } |
532 | 541 |
533 // If there is data for the page URL in history which is invalid, test that: | 542 // If there is data for the page URL in history which is invalid, test that: |
534 // - The invalid data is not sent to the UI. | 543 // - The invalid data is not sent to the UI. |
535 // - The icon is redownloaded. | 544 // - The icon is redownloaded. |
536 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { | 545 TEST_F(FaviconHandlerTest, FaviconInHistoryInvalid) { |
537 // Set non empty but invalid data. | 546 // Set non empty but invalid data. |
538 FaviconRawBitmapResult bitmap_result; | 547 std::vector<FaviconRawBitmapResult> bitmap_result = |
539 bitmap_result.expired = false; | 548 CreateRawBitmapResult(kIconURL16x16); |
540 // Empty bitmap data is invalid. | 549 // Empty bitmap data is invalid. |
541 bitmap_result.bitmap_data = new base::RefCountedBytes(); | 550 bitmap_result[0].bitmap_data = new base::RefCountedBytes(); |
542 bitmap_result.pixel_size = gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize); | |
543 bitmap_result.icon_type = FAVICON; | |
544 bitmap_result.icon_url = kIconURL16x16; | |
545 | 551 |
546 favicon_service_.fake()->Store(kPageURL, kIconURL16x16, {bitmap_result}); | 552 favicon_service_.fake()->Store(kPageURL, kIconURL16x16, bitmap_result); |
547 | 553 |
548 // TODO(crbug.com/700811): It would be nice if we could check the image | 554 // TODO(crbug.com/700811): It would be nice if we could check the image |
549 // being published to rule out invalid data. | 555 // being published to rule out invalid data. |
550 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _)); | 556 EXPECT_CALL(delegate_, OnFaviconUpdated(_, _, kIconURL16x16, _, _)); |
551 | 557 |
552 RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); | 558 RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); |
553 | 559 |
554 EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL)); | 560 EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL)); |
555 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16)); | 561 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL16x16)); |
556 } | 562 } |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1024 EXPECT_CALL(delegate_, | 1030 EXPECT_CALL(delegate_, |
1025 OnFaviconUpdated(_, _, kIconURL12x12, _, ImageSizeIs(12, 12))); | 1031 OnFaviconUpdated(_, _, kIconURL12x12, _, ImageSizeIs(12, 12))); |
1026 | 1032 |
1027 RunHandlerWithCandidates( | 1033 RunHandlerWithCandidates( |
1028 FaviconDriverObserver::NON_TOUCH_LARGEST, | 1034 FaviconDriverObserver::NON_TOUCH_LARGEST, |
1029 {FaviconURL(kIconURL10x10, FAVICON, SizeVector{gfx::Size(16, 16)}), | 1035 {FaviconURL(kIconURL10x10, FAVICON, SizeVector{gfx::Size(16, 16)}), |
1030 FaviconURL(kIconURL12x12, FAVICON, SizeVector{gfx::Size(15, 15)}), | 1036 FaviconURL(kIconURL12x12, FAVICON, SizeVector{gfx::Size(15, 15)}), |
1031 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); | 1037 FaviconURL(kIconURL16x16, FAVICON, kEmptySizes)}); |
1032 } | 1038 } |
1033 | 1039 |
| 1040 TEST_F(FaviconHandlerTest, TestRecordMultipleDownloadAttempts) { |
| 1041 base::HistogramTester histogram_tester; |
| 1042 |
| 1043 // Try to download the three failing icons and end up logging three attempts. |
| 1044 RunHandlerWithCandidates( |
| 1045 FaviconDriverObserver::NON_TOUCH_LARGEST, |
| 1046 {FaviconURL(GURL("http://www.google.com/a"), FAVICON, kEmptySizes), |
| 1047 FaviconURL(GURL("http://www.google.com/b"), FAVICON, kEmptySizes), |
| 1048 FaviconURL(GURL("http://www.google.com/c"), FAVICON, kEmptySizes)}); |
| 1049 |
| 1050 EXPECT_THAT( |
| 1051 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), |
| 1052 ElementsAre(base::Bucket(/*sample=*/3, /*expected_count=*/1))); |
| 1053 EXPECT_THAT( |
| 1054 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), |
| 1055 IsEmpty()); |
| 1056 EXPECT_THAT( |
| 1057 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), |
| 1058 IsEmpty()); |
| 1059 } |
| 1060 |
| 1061 TEST_F(FaviconHandlerTest, TestRecordSingleFaviconDownloadAttempt) { |
| 1062 base::HistogramTester histogram_tester; |
| 1063 |
| 1064 RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); |
| 1065 |
| 1066 EXPECT_THAT( |
| 1067 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), |
| 1068 ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); |
| 1069 EXPECT_THAT( |
| 1070 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), |
| 1071 IsEmpty()); |
| 1072 EXPECT_THAT( |
| 1073 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), |
| 1074 IsEmpty()); |
| 1075 } |
| 1076 |
| 1077 TEST_F(FaviconHandlerTest, TestRecordSingleLargeIconDownloadAttempt) { |
| 1078 base::HistogramTester histogram_tester; |
| 1079 |
| 1080 RunHandlerWithCandidates(FaviconDriverObserver::NON_TOUCH_LARGEST, |
| 1081 {FaviconURL(kIconURL64x64, FAVICON, kEmptySizes)}); |
| 1082 |
| 1083 EXPECT_THAT( |
| 1084 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), |
| 1085 IsEmpty()); |
| 1086 EXPECT_THAT( |
| 1087 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), |
| 1088 ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); |
| 1089 EXPECT_THAT( |
| 1090 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), |
| 1091 IsEmpty()); |
| 1092 } |
| 1093 |
| 1094 TEST_F(FaviconHandlerTest, TestRecordSingleTouchIconDownloadAttempt) { |
| 1095 base::HistogramTester histogram_tester; |
| 1096 RunHandlerWithCandidates( |
| 1097 FaviconDriverObserver::TOUCH_LARGEST, |
| 1098 {FaviconURL(kIconURL64x64, TOUCH_ICON, kEmptySizes)}); |
| 1099 |
| 1100 EXPECT_THAT( |
| 1101 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), |
| 1102 IsEmpty()); |
| 1103 EXPECT_THAT( |
| 1104 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), |
| 1105 IsEmpty()); |
| 1106 EXPECT_THAT( |
| 1107 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), |
| 1108 ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); |
| 1109 } |
| 1110 |
| 1111 TEST_F(FaviconHandlerTest, TestRecordDownloadAttemptsFinishedByCache) { |
| 1112 const GURL kIconURL1024x1024("http://www.google.com/a-404-ing-icon"); |
| 1113 base::HistogramTester histogram_tester; |
| 1114 favicon_service_.fake()->Store( |
| 1115 GURL("http://so.de"), kIconURL64x64, |
| 1116 CreateRawBitmapResult(kIconURL64x64, FAVICON, /*expired=*/false, 64)); |
| 1117 |
| 1118 RunHandlerWithCandidates( |
| 1119 FaviconDriverObserver::NON_TOUCH_LARGEST, |
| 1120 {FaviconURL(kIconURL1024x1024, FAVICON, {gfx::Size(1024, 1024)}), |
| 1121 FaviconURL(kIconURL12x12, FAVICON, {gfx::Size(12, 12)}), |
| 1122 FaviconURL(kIconURL64x64, FAVICON, {gfx::Size(64, 64)})}); |
| 1123 |
| 1124 // Should try only the first (receive 404) and get second icon from cache. |
| 1125 EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL1024x1024)); |
| 1126 |
| 1127 EXPECT_THAT( |
| 1128 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.LargeIcons"), |
| 1129 ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); |
| 1130 EXPECT_THAT( |
| 1131 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), |
| 1132 IsEmpty()); |
| 1133 EXPECT_THAT( |
| 1134 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.TouchIcons"), |
| 1135 IsEmpty()); |
| 1136 } |
| 1137 |
| 1138 TEST_F(FaviconHandlerTest, TestRecordSingleDownloadAttemptForRefreshingIcons) { |
| 1139 base::HistogramTester histogram_tester; |
| 1140 favicon_service_.fake()->Store( |
| 1141 GURL("http://www.google.com/ps"), kIconURL16x16, |
| 1142 CreateRawBitmapResult(kIconURL16x16, FAVICON, /*expired=*/true)); |
| 1143 |
| 1144 RunHandlerWithSimpleFaviconCandidates({kIconURL16x16}); |
| 1145 |
| 1146 EXPECT_THAT( |
| 1147 histogram_tester.GetAllSamples("Favicons.DownloadAttempts.Favicons"), |
| 1148 ElementsAre(base::Bucket(/*sample=*/1, /*expected_count=*/1))); |
| 1149 } |
| 1150 |
1034 } // namespace | 1151 } // namespace |
1035 } // namespace favicon | 1152 } // namespace favicon |
OLD | NEW |