// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/resource/resource_bundle.h"

#include "base/base_paths.h"
#include "base/big_endian.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "grit/ui_resources.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/layout.h"
#include "ui/base/resource/data_pack.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image_skia.h"
#if defined(OS_WIN)
#include "ui/gfx/win/dpi.h"
#endif

using ::testing::_;
using ::testing::Between;
using ::testing::Property;
using ::testing::Return;
using ::testing::ReturnArg;

namespace ui {

extern const char kSamplePakContents[];
extern const size_t kSamplePakSize;
extern const char kSamplePakContents2x[];
extern const size_t kSamplePakSize2x;
extern const char kEmptyPakContents[];
extern const size_t kEmptyPakSize;

namespace {

const unsigned char kPngMagic[8] = { 0x89, 'P', 'N', 'G', 13, 10, 26, 10 };
const size_t kPngChunkMetadataSize = 12;
const unsigned char kPngIHDRChunkType[4] = { 'I', 'H', 'D', 'R' };

// Custom chunk that GRIT adds to PNG to indicate that it could not find a
// bitmap at the requested scale factor and fell back to 1x.
const unsigned char kPngScaleChunk[12] = { 0x00, 0x00, 0x00, 0x00,
                                           'c', 's', 'C', 'l',
                                           0xc1, 0x30, 0x60, 0x4d };

// Mock for the ResourceBundle::Delegate class.
class MockResourceBundleDelegate : public ui::ResourceBundle::Delegate {
 public:
  MockResourceBundleDelegate() {
  }
  virtual ~MockResourceBundleDelegate() {
  }

  MOCK_METHOD2(GetPathForResourcePack, base::FilePath(
      const base::FilePath& pack_path, ui::ScaleFactor scale_factor));
  MOCK_METHOD2(GetPathForLocalePack, base::FilePath(
      const base::FilePath& pack_path, const std::string& locale));
  MOCK_METHOD1(GetImageNamed, gfx::Image(int resource_id));
  MOCK_METHOD2(GetNativeImageNamed,
      gfx::Image(int resource_id,
                 ui::ResourceBundle::ImageRTL rtl));
  MOCK_METHOD2(LoadDataResourceBytes,
      base::RefCountedStaticMemory*(int resource_id,
                                    ui::ScaleFactor scale_factor));
  MOCK_METHOD2(GetRawDataResourceMock, base::StringPiece(
      int resource_id,
      ui::ScaleFactor scale_factor));
  virtual bool GetRawDataResource(int resource_id,
                                  ui::ScaleFactor scale_factor,
                                  base::StringPiece* value) OVERRIDE {
    *value = GetRawDataResourceMock(resource_id, scale_factor);
    return true;
  }
  MOCK_METHOD1(GetLocalizedStringMock, base::string16(int message_id));
  virtual bool GetLocalizedString(int message_id,
                                  base::string16* value) OVERRIDE {
    *value = GetLocalizedStringMock(message_id);
    return true;
  }
  MOCK_METHOD1(GetFontMock,
               gfx::Font*(ui::ResourceBundle::FontStyle style));
  virtual scoped_ptr<gfx::Font> GetFont(
      ui::ResourceBundle::FontStyle style) OVERRIDE {
    return scoped_ptr<gfx::Font>(GetFontMock(style));
  }
};

// Returns |bitmap_data| with |custom_chunk| inserted after the IHDR chunk.
void AddCustomChunk(const base::StringPiece& custom_chunk,
                    std::vector<unsigned char>* bitmap_data) {
  EXPECT_LT(arraysize(kPngMagic) + kPngChunkMetadataSize, bitmap_data->size());
  EXPECT_TRUE(std::equal(
      bitmap_data->begin(),
      bitmap_data->begin() + arraysize(kPngMagic),
      kPngMagic));
  std::vector<unsigned char>::iterator ihdr_start =
      bitmap_data->begin() + arraysize(kPngMagic);
  char ihdr_length_data[sizeof(uint32)];
  for (size_t i = 0; i < sizeof(uint32); ++i)
    ihdr_length_data[i] = *(ihdr_start + i);
  uint32 ihdr_chunk_length = 0;
  base::ReadBigEndian(reinterpret_cast<char*>(ihdr_length_data),
                      &ihdr_chunk_length);
  EXPECT_TRUE(std::equal(
      ihdr_start + sizeof(uint32),
      ihdr_start + sizeof(uint32) + sizeof(kPngIHDRChunkType),
      kPngIHDRChunkType));

  bitmap_data->insert(ihdr_start + kPngChunkMetadataSize + ihdr_chunk_length,
                      custom_chunk.begin(), custom_chunk.end());
}

// Creates datapack at |path| with a single bitmap at resource ID 3
// which is |edge_size|x|edge_size| pixels.
// If |custom_chunk| is non empty, adds it after the IHDR chunk
// in the encoded bitmap data.
void CreateDataPackWithSingleBitmap(const base::FilePath& path,
                                    int edge_size,
                                    const base::StringPiece& custom_chunk) {
  SkBitmap bitmap;
  bitmap.setConfig(SkBitmap::kARGB_8888_Config, edge_size, edge_size);
  bitmap.allocPixels();
  bitmap.eraseColor(SK_ColorWHITE);
  std::vector<unsigned char> bitmap_data;
  EXPECT_TRUE(gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &bitmap_data));

  if (custom_chunk.size() > 0)
    AddCustomChunk(custom_chunk, &bitmap_data);

  std::map<uint16, base::StringPiece> resources;
  resources[3u] = base::StringPiece(
      reinterpret_cast<const char*>(&bitmap_data[0]), bitmap_data.size());
  DataPack::WritePack(path, resources, ui::DataPack::BINARY);
}

}  // namespace

class ResourceBundleTest : public testing::Test {
 public:
  ResourceBundleTest() : resource_bundle_(NULL) {
  }

  virtual ~ResourceBundleTest() {
  }

  // Overridden from testing::Test:
  virtual void TearDown() OVERRIDE {
    delete resource_bundle_;
  }

  // Returns new ResoureBundle with the specified |delegate|. The
  // ResourceBundleTest class manages the lifetime of the returned
  // ResourceBundle.
  ResourceBundle* CreateResourceBundle(ResourceBundle::Delegate* delegate) {
    DCHECK(!resource_bundle_);

    resource_bundle_ = new ResourceBundle(delegate);
    return resource_bundle_;
  }

 protected:
  ResourceBundle* resource_bundle_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceBundleTest);
};

TEST_F(ResourceBundleTest, DelegateGetPathForResourcePack) {
  MockResourceBundleDelegate delegate;
  ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);

  base::FilePath pack_path(FILE_PATH_LITERAL("/path/to/test_path.pak"));
  ui::ScaleFactor pack_scale_factor = ui::SCALE_FACTOR_200P;

  EXPECT_CALL(delegate,
      GetPathForResourcePack(
          Property(&base::FilePath::value, pack_path.value()),
          pack_scale_factor))
      .Times(1)
      .WillOnce(Return(pack_path));

  resource_bundle->AddDataPackFromPath(pack_path, pack_scale_factor);
}

#if defined(OS_LINUX)
// Fails consistently on Linux: crbug.com/161902
#define MAYBE_DelegateGetPathForLocalePack DISABLED_DelegateGetPathForLocalePack
#else
#define MAYBE_DelegateGetPathForLocalePack DelegateGetPathForLocalePack
#endif
TEST_F(ResourceBundleTest, MAYBE_DelegateGetPathForLocalePack) {
  MockResourceBundleDelegate delegate;
  ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);

  std::string locale = "en-US";

  // Cancel the load.
  EXPECT_CALL(delegate, GetPathForLocalePack(_, locale))
      .Times(2)
      .WillRepeatedly(Return(base::FilePath()))
      .RetiresOnSaturation();

  EXPECT_FALSE(resource_bundle->LocaleDataPakExists(locale));
  EXPECT_EQ("", resource_bundle->LoadLocaleResources(locale));

  // Allow the load to proceed.
  EXPECT_CALL(delegate, GetPathForLocalePack(_, locale))
      .Times(2)
      .WillRepeatedly(ReturnArg<0>());

  EXPECT_TRUE(resource_bundle->LocaleDataPakExists(locale));
  EXPECT_EQ(locale, resource_bundle->LoadLocaleResources(locale));
}

TEST_F(ResourceBundleTest, DelegateGetImageNamed) {
  MockResourceBundleDelegate delegate;
  ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);

  gfx::Image empty_image = resource_bundle->GetEmptyImage();
  int resource_id = 5;

  EXPECT_CALL(delegate, GetImageNamed(resource_id))
      .Times(1)
      .WillOnce(Return(empty_image));

  gfx::Image result = resource_bundle->GetImageNamed(resource_id);
  EXPECT_EQ(empty_image.ToSkBitmap(), result.ToSkBitmap());
}

TEST_F(ResourceBundleTest, DelegateGetNativeImageNamed) {
  MockResourceBundleDelegate delegate;
  ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);

  gfx::Image empty_image = resource_bundle->GetEmptyImage();
  int resource_id = 5;

  // Some platforms delegate GetNativeImageNamed calls to GetImageNamed.
  EXPECT_CALL(delegate, GetImageNamed(resource_id))
      .Times(Between(0, 1))
      .WillOnce(Return(empty_image));
  EXPECT_CALL(delegate,
      GetNativeImageNamed(resource_id, ui::ResourceBundle::RTL_DISABLED))
      .Times(Between(0, 1))
      .WillOnce(Return(empty_image));

  gfx::Image result = resource_bundle->GetNativeImageNamed(resource_id);
  EXPECT_EQ(empty_image.ToSkBitmap(), result.ToSkBitmap());
}

TEST_F(ResourceBundleTest, DelegateLoadDataResourceBytes) {
  MockResourceBundleDelegate delegate;
  ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);

  // Create the data resource for testing purposes.
  unsigned char data[] = "My test data";
  scoped_refptr<base::RefCountedStaticMemory> static_memory(
      new base::RefCountedStaticMemory(data, sizeof(data)));

  int resource_id = 5;
  ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_NONE;

  EXPECT_CALL(delegate, LoadDataResourceBytes(resource_id, scale_factor))
      .Times(1).WillOnce(Return(static_memory.get()));

  scoped_refptr<base::RefCountedStaticMemory> result =
      resource_bundle->LoadDataResourceBytesForScale(resource_id, scale_factor);
  EXPECT_EQ(static_memory, result);
}

TEST_F(ResourceBundleTest, DelegateGetRawDataResource) {
  MockResourceBundleDelegate delegate;
  ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);

  // Create the string piece for testing purposes.
  char data[] = "My test data";
  base::StringPiece string_piece(data);

  int resource_id = 5;

  EXPECT_CALL(delegate, GetRawDataResourceMock(
          resource_id, ui::SCALE_FACTOR_NONE))
      .Times(1)
      .WillOnce(Return(string_piece));

  base::StringPiece result = resource_bundle->GetRawDataResource(
      resource_id);
  EXPECT_EQ(string_piece.data(), result.data());
}

TEST_F(ResourceBundleTest, DelegateGetLocalizedString) {
  MockResourceBundleDelegate delegate;
  ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);

  base::string16 data = base::ASCIIToUTF16("My test data");
  int resource_id = 5;

  EXPECT_CALL(delegate, GetLocalizedStringMock(resource_id))
      .Times(1)
      .WillOnce(Return(data));

  base::string16 result = resource_bundle->GetLocalizedString(resource_id);
  EXPECT_EQ(data, result);
}

#if defined(USE_OZONE) && !defined(USE_PANGO)
#define MAYBE_DelegateGetFontList DISABLED_DelegateGetFontList
#else
#define MAYBE_DelegateGetFontList DelegateGetFontList
#endif

TEST_F(ResourceBundleTest, MAYBE_DelegateGetFontList) {
  MockResourceBundleDelegate delegate;
  ResourceBundle* resource_bundle = CreateResourceBundle(&delegate);

  // Should be called once for each font type. When we return NULL the default
  // font will be created.
  gfx::Font* test_font = NULL;
  EXPECT_CALL(delegate, GetFontMock(_))
      .Times(8)
      .WillRepeatedly(Return(test_font));

  const gfx::FontList* font_list =
      &resource_bundle->GetFontList(ui::ResourceBundle::BaseFont);
  EXPECT_TRUE(font_list);

  const gfx::Font* font =
      &resource_bundle->GetFont(ui::ResourceBundle::BaseFont);
  EXPECT_TRUE(font);
}

TEST_F(ResourceBundleTest, LocaleDataPakExists) {
  ResourceBundle* resource_bundle = CreateResourceBundle(NULL);

  // Check that ResourceBundle::LocaleDataPakExists returns the correct results.
  EXPECT_TRUE(resource_bundle->LocaleDataPakExists("en-US"));
  EXPECT_FALSE(resource_bundle->LocaleDataPakExists("not_a_real_locale"));
}

class ResourceBundleImageTest : public ResourceBundleTest {
 public:
  ResourceBundleImageTest() {}

  virtual ~ResourceBundleImageTest() {
  }

  virtual void SetUp() OVERRIDE {
    // Create a temporary directory to write test resource bundles to.
    ASSERT_TRUE(dir_.CreateUniqueTempDir());
  }

  // Returns resource bundle which uses an empty data pak for locale data.
  ui::ResourceBundle* CreateResourceBundleWithEmptyLocalePak() {
    // Write an empty data pak for locale data.
    const base::FilePath& locale_path = dir_path().Append(
        FILE_PATH_LITERAL("locale.pak"));
    EXPECT_EQ(base::WriteFile(locale_path, kEmptyPakContents,
                                   kEmptyPakSize),
              static_cast<int>(kEmptyPakSize));

    ui::ResourceBundle* resource_bundle = CreateResourceBundle(NULL);

    // Load the empty locale data pak.
    resource_bundle->LoadTestResources(base::FilePath(), locale_path);
    return resource_bundle;
  }

  // Returns the path of temporary directory to write test data packs into.
  const base::FilePath& dir_path() { return dir_.path(); }

 private:
  scoped_ptr<DataPack> locale_pack_;
  base::ScopedTempDir dir_;

  DISALLOW_COPY_AND_ASSIGN(ResourceBundleImageTest);
};

// Verify that we don't crash when trying to load a resource that is not found.
// In some cases, we fail to mmap resources.pak, but try to keep going anyway.
TEST_F(ResourceBundleImageTest, LoadDataResourceBytes) {
  base::FilePath data_path = dir_path().Append(FILE_PATH_LITERAL("sample.pak"));

  // Dump contents into the pak files.
  ASSERT_EQ(base::WriteFile(data_path, kEmptyPakContents,
      kEmptyPakSize), static_cast<int>(kEmptyPakSize));

  // Create a resource bundle from the file.
  ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
  resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);

  const int kUnfoundResourceId = 10000;
  EXPECT_EQ(NULL, resource_bundle->LoadDataResourceBytes(
      kUnfoundResourceId));

  // Give a .pak file that doesn't exist so we will fail to load it.
  resource_bundle->AddDataPackFromPath(
      base::FilePath(FILE_PATH_LITERAL("non-existant-file.pak")),
      ui::SCALE_FACTOR_NONE);
  EXPECT_EQ(NULL, resource_bundle->LoadDataResourceBytes(
      kUnfoundResourceId));
}

TEST_F(ResourceBundleImageTest, GetRawDataResource) {
  base::FilePath data_path = dir_path().Append(FILE_PATH_LITERAL("sample.pak"));
  base::FilePath data_2x_path =
      dir_path().Append(FILE_PATH_LITERAL("sample_2x.pak"));

  // Dump contents into the pak files.
  ASSERT_EQ(base::WriteFile(data_path, kSamplePakContents,
      kSamplePakSize), static_cast<int>(kSamplePakSize));
  ASSERT_EQ(base::WriteFile(data_2x_path, kSamplePakContents2x,
      kSamplePakSize2x), static_cast<int>(kSamplePakSize2x));

  // Load the regular and 2x pak files.
  ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
  resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
  resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);

  // Resource ID 4 exists in both 1x and 2x paks, so we expect a different
  // result when requesting the 2x scale.
  EXPECT_EQ("this is id 4", resource_bundle->GetRawDataResourceForScale(4,
      SCALE_FACTOR_100P));
  EXPECT_EQ("this is id 4 2x", resource_bundle->GetRawDataResourceForScale(4,
      SCALE_FACTOR_200P));

  // Resource ID 6 only exists in the 1x pak so we expect the same resource
  // for both scale factor requests.
  EXPECT_EQ("this is id 6", resource_bundle->GetRawDataResourceForScale(6,
      SCALE_FACTOR_100P));
  EXPECT_EQ("this is id 6", resource_bundle->GetRawDataResourceForScale(6,
      SCALE_FACTOR_200P));
}

// Test requesting image reps at various scale factors from the image returned
// via ResourceBundle::GetImageNamed().
TEST_F(ResourceBundleImageTest, GetImageNamed) {
#if defined(OS_WIN)
  gfx::ForceHighDPISupportForTesting(2.0);
#endif
  std::vector<ScaleFactor> supported_factors;
  supported_factors.push_back(SCALE_FACTOR_100P);
  supported_factors.push_back(SCALE_FACTOR_200P);
  test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
  base::FilePath data_1x_path = dir_path().AppendASCII("sample_1x.pak");
  base::FilePath data_2x_path = dir_path().AppendASCII("sample_2x.pak");

  // Create the pak files.
  CreateDataPackWithSingleBitmap(data_1x_path, 10, base::StringPiece());
  CreateDataPackWithSingleBitmap(data_2x_path, 20, base::StringPiece());

  // Load the regular and 2x pak files.
  ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
  resource_bundle->AddDataPackFromPath(data_1x_path, SCALE_FACTOR_100P);
  resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);

  EXPECT_EQ(SCALE_FACTOR_200P, resource_bundle->GetMaxScaleFactor());

  gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);

#if defined(OS_CHROMEOS) || defined(OS_WIN)
  // ChromeOS/Windows load highest scale factor first.
  EXPECT_EQ(ui::SCALE_FACTOR_200P,
            GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
#else
  EXPECT_EQ(ui::SCALE_FACTOR_100P,
            GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
#endif

  // Resource ID 3 exists in both 1x and 2x paks. Image reps should be
  // available for both scale factors in |image_skia|.
  gfx::ImageSkiaRep image_rep =
      image_skia->GetRepresentation(
      GetScaleForScaleFactor(ui::SCALE_FACTOR_100P));
  EXPECT_EQ(ui::SCALE_FACTOR_100P, GetSupportedScaleFactor(image_rep.scale()));
  image_rep =
      image_skia->GetRepresentation(
      GetScaleForScaleFactor(ui::SCALE_FACTOR_200P));
  EXPECT_EQ(ui::SCALE_FACTOR_200P, GetSupportedScaleFactor(image_rep.scale()));

  // The 1.4x pack was not loaded. Requesting the 1.4x resource should return
  // either the 1x or the 2x resource.
  image_rep = image_skia->GetRepresentation(
      ui::GetScaleForScaleFactor(ui::SCALE_FACTOR_140P));
  ui::ScaleFactor scale_factor = GetSupportedScaleFactor(image_rep.scale());
  EXPECT_TRUE(scale_factor == ui::SCALE_FACTOR_100P ||
              scale_factor == ui::SCALE_FACTOR_200P);

  // ImageSkia scales image if the one for the requested scale factor is not
  // available.
  EXPECT_EQ(1.4f, image_skia->GetRepresentation(1.4f).scale());
}

// Test that GetImageNamed() behaves properly for images which GRIT has
// annotated as having fallen back to 1x.
TEST_F(ResourceBundleImageTest, GetImageNamedFallback1x) {
  std::vector<ScaleFactor> supported_factors;
  supported_factors.push_back(SCALE_FACTOR_100P);
  supported_factors.push_back(SCALE_FACTOR_200P);
  test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
  base::FilePath data_path = dir_path().AppendASCII("sample.pak");
  base::FilePath data_2x_path = dir_path().AppendASCII("sample_2x.pak");

  // Create the pak files.
  CreateDataPackWithSingleBitmap(data_path, 10, base::StringPiece());
  // 2x data pack bitmap has custom chunk to indicate that the 2x bitmap is not
  // available and that GRIT fell back to 1x.
  CreateDataPackWithSingleBitmap(data_2x_path, 10, base::StringPiece(
      reinterpret_cast<const char*>(kPngScaleChunk),
      arraysize(kPngScaleChunk)));

  // Load the regular and 2x pak files.
  ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
  resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
  resource_bundle->AddDataPackFromPath(data_2x_path, SCALE_FACTOR_200P);

  gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);

  // The image rep for 2x should be available. It should be resized to the
  // proper 2x size.
  gfx::ImageSkiaRep image_rep =
      image_skia->GetRepresentation(GetScaleForScaleFactor(
      ui::SCALE_FACTOR_200P));
  EXPECT_EQ(ui::SCALE_FACTOR_200P, GetSupportedScaleFactor(image_rep.scale()));
  EXPECT_EQ(20, image_rep.pixel_width());
  EXPECT_EQ(20, image_rep.pixel_height());
}

#if defined(OS_WIN)
// Tests GetImageNamed() behaves properly when the size of a scaled image
// requires rounding as a result of using a non-integer scale factor.
// Scale factors of 140 and 1805 are Windows specific.
TEST_F(ResourceBundleImageTest, GetImageNamedFallback1xRounding) {
  std::vector<ScaleFactor> supported_factors;
  supported_factors.push_back(SCALE_FACTOR_100P);
  supported_factors.push_back(SCALE_FACTOR_140P);
  supported_factors.push_back(SCALE_FACTOR_180P);
  test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);

  base::FilePath data_path = dir_path().AppendASCII("sample.pak");
  base::FilePath data_140P_path = dir_path().AppendASCII("sample_140P.pak");
  base::FilePath data_180P_path = dir_path().AppendASCII("sample_180P.pak");

  CreateDataPackWithSingleBitmap(data_path, 8, base::StringPiece());
  // Mark 140% and 180% images as requiring 1x fallback.
  CreateDataPackWithSingleBitmap(data_140P_path, 8, base::StringPiece(
    reinterpret_cast<const char*>(kPngScaleChunk),
    arraysize(kPngScaleChunk)));
  CreateDataPackWithSingleBitmap(data_180P_path, 8, base::StringPiece(
    reinterpret_cast<const char*>(kPngScaleChunk),
    arraysize(kPngScaleChunk)));

  ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
  resource_bundle->AddDataPackFromPath(data_path, SCALE_FACTOR_100P);
  resource_bundle->AddDataPackFromPath(data_140P_path, SCALE_FACTOR_140P);
  resource_bundle->AddDataPackFromPath(data_180P_path, SCALE_FACTOR_180P);

  // Non-integer dimensions should be rounded up.
  gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
  gfx::ImageSkiaRep image_rep =
    image_skia->GetRepresentation(
    GetScaleForScaleFactor(ui::SCALE_FACTOR_140P));
  EXPECT_EQ(12, image_rep.pixel_width());
  image_rep = image_skia->GetRepresentation(
    GetScaleForScaleFactor(ui::SCALE_FACTOR_180P));
  EXPECT_EQ(15, image_rep.pixel_width());
}
#endif

#if defined(OS_IOS)
// Fails on devices that have non-100P scaling. See crbug.com/298406
#define MAYBE_FallbackToNone DISABLED_FallbackToNone
#else
#define MAYBE_FallbackToNone FallbackToNone
#endif
TEST_F(ResourceBundleImageTest, MAYBE_FallbackToNone) {
  base::FilePath data_default_path = dir_path().AppendASCII("sample.pak");

  // Create the pak files.
  CreateDataPackWithSingleBitmap(data_default_path, 10, base::StringPiece());

    // Load the regular pak files only.
  ResourceBundle* resource_bundle = CreateResourceBundleWithEmptyLocalePak();
  resource_bundle->AddDataPackFromPath(data_default_path, SCALE_FACTOR_NONE);

  gfx::ImageSkia* image_skia = resource_bundle->GetImageSkiaNamed(3);
  EXPECT_EQ(1u, image_skia->image_reps().size());
  EXPECT_TRUE(image_skia->image_reps()[0].unscaled());
  EXPECT_EQ(ui::SCALE_FACTOR_100P,
            GetSupportedScaleFactor(image_skia->image_reps()[0].scale()));
}

}  // namespace ui
