This source file includes following definitions.
- GetImageForScale
 
- GetImageForScale
 
- GetImageForScale
 
- can_modify_
 
- Run
 
- StartAndJoin
 
- can_read
 
- can_modify
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
- TEST
 
#include "ui/gfx/image/image_skia.h"
#include "base/logging.h"
#include "base/threading/simple_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/size.h"
#if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON))
#define ENABLE_NON_THREAD_SAFE 1
#else
#define ENABLE_NON_THREAD_SAFE 0
#endif
namespace gfx {
namespace {
class FixedSource : public ImageSkiaSource {
 public:
  FixedSource(const ImageSkiaRep& image) : image_(image) {}
  virtual ~FixedSource() {
  }
  virtual ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
    return image_;
  }
 private:
  ImageSkiaRep image_;
  DISALLOW_COPY_AND_ASSIGN(FixedSource);
};
class DynamicSource : public ImageSkiaSource {
 public:
  DynamicSource(const gfx::Size& size) : size_(size) {}
  virtual ~DynamicSource() {
  }
  virtual ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
    return gfx::ImageSkiaRep(size_, scale);
  }
 private:
  gfx::Size size_;
  DISALLOW_COPY_AND_ASSIGN(DynamicSource);
};
class NullSource: public ImageSkiaSource {
 public:
  NullSource() {
  }
  virtual ~NullSource() {
  }
  virtual ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
    return gfx::ImageSkiaRep();
  }
 private:
  DISALLOW_COPY_AND_ASSIGN(NullSource);
};
}  
namespace test {
class TestOnThread : public base::SimpleThread {
 public:
  explicit TestOnThread(ImageSkia* image_skia)
      : SimpleThread("image_skia_on_thread"),
        image_skia_(image_skia),
        can_read_(false),
        can_modify_(false) {
  }
  virtual void Run() OVERRIDE {
    can_read_ = image_skia_->CanRead();
    can_modify_ = image_skia_->CanModify();
    if (can_read_)
      image_skia_->image_reps();
  }
  void StartAndJoin() {
    Start();
    Join();
  }
  bool can_read() const { return can_read_; }
  bool can_modify() const { return can_modify_; }
 private:
  ImageSkia* image_skia_;
  bool can_read_;
  bool can_modify_;
  DISALLOW_COPY_AND_ASSIGN(TestOnThread);
};
}  
TEST(ImageSkiaTest, FixedSource) {
  ImageSkiaRep image(Size(100, 200), 1.0f);
  ImageSkia image_skia(new FixedSource(image), Size(100, 200));
  EXPECT_EQ(0U, image_skia.image_reps().size());
  const ImageSkiaRep& result_100p = image_skia.GetRepresentation(1.0f);
  EXPECT_EQ(100, result_100p.GetWidth());
  EXPECT_EQ(200, result_100p.GetHeight());
  EXPECT_EQ(1.0f, result_100p.scale());
  EXPECT_EQ(1U, image_skia.image_reps().size());
  const ImageSkiaRep& result_200p = image_skia.GetRepresentation(2.0f);
  EXPECT_EQ(100, result_200p.GetWidth());
  EXPECT_EQ(200, result_200p.GetHeight());
  EXPECT_EQ(100, result_200p.pixel_width());
  EXPECT_EQ(200, result_200p.pixel_height());
  EXPECT_EQ(1.0f, result_200p.scale());
  EXPECT_EQ(1U, image_skia.image_reps().size());
  
  
  image_skia.GetRepresentation(1.0f);
  image_skia.GetRepresentation(2.0f);
  EXPECT_EQ(1U, image_skia.image_reps().size());
}
TEST(ImageSkiaTest, DynamicSource) {
  ImageSkia image_skia(new DynamicSource(Size(100, 200)), Size(100, 200));
  EXPECT_EQ(0U, image_skia.image_reps().size());
  const ImageSkiaRep& result_100p = image_skia.GetRepresentation(1.0f);
  EXPECT_EQ(100, result_100p.GetWidth());
  EXPECT_EQ(200, result_100p.GetHeight());
  EXPECT_EQ(1.0f, result_100p.scale());
  EXPECT_EQ(1U, image_skia.image_reps().size());
  const ImageSkiaRep& result_200p =
      image_skia.GetRepresentation(2.0f);
  EXPECT_EQ(100, result_200p.GetWidth());
  EXPECT_EQ(200, result_200p.GetHeight());
  EXPECT_EQ(200, result_200p.pixel_width());
  EXPECT_EQ(400, result_200p.pixel_height());
  EXPECT_EQ(2.0f, result_200p.scale());
  EXPECT_EQ(2U, image_skia.image_reps().size());
  
  
  image_skia.GetRepresentation(1.0f);
  EXPECT_EQ(2U, image_skia.image_reps().size());
  image_skia.GetRepresentation(2.0f);
  EXPECT_EQ(2U, image_skia.image_reps().size());
}
TEST(ImageSkiaTest, ManyRepsPerScaleFactor) {
  const int kSmallIcon1x = 16;
  const int kSmallIcon2x = 32;
  const int kLargeIcon1x = 32;
  ImageSkia image(new NullSource(), gfx::Size(kSmallIcon1x, kSmallIcon1x));
  
  
  
  image.GetRepresentation(1.0f);
  image.GetRepresentation(2.0f);
  
  image.AddRepresentation(ImageSkiaRep(
      gfx::Size(kSmallIcon1x, kSmallIcon1x), 1.0f));
  image.AddRepresentation(ImageSkiaRep(
      gfx::Size(kSmallIcon2x, kSmallIcon2x), 2.0f));
  image.AddRepresentation(ImageSkiaRep(
      gfx::Size(kLargeIcon1x, kLargeIcon1x), 1.0f));
  std::vector<ImageSkiaRep> image_reps = image.image_reps();
  EXPECT_EQ(3u, image_reps.size());
  int num_1x = 0;
  int num_2x = 0;
  for (size_t i = 0; i < image_reps.size(); ++i) {
    if (image_reps[i].scale() == 1.0f)
      num_1x++;
    else if (image_reps[i].scale() == 2.0f)
      num_2x++;
  }
  EXPECT_EQ(2, num_1x);
  EXPECT_EQ(1, num_2x);
}
TEST(ImageSkiaTest, GetBitmap) {
  ImageSkia image_skia(new DynamicSource(Size(100, 200)), Size(100, 200));
  const SkBitmap* bitmap = image_skia.bitmap();
  EXPECT_NE(static_cast<SkBitmap*>(NULL), bitmap);
  EXPECT_FALSE(bitmap->isNull());
}
TEST(ImageSkiaTest, GetBitmapFromEmpty) {
  
  
  ImageSkia empty_image(ImageSkiaRep(Size(100, 200), 1.0f));
  ImageSkia empty_image_copy(empty_image);
  empty_image.RemoveRepresentation(1.0f);
  
  
  const SkBitmap* bitmap = empty_image_copy.bitmap();
  ASSERT_NE(static_cast<SkBitmap*>(NULL), bitmap);
  EXPECT_TRUE(bitmap->isNull());
  EXPECT_TRUE(bitmap->empty());
}
TEST(ImageSkiaTest, BackedBySameObjectAs) {
  
  ImageSkia image;
  ImageSkia unrelated;
  EXPECT_TRUE(image.BackedBySameObjectAs(unrelated));
  image.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
                                            1.0f));
  ImageSkia copy = image;
  copy.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
                                           2.0f));
  unrelated.AddRepresentation(gfx::ImageSkiaRep(gfx::Size(10, 10),
                                                1.0f));
  EXPECT_TRUE(image.BackedBySameObjectAs(copy));
  EXPECT_FALSE(image.BackedBySameObjectAs(unrelated));
  EXPECT_FALSE(copy.BackedBySameObjectAs(unrelated));
}
#if ENABLE_NON_THREAD_SAFE
TEST(ImageSkiaTest, EmptyOnThreadTest) {
  ImageSkia empty;
  test::TestOnThread empty_on_thread(&empty);
  empty_on_thread.Start();
  empty_on_thread.Join();
  EXPECT_TRUE(empty_on_thread.can_read());
  EXPECT_TRUE(empty_on_thread.can_modify());
}
TEST(ImageSkiaTest, StaticOnThreadTest) {
  ImageSkia image(ImageSkiaRep(Size(100, 200), 1.0f));
  EXPECT_FALSE(image.IsThreadSafe());
  test::TestOnThread image_on_thread(&image);
  
  
  image_on_thread.StartAndJoin();
  EXPECT_TRUE(image_on_thread.can_read());
  EXPECT_TRUE(image_on_thread.can_modify());
  EXPECT_FALSE(image.CanRead());
  EXPECT_FALSE(image.CanModify());
  image.DetachStorageFromThread();
  
  
  image.image_reps();
  test::TestOnThread image_on_thread2(&image);
  image_on_thread2.StartAndJoin();
  EXPECT_FALSE(image_on_thread2.can_read());
  EXPECT_FALSE(image_on_thread2.can_modify());
  EXPECT_TRUE(image.CanRead());
  EXPECT_TRUE(image.CanModify());
  image.DetachStorageFromThread();
  scoped_ptr<ImageSkia> deep_copy(image.DeepCopy());
  EXPECT_FALSE(deep_copy->IsThreadSafe());
  test::TestOnThread deepcopy_on_thread(deep_copy.get());
  deepcopy_on_thread.StartAndJoin();
  EXPECT_TRUE(deepcopy_on_thread.can_read());
  EXPECT_TRUE(deepcopy_on_thread.can_modify());
  EXPECT_FALSE(deep_copy->CanRead());
  EXPECT_FALSE(deep_copy->CanModify());
  scoped_ptr<ImageSkia> deep_copy2(image.DeepCopy());
  EXPECT_EQ(1U, deep_copy2->image_reps().size());
  
  
  deep_copy2->image_reps();
  EXPECT_FALSE(deep_copy2->IsThreadSafe());
  test::TestOnThread deepcopy2_on_thread(deep_copy2.get());
  deepcopy2_on_thread.StartAndJoin();
  EXPECT_FALSE(deepcopy2_on_thread.can_read());
  EXPECT_FALSE(deepcopy2_on_thread.can_modify());
  EXPECT_TRUE(deep_copy2->CanRead());
  EXPECT_TRUE(deep_copy2->CanModify());
  image.DetachStorageFromThread();
  image.SetReadOnly();
  
  EXPECT_TRUE(image.IsThreadSafe());
  test::TestOnThread readonly_on_thread(&image);
  readonly_on_thread.StartAndJoin();
  EXPECT_TRUE(readonly_on_thread.can_read());
  EXPECT_FALSE(readonly_on_thread.can_modify());
  EXPECT_TRUE(image.CanRead());
  EXPECT_FALSE(image.CanModify());
  image.DetachStorageFromThread();
  image.MakeThreadSafe();
  EXPECT_TRUE(image.IsThreadSafe());
  test::TestOnThread threadsafe_on_thread(&image);
  threadsafe_on_thread.StartAndJoin();
  EXPECT_TRUE(threadsafe_on_thread.can_read());
  EXPECT_FALSE(threadsafe_on_thread.can_modify());
  EXPECT_TRUE(image.CanRead());
  EXPECT_FALSE(image.CanModify());
}
TEST(ImageSkiaTest, SourceOnThreadTest) {
  ImageSkia image(new DynamicSource(Size(100, 200)), Size(100, 200));
  EXPECT_FALSE(image.IsThreadSafe());
  test::TestOnThread image_on_thread(&image);
  image_on_thread.StartAndJoin();
  
  
  EXPECT_TRUE(image_on_thread.can_read());
  EXPECT_TRUE(image_on_thread.can_modify());
  EXPECT_FALSE(image.CanRead());
  EXPECT_FALSE(image.CanModify());
  image.DetachStorageFromThread();
  
  
  image.image_reps();
  test::TestOnThread image_on_thread2(&image);
  image_on_thread2.StartAndJoin();
  EXPECT_FALSE(image_on_thread2.can_read());
  EXPECT_FALSE(image_on_thread2.can_modify());
  EXPECT_TRUE(image.CanRead());
  EXPECT_TRUE(image.CanModify());
  image.DetachStorageFromThread();
  image.SetReadOnly();
  EXPECT_FALSE(image.IsThreadSafe());
  test::TestOnThread readonly_on_thread(&image);
  readonly_on_thread.StartAndJoin();
  EXPECT_TRUE(readonly_on_thread.can_read());
  EXPECT_FALSE(readonly_on_thread.can_modify());
  EXPECT_FALSE(image.CanRead());
  EXPECT_FALSE(image.CanModify());
  image.DetachStorageFromThread();
  image.MakeThreadSafe();
  EXPECT_TRUE(image.IsThreadSafe());
  
  EXPECT_EQ(ImageSkia::GetSupportedScales().size(),
           image.image_reps().size());
  test::TestOnThread threadsafe_on_thread(&image);
  threadsafe_on_thread.StartAndJoin();
  EXPECT_TRUE(threadsafe_on_thread.can_read());
  EXPECT_FALSE(threadsafe_on_thread.can_modify());
  EXPECT_TRUE(image.CanRead());
  EXPECT_FALSE(image.CanModify());
}
#endif  
#undef ENABLE_NON_THREAD_SAFE
}