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
3 // found in the LICENSE file.
5 #include "ui/base/resource/resource_bundle.h"
7 #include "base/base_paths.h"
8 #include "base/big_endian.h"
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/logging.h"
13 #include "base/memory/ref_counted_memory.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/skia/include/core/SkBitmap.h"
18 #include "ui/base/layout.h"
19 #include "ui/base/resource/data_pack.h"
20 #include "ui/gfx/codec/png_codec.h"
21 #include "ui/gfx/image/image_skia.h"
22 #include "ui/resources/grit/ui_resources.h"
25 #include "ui/gfx/win/dpi.h"
29 using ::testing::Between;
30 using ::testing::Property;
31 using ::testing::Return;
32 using ::testing::ReturnArg;
36 extern const char kSamplePakContents[];
37 extern const size_t kSamplePakSize;
38 extern const char kSamplePakContents2x[];
39 extern const size_t kSamplePakSize2x;
40 extern const char kEmptyPakContents[];
41 extern const size_t kEmptyPakSize;
45 const unsigned char kPngMagic[8] = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 };
46 const size_t kPngChunkMetadataSize = 12;
47 const unsigned char kPngIHDRChunkType[4] = { 'I', 'H', 'D', 'R' };
49 // Custom chunk that GRIT adds to PNG to indicate that it could not find a
50 // bitmap at the requested scale factor and fell back to 1x.
51 const unsigned char kPngScaleChunk[12] = { 0x00, 0x00, 0x00, 0x00,
53 0xc1, 0x30, 0x60, 0x4d };
55 // Mock for the ResourceBundle::Delegate class.
56 class MockResourceBundleDelegate : public ui::ResourceBundle::Delegate {
58 MockResourceBundleDelegate() {
60 virtual ~MockResourceBundleDelegate() {
63 MOCK_METHOD2(GetPathForResourcePack, base::FilePath(
64 const base::FilePath& pack_path, ui::ScaleFactor scale_factor));
65 MOCK_METHOD2(GetPathForLocalePack, base::FilePath(
66 const base::FilePath& pack_path, const std::string& locale));
67 MOCK_METHOD1(GetImageNamed, gfx::Image(int resource_id));
68 MOCK_METHOD2(GetNativeImageNamed,
69 gfx::Image(int resource_id,
70 ui::ResourceBundle::ImageRTL rtl));
71 MOCK_METHOD2(LoadDataResourceBytes,
72 base::RefCountedStaticMemory*(int resource_id,
73 ui::ScaleFactor scale_factor));
74 MOCK_METHOD2(GetRawDataResourceMock, base::StringPiece(
76 ui::ScaleFactor scale_factor));
77 virtual bool GetRawDataResource(int resource_id,
78 ui::ScaleFactor scale_factor,
79 base::StringPiece* value) override {
80 *value = GetRawDataResourceMock(resource_id, scale_factor);
83 MOCK_METHOD1(GetLocalizedStringMock, base::string16(int message_id));
84 virtual bool GetLocalizedString(int message_id,
85 base::string16* value) override {
86 *value = GetLocalizedStringMock(message_id);
89 MOCK_METHOD1(GetFontMock,
90 gfx::Font*(ui::ResourceBundle::FontStyle style));
91 virtual scoped_ptr<gfx::Font> GetFont(
92 ui::ResourceBundle::FontStyle style) override {
93 return scoped_ptr<gfx::Font>(GetFontMock(style));
97 // Returns |bitmap_data| with |custom_chunk| inserted after the IHDR chunk.
98 void AddCustomChunk(const base::StringPiece& custom_chunk,
99 std::vector<unsigned char>* bitmap_data) {
100 EXPECT_LT(arraysize(kPngMagic) + kPngChunkMetadataSize, bitmap_data->size());
101 EXPECT_TRUE(std::equal(
102 bitmap_data->begin(),
103 bitmap_data->begin() + arraysize(kPngMagic),
105 std::vector<unsigned char>::iterator ihdr_start =
106 bitmap_data->begin() + arraysize(kPngMagic);
107 char ihdr_length_data[sizeof(uint32)];
108 for (size_t i = 0; i < sizeof(uint32); ++i)
109 ihdr_length_data[i] = *(ihdr_start + i);
110 uint32 ihdr_chunk_length = 0;
111 base::ReadBigEndian(reinterpret_cast<char*>(ihdr_length_data),
113 EXPECT_TRUE(std::equal(
114 ihdr_start + sizeof(uint32),
115 ihdr_start + sizeof(uint32) + sizeof(kPngIHDRChunkType),
118 bitmap_data->insert(ihdr_start + kPngChunkMetadataSize + ihdr_chunk_length,
119 custom_chunk.begin(), custom_chunk.end());
122 // Creates datapack at |path| with a single bitmap at resource ID 3
123 // which is |edge_size|x|edge_size| pixels.
124 // If |custom_chunk| is non empty, adds it after the IHDR chunk
125 // in the encoded bitmap data.
126 void CreateDataPackWithSingleBitmap(const base::FilePath& path,
128 const base::StringPiece& custom_chunk) {
130 bitmap.allocN32Pixels(edge_size, edge_size);
131 bitmap.eraseColor(SK_ColorWHITE);
132 std::vector<unsigned char> bitmap_data;
133 EXPECT_TRUE(gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bitmap_data));
135 if (custom_chunk.size() > 0)
136 AddCustomChunk(custom_chunk, &bitmap_data);
138 std::map<uint16, base::StringPiece> resources;
139 resources[3u] = base::StringPiece(
140 reinterpret_cast<const char*>(&bitmap_data[0]), bitmap_data.size());
141 DataPack::WritePack(path, resources, ui::DataPack::BINARY);
146 class ResourceBundleTest : public testing::Test {
148 ResourceBundleTest() : resource_bundle_(NULL) {
151 ~ResourceBundleTest() override {}
153 // Overridden from testing::Test:
154 void TearDown() override { delete resource_bundle_; }
156 // Returns new ResoureBundle with the specified |delegate|. The
157 // ResourceBundleTest class manages the lifetime of the returned
159 ResourceBundle* CreateResourceBundle(ResourceBundle::Delegate* delegate) {
160 DCHECK(!resource_bundle_);
162 resource_bundle_ = new ResourceBundle(delegate);
163 return resource_bundle_;
167 ResourceBundle* resource_bundle_;
170 DISALLOW_COPY_AND_ASSIGN(ResourceBundleTest);
173 TEST_F(ResourceBundleTest, DelegateGetPathForResourcePack) {
174 MockResourceBundleDelegate delegate;
175 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
177 base::FilePath pack_path(FILE_PATH_LITERAL("/path/to/test_path.pak"));
178 ui::ScaleFactor pack_scale_factor = ui::SCALE_FACTOR_200P;
180 EXPECT_CALL(delegate,
181 GetPathForResourcePack(
182 Property(&base::FilePath::value, pack_path.value()),
185 .WillOnce(Return(pack_path));
187 resource_bundle->AddDataPackFromPath(pack_path, pack_scale_factor);
190 #if defined(OS_LINUX)
191 // Fails consistently on Linux: crbug.com/161902
192 #define MAYBE_DelegateGetPathForLocalePack DISABLED_DelegateGetPathForLocalePack
194 #define MAYBE_DelegateGetPathForLocalePack DelegateGetPathForLocalePack
196 TEST_F(ResourceBundleTest, MAYBE_DelegateGetPathForLocalePack) {
197 MockResourceBundleDelegate delegate;
198 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
200 std::string locale = "en-US";
203 EXPECT_CALL(delegate, GetPathForLocalePack(_, locale))
205 .WillRepeatedly(Return(base::FilePath()))
206 .RetiresOnSaturation();
208 EXPECT_FALSE(resource_bundle->LocaleDataPakExists(locale));
209 EXPECT_EQ("", resource_bundle->LoadLocaleResources(locale));
211 // Allow the load to proceed.
212 EXPECT_CALL(delegate, GetPathForLocalePack(_, locale))
214 .WillRepeatedly(ReturnArg<0>());
216 EXPECT_TRUE(resource_bundle->LocaleDataPakExists(locale));
217 EXPECT_EQ(locale, resource_bundle->LoadLocaleResources(locale));
220 TEST_F(ResourceBundleTest, DelegateGetImageNamed) {
221 MockResourceBundleDelegate delegate;
222 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
224 gfx::Image empty_image = resource_bundle->GetEmptyImage();
227 EXPECT_CALL(delegate, GetImageNamed(resource_id))
229 .WillOnce(Return(empty_image));
231 gfx::Image result = resource_bundle->GetImageNamed(resource_id);
232 EXPECT_EQ(empty_image.ToSkBitmap(), result.ToSkBitmap());
235 TEST_F(ResourceBundleTest, DelegateGetNativeImageNamed) {
236 MockResourceBundleDelegate delegate;
237 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
239 gfx::Image empty_image = resource_bundle->GetEmptyImage();
242 // Some platforms delegate GetNativeImageNamed calls to GetImageNamed.
243 EXPECT_CALL(delegate, GetImageNamed(resource_id))
244 .Times(Between(0, 1))
245 .WillOnce(Return(empty_image));
246 EXPECT_CALL(delegate,
247 GetNativeImageNamed(resource_id, ui::ResourceBundle::RTL_DISABLED))
248 .Times(Between(0, 1))
249 .WillOnce(Return(empty_image));
251 gfx::Image result = resource_bundle->GetNativeImageNamed(resource_id);
252 EXPECT_EQ(empty_image.ToSkBitmap(), result.ToSkBitmap());
255 TEST_F(ResourceBundleTest, DelegateLoadDataResourceBytes) {
256 MockResourceBundleDelegate delegate;
257 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
259 // Create the data resource for testing purposes.
260 unsigned char data[] = "My test data";
261 scoped_refptr<base::RefCountedStaticMemory> static_memory(
262 new base::RefCountedStaticMemory(data, sizeof(data)));
265 ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_NONE;
267 EXPECT_CALL(delegate, LoadDataResourceBytes(resource_id, scale_factor))
268 .Times(1).WillOnce(Return(static_memory.get()));
270 scoped_refptr<base::RefCountedStaticMemory> result =
271 resource_bundle->LoadDataResourceBytesForScale(resource_id, scale_factor);
272 EXPECT_EQ(static_memory, result);
275 TEST_F(ResourceBundleTest, DelegateGetRawDataResource) {
276 MockResourceBundleDelegate delegate;
277 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
279 // Create the string piece for testing purposes.
280 char data[] = "My test data";
281 base::StringPiece string_piece(data);
285 EXPECT_CALL(delegate, GetRawDataResourceMock(
286 resource_id, ui::SCALE_FACTOR_NONE))
288 .WillOnce(Return(string_piece));
290 base::StringPiece result = resource_bundle->GetRawDataResource(
292 EXPECT_EQ(string_piece.data(), result.data());
295 TEST_F(ResourceBundleTest, DelegateGetLocalizedString) {
296 MockResourceBundleDelegate delegate;
297 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
299 base::string16 data = base::ASCIIToUTF16("My test data");
302 EXPECT_CALL(delegate, GetLocalizedStringMock(resource_id))
304 .WillOnce(Return(data));
306 base::string16 result = resource_bundle->GetLocalizedString(resource_id);
307 EXPECT_EQ(data, result);
310 TEST_F(ResourceBundleTest, OverrideStringResource) {
311 ResourceBundle* resource_bundle = CreateResourceBundle(NULL);
313 base::string16 data = base::ASCIIToUTF16("My test data");
316 base::string16 result = resource_bundle->GetLocalizedString(resource_id);
317 EXPECT_EQ(base::string16(), result);
319 resource_bundle->OverrideLocaleStringResource(resource_id, data);
321 result = resource_bundle->GetLocalizedString(resource_id);
322 EXPECT_EQ(data, result);
325 TEST_F(ResourceBundleTest, DelegateGetLocalizedStringWithOverride) {
326 MockResourceBundleDelegate delegate;
327 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
329 base::string16 delegate_data = base::ASCIIToUTF16("My delegate data");
332 EXPECT_CALL(delegate, GetLocalizedStringMock(resource_id)).Times(1).WillOnce(
333 Return(delegate_data));
335 base::string16 override_data = base::ASCIIToUTF16("My override data");
337 base::string16 result = resource_bundle->GetLocalizedString(resource_id);
338 EXPECT_EQ(delegate_data, result);
341 #if (defined(USE_OZONE) && !defined(USE_PANGO)) || defined(OS_ANDROID)
342 #define MAYBE_DelegateGetFontList DISABLED_DelegateGetFontList
344 #define MAYBE_DelegateGetFontList DelegateGetFontList
347 TEST_F(ResourceBundleTest, MAYBE_DelegateGetFontList) {
348 MockResourceBundleDelegate delegate;
349 ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);
351 // Should be called once for each font type. When we return NULL the default
352 // font will be created.
353 gfx::Font* test_font = NULL;
354 EXPECT_CALL(delegate, GetFontMock(_))
356 .WillRepeatedly(Return(test_font));
358 const gfx::FontList* font_list =
359 &resource_bundle->GetFontList(ui::ResourceBundle::BaseFont);
360 EXPECT_TRUE(font_list);
362 const gfx::Font* font =
363 &resource_bundle->GetFont(ui::ResourceBundle::BaseFont);
367 TEST_F(ResourceBundleTest, LocaleDataPakExists) {
368 ResourceBundle* resource_bundle = CreateResourceBundle(NULL);
370 // Check that ResourceBundle::LocaleDataPakExists returns the correct results.
371 EXPECT_TRUE(resource_bundle->LocaleDataPakExists("en-US"));
372 EXPECT_FALSE(resource_bundle->LocaleDataPakExists("not_a_real_locale"));
375 class ResourceBundleImageTest : public ResourceBundleTest {
377 ResourceBundleImageTest() {}
379 ~ResourceBundleImageTest() override {}
381 void SetUp() override {
382 // Create a temporary directory to write test resource bundles to.
383 ASSERT_TRUE(dir_.CreateUniqueTempDir());
386 // Returns resource bundle which uses an empty data pak for locale data.
387 ui::ResourceBundle* CreateResourceBundleWithEmptyLocalePak() {
388 // Write an empty data pak for locale data.
389 const base::FilePath& locale_path = dir_path().Append(
390 FILE_PATH_LITERAL("locale.pak"));
391 EXPECT_EQ(base::WriteFile(locale_path, kEmptyPakContents, kEmptyPakSize),
392 static_cast<int>(kEmptyPakSize));
394 ui::ResourceBundle* resource_bundle = CreateResourceBundle(NULL);
396 // Load the empty locale data pak.
397 resource_bundle->LoadTestResources(base::FilePath(), locale_path);
398 return resource_bundle;
401 // Returns the path of temporary directory to write test data packs into.
402 const base::FilePath& dir_path() { return dir_.path(); }
405 scoped_ptr<DataPack> locale_pack_;
406 base::ScopedTempDir dir_;
408 DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageTest);
411 // Verify that we don't crash when trying to load a resource that is not found.
412 // In some cases, we fail to mmap resources.pak, but try to keep going anyway.
413 TEST_F(ResourceBundleImageTest, LoadDataResourceBytes) {
414 base::FilePath data_path = dir_path().Append(FILE_PATH_LITERAL("sample.pak"));
416 // Dump contents into the pak files.
417 ASSERT_EQ(base::WriteFile(data_path, kEmptyPakContents,
418 kEmptyPakSize), static_cast<int>(kEmptyPakSize));
420 // Create a resource bundle from the file.
421 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
422 resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
424 const int kUnfoundResourceId = 10000;
425 EXPECT_EQ(NULL, resource_bundle->LoadDataResourceBytes(
426 kUnfoundResourceId));
428 // Give a .pak file that doesn't exist so we will fail to load it.
429 resource_bundle->AddDataPackFromPath(
430 base::FilePath(FILE_PATH_LITERAL("non-existant-file.pak")),
431 ui::SCALE_FACTOR_NONE);
432 EXPECT_EQ(NULL, resource_bundle->LoadDataResourceBytes(
433 kUnfoundResourceId));
436 TEST_F(ResourceBundleImageTest, GetRawDataResource) {
437 base::FilePath data_path = dir_path().Append(FILE_PATH_LITERAL("sample.pak"));
438 base::FilePath data_2x_path =
439 dir_path().Append(FILE_PATH_LITERAL("sample_2x.pak"));
441 // Dump contents into the pak files.
442 ASSERT_EQ(base::WriteFile(data_path, kSamplePakContents,
443 kSamplePakSize), static_cast<int>(kSamplePakSize));
444 ASSERT_EQ(base::WriteFile(data_2x_path, kSamplePakContents2x,
445 kSamplePakSize2x), static_cast<int>(kSamplePakSize2x));
447 // Load the regular and 2x pak files.
448 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
449 resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
450 resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);
452 // Resource ID 4 exists in both 1x and 2x paks, so we expect a different
453 // result when requesting the 2x scale.
454 EXPECT_EQ("this is id 4", resource_bundle->GetRawDataResourceForScale(4,
456 EXPECT_EQ("this is id 4 2x", resource_bundle->GetRawDataResourceForScale(4,
459 // Resource ID 6 only exists in the 1x pak so we expect the same resource
460 // for both scale factor requests.
461 EXPECT_EQ("this is id 6", resource_bundle->GetRawDataResourceForScale(6,
463 EXPECT_EQ("this is id 6", resource_bundle->GetRawDataResourceForScale(6,
467 // Test requesting image reps at various scale factors from the image returned
468 // via ResourceBundle::GetImageNamed().
469 TEST_F(ResourceBundleImageTest, GetImageNamed) {
471 gfx::InitDeviceScaleFactor(2.0);
473 std::vector<ScaleFactor> supported_factors;
474 supported_factors.push_back(SCALE_FACTOR_100P);
475 supported_factors.push_back(SCALE_FACTOR_200P);
476 test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
477 base::FilePath data_1x_path = dir_path().AppendASCII("sample_1x.pak");
478 base::FilePath data_2x_path = dir_path().AppendASCII("sample_2x.pak");
480 // Create the pak files.
481 CreateDataPackWithSingleBitmap(data_1x_path, 10, base::StringPiece());
482 CreateDataPackWithSingleBitmap(data_2x_path, 20, base::StringPiece());
484 // Load the regular and 2x pak files.
485 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
486 resource_bundle->AddDataPackFromPath(data_1x_path, SCALE_FACTOR_100P);
487 resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);
489 EXPECT_EQ(SCALE_FACTOR_200P, resource_bundle->GetMaxScaleFactor());
491 gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
493 #if defined(OS_CHROMEOS) || defined(OS_WIN)
494 // ChromeOS/Windows load highest scale factor first.
495 EXPECT_EQ(ui::SCALE_FACTOR_200P,
496 GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
498 EXPECT_EQ(ui::SCALE_FACTOR_100P,
499 GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
502 // Resource ID 3 exists in both 1x and 2x paks. Image reps should be
503 // available for both scale factors in |image_skia|.
504 gfx::ImageSkiaRep image_rep =
505 image_skia->GetRepresentation(
506 GetScaleForScaleFactor(ui::SCALE_FACTOR_100P));
507 EXPECT_EQ(ui::SCALE_FACTOR_100P, GetSupportedScaleFactor(image_rep.scale()));
509 image_skia->GetRepresentation(
510 GetScaleForScaleFactor(ui::SCALE_FACTOR_200P));
511 EXPECT_EQ(ui::SCALE_FACTOR_200P, GetSupportedScaleFactor(image_rep.scale()));
513 // The 1.4x pack was not loaded. Requesting the 1.4x resource should return
514 // either the 1x or the 2x resource.
515 image_rep = image_skia->GetRepresentation(
516 ui::GetScaleForScaleFactor(ui::SCALE_FACTOR_140P));
517 ui::ScaleFactor scale_factor = GetSupportedScaleFactor(image_rep.scale());
518 EXPECT_TRUE(scale_factor == ui::SCALE_FACTOR_100P ||
519 scale_factor == ui::SCALE_FACTOR_200P);
521 // ImageSkia scales image if the one for the requested scale factor is not
523 EXPECT_EQ(1.4f, image_skia->GetRepresentation(1.4f).scale());
526 // Test that GetImageNamed() behaves properly for images which GRIT has
527 // annotated as having fallen back to 1x.
528 TEST_F(ResourceBundleImageTest, GetImageNamedFallback1x) {
529 std::vector<ScaleFactor> supported_factors;
530 supported_factors.push_back(SCALE_FACTOR_100P);
531 supported_factors.push_back(SCALE_FACTOR_200P);
532 test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
533 base::FilePath data_path = dir_path().AppendASCII("sample.pak");
534 base::FilePath data_2x_path = dir_path().AppendASCII("sample_2x.pak");
536 // Create the pak files.
537 CreateDataPackWithSingleBitmap(data_path, 10, base::StringPiece());
538 // 2x data pack bitmap has custom chunk to indicate that the 2x bitmap is not
539 // available and that GRIT fell back to 1x.
540 CreateDataPackWithSingleBitmap(data_2x_path, 10, base::StringPiece(
541 reinterpret_cast<const char*>(kPngScaleChunk),
542 arraysize(kPngScaleChunk)));
544 // Load the regular and 2x pak files.
545 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
546 resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
547 resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);
549 gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
551 // The image rep for 2x should be available. It should be resized to the
553 gfx::ImageSkiaRep image_rep =
554 image_skia->GetRepresentation(GetScaleForScaleFactor(
555 ui::SCALE_FACTOR_200P));
556 EXPECT_EQ(ui::SCALE_FACTOR_200P, GetSupportedScaleFactor(image_rep.scale()));
557 EXPECT_EQ(20, image_rep.pixel_width());
558 EXPECT_EQ(20, image_rep.pixel_height());
562 // Tests GetImageNamed() behaves properly when the size of a scaled image
563 // requires rounding as a result of using a non-integer scale factor.
564 // Scale factors of 140 and 1805 are Windows specific.
565 TEST_F(ResourceBundleImageTest, GetImageNamedFallback1xRounding) {
566 std::vector<ScaleFactor> supported_factors;
567 supported_factors.push_back(SCALE_FACTOR_100P);
568 supported_factors.push_back(SCALE_FACTOR_140P);
569 supported_factors.push_back(SCALE_FACTOR_180P);
570 test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
572 base::FilePath data_path = dir_path().AppendASCII("sample.pak");
573 base::FilePath data_140P_path = dir_path().AppendASCII("sample_140P.pak");
574 base::FilePath data_180P_path = dir_path().AppendASCII("sample_180P.pak");
576 CreateDataPackWithSingleBitmap(data_path, 8, base::StringPiece());
577 // Mark 140% and 180% images as requiring 1x fallback.
578 CreateDataPackWithSingleBitmap(data_140P_path, 8, base::StringPiece(
579 reinterpret_cast<const char*>(kPngScaleChunk),
580 arraysize(kPngScaleChunk)));
581 CreateDataPackWithSingleBitmap(data_180P_path, 8, base::StringPiece(
582 reinterpret_cast<const char*>(kPngScaleChunk),
583 arraysize(kPngScaleChunk)));
585 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
586 resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
587 resource_bundle->AddDataPackFromPath(data_140P_path, SCALE_FACTOR_140P);
588 resource_bundle->AddDataPackFromPath(data_180P_path, SCALE_FACTOR_180P);
590 // Non-integer dimensions should be rounded up.
591 gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
592 gfx::ImageSkiaRep image_rep =
593 image_skia->GetRepresentation(
594 GetScaleForScaleFactor(ui::SCALE_FACTOR_140P));
595 EXPECT_EQ(12, image_rep.pixel_width());
596 image_rep = image_skia->GetRepresentation(
597 GetScaleForScaleFactor(ui::SCALE_FACTOR_180P));
598 EXPECT_EQ(15, image_rep.pixel_width());
603 // Fails on devices that have non-100P scaling. See crbug.com/298406
604 #define MAYBE_FallbackToNone DISABLED_FallbackToNone
606 #define MAYBE_FallbackToNone FallbackToNone
608 TEST_F(ResourceBundleImageTest, MAYBE_FallbackToNone) {
609 base::FilePath data_default_path = dir_path().AppendASCII("sample.pak");
611 // Create the pak files.
612 CreateDataPackWithSingleBitmap(data_default_path, 10, base::StringPiece());
614 // Load the regular pak files only.
615 ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
616 resource_bundle->AddDataPackFromPath(data_default_path, SCALE_FACTOR_NONE);
618 gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
619 EXPECT_EQ(1u, image_skia->image_reps().size());
620 EXPECT_TRUE(image_skia->image_reps()[0].unscaled());
621 EXPECT_EQ(ui::SCALE_FACTOR_100P,
622 GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));