Chromium Code Reviews| 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 kPageURL, kIconURL16x16, | |
|
pkotwicz
2017/04/12 14:39:24
In order to trigger the error case in FaviconHandl
fhorschig
2017/04/13 14:49:35
Correct, thanks!
(I should be more careful while r
| |
| 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 |