Home | History | Annotate | Download | only in extensions
      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.
      4 
      5 #include "chrome/browser/extensions/extension_icon_image.h"
      6 
      7 #include "base/json/json_file_value_serializer.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/path_service.h"
     10 #include "chrome/browser/extensions/image_loader.h"
     11 #include "chrome/common/chrome_paths.h"
     12 #include "chrome/common/extensions/extension_constants.h"
     13 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
     14 #include "chrome/test/base/testing_profile.h"
     15 #include "content/public/test/test_browser_thread.h"
     16 #include "extensions/common/extension.h"
     17 #include "extensions/common/manifest.h"
     18 #include "grit/theme_resources.h"
     19 #include "skia/ext/image_operations.h"
     20 #include "testing/gtest/include/gtest/gtest.h"
     21 #include "ui/base/resource/resource_bundle.h"
     22 #include "ui/gfx/image/image_skia_source.h"
     23 #include "ui/gfx/skia_util.h"
     24 
     25 using content::BrowserThread;
     26 using extensions::Extension;
     27 using extensions::IconImage;
     28 using extensions::Manifest;
     29 
     30 namespace {
     31 
     32 SkBitmap CreateBlankBitmapForScale(int size_dip, ui::ScaleFactor scale_factor) {
     33   SkBitmap bitmap;
     34   const float scale = ui::GetImageScale(scale_factor);
     35   bitmap.setConfig(SkBitmap::kARGB_8888_Config,
     36                    static_cast<int>(size_dip * scale),
     37                    static_cast<int>(size_dip * scale));
     38   bitmap.allocPixels();
     39   bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0));
     40   return bitmap;
     41 }
     42 
     43 SkBitmap EnsureBitmapSize(const SkBitmap& original, int size) {
     44   if (original.width() == size && original.height() == size)
     45     return original;
     46 
     47   SkBitmap resized = skia::ImageOperations::Resize(
     48       original, skia::ImageOperations::RESIZE_LANCZOS3, size, size);
     49   return resized;
     50 }
     51 
     52 // Used to test behavior including images defined by an image skia source.
     53 // |GetImageForScale| simply returns image representation from the image given
     54 // in the ctor.
     55 class MockImageSkiaSource : public gfx::ImageSkiaSource {
     56  public:
     57   explicit MockImageSkiaSource(const gfx::ImageSkia& image)
     58       : image_(image) {
     59   }
     60   virtual ~MockImageSkiaSource() {}
     61 
     62   virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE {
     63     return image_.GetRepresentation(scale);
     64   }
     65 
     66  private:
     67   gfx::ImageSkia image_;
     68 };
     69 
     70 // Helper class for synchronously loading extension image resource.
     71 class TestImageLoader {
     72  public:
     73   explicit TestImageLoader(const Extension* extension)
     74       : extension_(extension),
     75         waiting_(false),
     76         image_loaded_(false) {
     77   }
     78   virtual ~TestImageLoader() {}
     79 
     80   void OnImageLoaded(const gfx::Image& image) {
     81     image_ = image;
     82     image_loaded_ = true;
     83     if (waiting_)
     84       base::MessageLoop::current()->Quit();
     85   }
     86 
     87   SkBitmap LoadBitmap(const std::string& path,
     88                       int size) {
     89     image_loaded_ = false;
     90 
     91     image_loader_.LoadImageAsync(
     92         extension_, extension_->GetResource(path), gfx::Size(size, size),
     93         base::Bind(&TestImageLoader::OnImageLoaded,
     94                    base::Unretained(this)));
     95 
     96     // If |image_| still hasn't been loaded (i.e. it is being loaded
     97     // asynchronously), wait for it.
     98     if (!image_loaded_) {
     99       waiting_ = true;
    100       base::MessageLoop::current()->Run();
    101       waiting_ = false;
    102     }
    103 
    104     EXPECT_TRUE(image_loaded_);
    105 
    106     return image_.IsEmpty() ? SkBitmap() : *image_.ToSkBitmap();
    107   }
    108 
    109  private:
    110   const Extension* extension_;
    111   bool waiting_;
    112   bool image_loaded_;
    113   gfx::Image image_;
    114   extensions::ImageLoader image_loader_;
    115 
    116   DISALLOW_COPY_AND_ASSIGN(TestImageLoader);
    117 };
    118 
    119 class ExtensionIconImageTest : public testing::Test,
    120                                public IconImage::Observer {
    121  public:
    122   ExtensionIconImageTest()
    123       : image_loaded_count_(0),
    124         quit_in_image_loaded_(false),
    125         ui_thread_(BrowserThread::UI, &ui_loop_),
    126         file_thread_(BrowserThread::FILE),
    127         io_thread_(BrowserThread::IO) {
    128   }
    129 
    130   virtual ~ExtensionIconImageTest() {}
    131 
    132   void WaitForImageLoad() {
    133     quit_in_image_loaded_ = true;
    134     base::MessageLoop::current()->Run();
    135     quit_in_image_loaded_ = false;
    136   }
    137 
    138   int ImageLoadedCount() {
    139     int result = image_loaded_count_;
    140     image_loaded_count_ = 0;
    141     return result;
    142   }
    143 
    144   scoped_refptr<Extension> CreateExtension(const char* name,
    145                                            Manifest::Location location) {
    146     // Create and load an extension.
    147     base::FilePath test_file;
    148     if (!PathService::Get(chrome::DIR_TEST_DATA, &test_file)) {
    149       EXPECT_FALSE(true);
    150       return NULL;
    151     }
    152     test_file = test_file.AppendASCII("extensions").AppendASCII(name);
    153     int error_code = 0;
    154     std::string error;
    155     JSONFileValueSerializer serializer(test_file.AppendASCII("app.json"));
    156     scoped_ptr<DictionaryValue> valid_value(
    157         static_cast<DictionaryValue*>(serializer.Deserialize(&error_code,
    158                                                              &error)));
    159     EXPECT_EQ(0, error_code) << error;
    160     if (error_code != 0)
    161       return NULL;
    162 
    163     EXPECT_TRUE(valid_value.get());
    164     if (!valid_value)
    165       return NULL;
    166 
    167     return Extension::Create(test_file, location, *valid_value,
    168                              Extension::NO_FLAGS, &error);
    169   }
    170 
    171   // testing::Test overrides:
    172   virtual void SetUp() OVERRIDE {
    173     file_thread_.Start();
    174     io_thread_.Start();
    175   }
    176 
    177   // IconImage::Delegate overrides:
    178   virtual void OnExtensionIconImageChanged(IconImage* image) OVERRIDE {
    179     image_loaded_count_++;
    180     if (quit_in_image_loaded_)
    181       base::MessageLoop::current()->Quit();
    182   }
    183 
    184   gfx::ImageSkia GetDefaultIcon() {
    185     return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
    186         IDR_EXTENSIONS_FAVICON);
    187   }
    188 
    189   // Loads an image to be used in test from the extension.
    190   // The image will be loaded from the relative path |path|.
    191   SkBitmap GetTestBitmap(const Extension* extension,
    192                          const std::string& path,
    193                          int size) {
    194     TestImageLoader image_loader(extension);
    195     return image_loader.LoadBitmap(path, size);
    196   }
    197 
    198  private:
    199   int image_loaded_count_;
    200   bool quit_in_image_loaded_;
    201   base::MessageLoop ui_loop_;
    202   content::TestBrowserThread ui_thread_;
    203   content::TestBrowserThread file_thread_;
    204   content::TestBrowserThread io_thread_;
    205 
    206   DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest);
    207 };
    208 
    209 }  // namespace
    210 
    211 TEST_F(ExtensionIconImageTest, Basic) {
    212   std::vector<ui::ScaleFactor> supported_factors;
    213   supported_factors.push_back(ui::SCALE_FACTOR_100P);
    214   supported_factors.push_back(ui::SCALE_FACTOR_200P);
    215   ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
    216   scoped_ptr<Profile> profile(new TestingProfile());
    217   scoped_refptr<Extension> extension(CreateExtension(
    218       "extension_icon_image", Manifest::INVALID_LOCATION));
    219   ASSERT_TRUE(extension.get() != NULL);
    220 
    221   gfx::ImageSkia default_icon = GetDefaultIcon();
    222 
    223   // Load images we expect to find as representations in icon_image, so we
    224   // can later use them to validate icon_image.
    225   SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16);
    226   ASSERT_FALSE(bitmap_16.empty());
    227 
    228   // There is no image of size 32 defined in the extension manifest, so we
    229   // should expect manifest image of size 48 resized to size 32.
    230   SkBitmap bitmap_48_resized_to_32 =
    231       GetTestBitmap(extension.get(), "48.png", 32);
    232   ASSERT_FALSE(bitmap_48_resized_to_32.empty());
    233 
    234   IconImage image(profile.get(),
    235                   extension.get(),
    236                   extensions::IconsInfo::GetIcons(extension.get()),
    237                   16,
    238                   default_icon,
    239                   this);
    240 
    241   // No representations in |image_| yet.
    242   gfx::ImageSkia::ImageSkiaReps image_reps = image.image_skia().image_reps();
    243   ASSERT_EQ(0u, image_reps.size());
    244 
    245   // Gets representation for a scale factor.
    246   gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f);
    247 
    248   // Before the image representation is loaded, image should contain blank
    249   // image representation.
    250   EXPECT_TRUE(gfx::BitmapsAreEqual(
    251       representation.sk_bitmap(),
    252       CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_100P)));
    253 
    254   WaitForImageLoad();
    255   EXPECT_EQ(1, ImageLoadedCount());
    256   ASSERT_EQ(1u, image.image_skia().image_reps().size());
    257 
    258   representation = image.image_skia().GetRepresentation(1.0f);
    259 
    260   // We should get the right representation now.
    261   EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), bitmap_16));
    262   EXPECT_EQ(16, representation.pixel_width());
    263 
    264   // Gets representation for an additional scale factor.
    265   representation = image.image_skia().GetRepresentation(2.0f);
    266 
    267   EXPECT_TRUE(gfx::BitmapsAreEqual(
    268       representation.sk_bitmap(),
    269       CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_200P)));
    270 
    271   WaitForImageLoad();
    272   EXPECT_EQ(1, ImageLoadedCount());
    273   ASSERT_EQ(2u, image.image_skia().image_reps().size());
    274 
    275   representation = image.image_skia().GetRepresentation(2.0f);
    276 
    277   // Image should have been resized.
    278   EXPECT_EQ(32, representation.pixel_width());
    279   EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(),
    280                                    bitmap_48_resized_to_32));
    281 }
    282 
    283 // There is no resource with either exact or bigger size, but there is a smaller
    284 // resource.
    285 TEST_F(ExtensionIconImageTest, FallbackToSmallerWhenNoBigger) {
    286   std::vector<ui::ScaleFactor> supported_factors;
    287   supported_factors.push_back(ui::SCALE_FACTOR_100P);
    288   supported_factors.push_back(ui::SCALE_FACTOR_200P);
    289   ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors);
    290   scoped_ptr<Profile> profile(new TestingProfile());
    291   scoped_refptr<Extension> extension(CreateExtension(
    292       "extension_icon_image", Manifest::INVALID_LOCATION));
    293   ASSERT_TRUE(extension.get() != NULL);
    294 
    295   gfx::ImageSkia default_icon = GetDefaultIcon();
    296 
    297   // Load images we expect to find as representations in icon_image, so we
    298   // can later use them to validate icon_image.
    299   SkBitmap bitmap_48 = GetTestBitmap(extension.get(), "48.png", 48);
    300   ASSERT_FALSE(bitmap_48.empty());
    301 
    302   IconImage image(profile.get(),
    303                   extension.get(),
    304                   extensions::IconsInfo::GetIcons(extension.get()),
    305                   32,
    306                   default_icon,
    307                   this);
    308 
    309   gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(2.0f);
    310 
    311   WaitForImageLoad();
    312   EXPECT_EQ(1, ImageLoadedCount());
    313   ASSERT_EQ(1u, image.image_skia().image_reps().size());
    314 
    315   representation = image.image_skia().GetRepresentation(2.0f);
    316 
    317   // We should have loaded the biggest smaller resource resized to the actual
    318   // size.
    319   EXPECT_EQ(2.0f, representation.scale());
    320   EXPECT_EQ(64, representation.pixel_width());
    321   EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(),
    322                                    EnsureBitmapSize(bitmap_48, 64)));
    323 }
    324 
    325 // There is no resource with exact size, but there is a smaller and a bigger
    326 // one. Requested size is smaller than 32 though, so the smaller resource should
    327 // be loaded.
    328 TEST_F(ExtensionIconImageTest, FallbackToSmaller) {
    329   scoped_ptr<Profile> profile(new TestingProfile());
    330   scoped_refptr<Extension> extension(CreateExtension(
    331       "extension_icon_image", Manifest::INVALID_LOCATION));
    332   ASSERT_TRUE(extension.get() != NULL);
    333 
    334   gfx::ImageSkia default_icon = GetDefaultIcon();
    335 
    336   // Load images we expect to find as representations in icon_image, so we
    337   // can later use them to validate icon_image.
    338   SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16);
    339   ASSERT_FALSE(bitmap_16.empty());
    340 
    341   IconImage image(profile.get(),
    342                   extension.get(),
    343                   extensions::IconsInfo::GetIcons(extension.get()),
    344                   17,
    345                   default_icon,
    346                   this);
    347 
    348   gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f);
    349 
    350   WaitForImageLoad();
    351   EXPECT_EQ(1, ImageLoadedCount());
    352   ASSERT_EQ(1u, image.image_skia().image_reps().size());
    353 
    354   representation = image.image_skia().GetRepresentation(1.0f);
    355 
    356   // We should have loaded smaller (resized) resource.
    357   EXPECT_EQ(1.0f, representation.scale());
    358   EXPECT_EQ(17, representation.pixel_width());
    359   EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(),
    360                                    EnsureBitmapSize(bitmap_16, 17)));
    361 }
    362 
    363 // If resource set is empty, |GetRepresentation| should synchronously return
    364 // default icon, without notifying observer of image change.
    365 TEST_F(ExtensionIconImageTest, NoResources) {
    366   scoped_ptr<Profile> profile(new TestingProfile());
    367   scoped_refptr<Extension> extension(CreateExtension(
    368       "extension_icon_image", Manifest::INVALID_LOCATION));
    369   ASSERT_TRUE(extension.get() != NULL);
    370 
    371   ExtensionIconSet empty_icon_set;
    372   gfx::ImageSkia default_icon = GetDefaultIcon();
    373 
    374   const int kRequestedSize = 24;
    375   IconImage image(profile.get(),
    376                   extension.get(),
    377                   empty_icon_set,
    378                   kRequestedSize,
    379                   default_icon,
    380                   this);
    381 
    382   gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f);
    383   EXPECT_TRUE(gfx::BitmapsAreEqual(
    384       representation.sk_bitmap(),
    385       EnsureBitmapSize(
    386           default_icon.GetRepresentation(1.0f).sk_bitmap(),
    387           kRequestedSize)));
    388 
    389   EXPECT_EQ(0, ImageLoadedCount());
    390   // We should have a default icon representation.
    391   ASSERT_EQ(1u, image.image_skia().image_reps().size());
    392 
    393   representation = image.image_skia().GetRepresentation(1.0f);
    394   EXPECT_TRUE(gfx::BitmapsAreEqual(
    395       representation.sk_bitmap(),
    396       EnsureBitmapSize(
    397           default_icon.GetRepresentation(1.0f).sk_bitmap(),
    398           kRequestedSize)));
    399 }
    400 
    401 // If resource set is invalid, image load should be done asynchronously and
    402 // the observer should be notified when it's done. |GetRepresentation| should
    403 // return the default icon representation once image load is done.
    404 TEST_F(ExtensionIconImageTest, InvalidResource) {
    405   scoped_ptr<Profile> profile(new TestingProfile());
    406   scoped_refptr<Extension> extension(CreateExtension(
    407       "extension_icon_image", Manifest::INVALID_LOCATION));
    408   ASSERT_TRUE(extension.get() != NULL);
    409 
    410   const int kInvalidIconSize = 24;
    411   ExtensionIconSet invalid_icon_set;
    412   invalid_icon_set.Add(kInvalidIconSize, "invalid.png");
    413 
    414   gfx::ImageSkia default_icon = GetDefaultIcon();
    415 
    416   IconImage image(profile.get(),
    417                   extension.get(),
    418                   invalid_icon_set,
    419                   kInvalidIconSize,
    420                   default_icon,
    421                   this);
    422 
    423   gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f);
    424   EXPECT_TRUE(gfx::BitmapsAreEqual(
    425       representation.sk_bitmap(),
    426       CreateBlankBitmapForScale(kInvalidIconSize, ui::SCALE_FACTOR_100P)));
    427 
    428   WaitForImageLoad();
    429   EXPECT_EQ(1, ImageLoadedCount());
    430   // We should have default icon representation now.
    431   ASSERT_EQ(1u, image.image_skia().image_reps().size());
    432 
    433   representation = image.image_skia().GetRepresentation(1.0f);
    434   EXPECT_TRUE(gfx::BitmapsAreEqual(
    435       representation.sk_bitmap(),
    436       EnsureBitmapSize(
    437           default_icon.GetRepresentation(1.0f).sk_bitmap(),
    438           kInvalidIconSize)));
    439 }
    440 
    441 // Test that IconImage works with lazily (but synchronously) created default
    442 // icon when IconImage returns synchronously.
    443 TEST_F(ExtensionIconImageTest, LazyDefaultIcon) {
    444   scoped_ptr<Profile> profile(new TestingProfile());
    445   scoped_refptr<Extension> extension(CreateExtension(
    446       "extension_icon_image", Manifest::INVALID_LOCATION));
    447   ASSERT_TRUE(extension.get() != NULL);
    448 
    449   gfx::ImageSkia default_icon = GetDefaultIcon();
    450   gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon),
    451                                     default_icon.size());
    452 
    453   ExtensionIconSet empty_icon_set;
    454 
    455   const int kRequestedSize = 128;
    456   IconImage image(profile.get(),
    457                   extension.get(),
    458                   empty_icon_set,
    459                   kRequestedSize,
    460                   lazy_default_icon,
    461                   this);
    462 
    463   ASSERT_FALSE(lazy_default_icon.HasRepresentation(1.0f));
    464 
    465   gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f);
    466 
    467   // The resouce set is empty, so we should get the result right away.
    468   EXPECT_TRUE(lazy_default_icon.HasRepresentation(1.0f));
    469   EXPECT_TRUE(gfx::BitmapsAreEqual(
    470       representation.sk_bitmap(),
    471       EnsureBitmapSize(
    472           default_icon.GetRepresentation(1.0f).sk_bitmap(),
    473           kRequestedSize)));
    474 
    475   // We should have a default icon representation.
    476   ASSERT_EQ(1u, image.image_skia().image_reps().size());
    477 }
    478 
    479 // Test that IconImage works with lazily (but synchronously) created default
    480 // icon when IconImage returns asynchronously.
    481 TEST_F(ExtensionIconImageTest, LazyDefaultIcon_AsyncIconImage) {
    482   scoped_ptr<Profile> profile(new TestingProfile());
    483   scoped_refptr<Extension> extension(CreateExtension(
    484       "extension_icon_image", Manifest::INVALID_LOCATION));
    485   ASSERT_TRUE(extension.get() != NULL);
    486 
    487   gfx::ImageSkia default_icon = GetDefaultIcon();
    488   gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon),
    489                                     default_icon.size());
    490 
    491   const int kInvalidIconSize = 24;
    492   ExtensionIconSet invalid_icon_set;
    493   invalid_icon_set.Add(kInvalidIconSize, "invalid.png");
    494 
    495   IconImage image(profile.get(),
    496                   extension.get(),
    497                   invalid_icon_set,
    498                   kInvalidIconSize,
    499                   lazy_default_icon,
    500                   this);
    501 
    502   ASSERT_FALSE(lazy_default_icon.HasRepresentation(1.0f));
    503 
    504   gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f);
    505 
    506   WaitForImageLoad();
    507   EXPECT_EQ(1, ImageLoadedCount());
    508   // We should have default icon representation now.
    509   ASSERT_EQ(1u, image.image_skia().image_reps().size());
    510 
    511   EXPECT_TRUE(lazy_default_icon.HasRepresentation(1.0f));
    512 
    513   representation = image.image_skia().GetRepresentation(1.0f);
    514   EXPECT_TRUE(gfx::BitmapsAreEqual(
    515       representation.sk_bitmap(),
    516       EnsureBitmapSize(
    517           default_icon.GetRepresentation(1.0f).sk_bitmap(),
    518           kInvalidIconSize)));
    519 }
    520 
    521 // Tests behavior of image created by IconImage after IconImage host goes
    522 // away. The image should still return loaded representations. If requested
    523 // representation was not loaded while IconImage host was around, transparent
    524 // representations should be returned.
    525 TEST_F(ExtensionIconImageTest, IconImageDestruction) {
    526   scoped_ptr<Profile> profile(new TestingProfile());
    527   scoped_refptr<Extension> extension(CreateExtension(
    528       "extension_icon_image", Manifest::INVALID_LOCATION));
    529   ASSERT_TRUE(extension.get() != NULL);
    530 
    531   gfx::ImageSkia default_icon = GetDefaultIcon();
    532 
    533   // Load images we expect to find as representations in icon_image, so we
    534   // can later use them to validate icon_image.
    535   SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16);
    536   ASSERT_FALSE(bitmap_16.empty());
    537 
    538   scoped_ptr<IconImage> image(
    539       new IconImage(profile.get(),
    540                     extension.get(),
    541                     extensions::IconsInfo::GetIcons(extension.get()),
    542                     16,
    543                     default_icon,
    544                     this));
    545 
    546   // Load an image representation.
    547   gfx::ImageSkiaRep representation =
    548       image->image_skia().GetRepresentation(1.0f);
    549 
    550   WaitForImageLoad();
    551   EXPECT_EQ(1, ImageLoadedCount());
    552   ASSERT_EQ(1u, image->image_skia().image_reps().size());
    553 
    554   // Stash loaded image skia, and destroy |image|.
    555   gfx::ImageSkia image_skia = image->image_skia();
    556   image.reset();
    557   extension = NULL;
    558 
    559   // Image skia should still be able to get previously loaded representation.
    560   representation = image_skia.GetRepresentation(1.0f);
    561 
    562   EXPECT_EQ(1.0f, representation.scale());
    563   EXPECT_EQ(16, representation.pixel_width());
    564   EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), bitmap_16));
    565 
    566   // When requesting another representation, we should get blank image.
    567   representation = image_skia.GetRepresentation(2.0f);
    568 
    569   EXPECT_TRUE(gfx::BitmapsAreEqual(
    570       representation.sk_bitmap(),
    571       CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_200P)));
    572 }
    573