16d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "extensions/browser/extension_icon_image.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector> 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_file_value_serializer.h" 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/notification_service.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/test/test_browser_context.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extensions_test.h" 166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "extensions/browser/image_loader.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/common/extension_paths.h" 193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h" 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/manifest_handlers/icons_handler.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/image_operations.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_source.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace extensions { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap CreateBlankBitmapForScale(int size_dip, ui::ScaleFactor scale_factor) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const float scale = ui::GetScaleForScaleFactor(scale_factor); 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bitmap.allocN32Pixels(static_cast<int>(size_dip * scale), 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static_cast<int>(size_dip * scale)); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0)); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bitmap; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap EnsureBitmapSize(const SkBitmap& original, int size) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (original.width() == size && original.height() == size) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return original; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap resized = skia::ImageOperations::Resize( 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original, skia::ImageOperations::RESIZE_LANCZOS3, size, size); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resized; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used to test behavior including images defined by an image skia source. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |GetImageForScale| simply returns image representation from the image given 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the ctor. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockImageSkiaSource : public gfx::ImageSkiaSource { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit MockImageSkiaSource(const gfx::ImageSkia& image) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : image_(image) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockImageSkiaSource() {} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual gfx::ImageSkiaRep GetImageForScale(float scale) OVERRIDE { 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return image_.GetRepresentation(scale); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia image_; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class for synchronously loading extension image resource. 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestImageLoader { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit TestImageLoader(const Extension* extension) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : extension_(extension), 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_(false), 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_loaded_(false) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestImageLoader() {} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnImageLoaded(const gfx::Image& image) { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_ = image; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_loaded_ = true; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (waiting_) 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap LoadBitmap(const std::string& path, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int size) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_loaded_ = false; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_loader_.LoadImageAsync( 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_, extension_->GetResource(path), gfx::Size(size, size), 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&TestImageLoader::OnImageLoaded, 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |image_| still hasn't been loaded (i.e. it is being loaded 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // asynchronously), wait for it. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!image_loaded_) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_ = true; 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_ = false; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(image_loaded_); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image_.IsEmpty() ? SkBitmap() : *image_.ToSkBitmap(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension_; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool waiting_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool image_loaded_; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image image_; 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ImageLoader image_loader_; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestImageLoader); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass ExtensionIconImageTest : public ExtensionsTest, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public IconImage::Observer { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconImageTest() 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : image_loaded_count_(0), 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_image_loaded_(false), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_thread_(BrowserThread::UI, &ui_loop_), 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_(BrowserThread::FILE), 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci io_thread_(BrowserThread::IO), 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci notification_service_(content::NotificationService::Create()) {} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ExtensionIconImageTest() {} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForImageLoad() { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_image_loaded_ = true; 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_image_loaded_ = false; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ImageLoadedCount() { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = image_loaded_count_; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_loaded_count_ = 0; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> CreateExtension(const char* name, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Location location) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create and load an extension. 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_file; 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!PathService::Get(DIR_TEST_DATA, &test_file)) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(true); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) test_file = test_file.AppendASCII(name); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_code = 0; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error; 1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) JSONFileValueSerializer serializer(test_file.AppendASCII("manifest.json")); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> valid_value( 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<base::DictionaryValue*>(serializer.Deserialize(&error_code, 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &error))); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, error_code) << error; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_code != 0) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(valid_value.get()); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!valid_value) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Extension::Create(test_file, location, *valid_value, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::NO_FLAGS, &error); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing::Test overrides: 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_.Start(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_.Start(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IconImage::Delegate overrides: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnExtensionIconImageChanged(IconImage* image) OVERRIDE { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_loaded_count_++; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quit_in_image_loaded_) 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia GetDefaultIcon() { 1836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return gfx::ImageSkia(gfx::ImageSkiaRep(gfx::Size(16, 16), 1.0f)); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loads an image to be used in test from the extension. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The image will be loaded from the relative path |path|. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap GetTestBitmap(const Extension* extension, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& path, 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int size) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestImageLoader image_loader(extension); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return image_loader.LoadBitmap(path, size); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_loaded_count_; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool quit_in_image_loaded_; 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop ui_loop_; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread file_thread_; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread io_thread_; 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<content::NotificationService> notification_service_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, Basic) { 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<ui::ScaleFactor> supported_factors; 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_factors.push_back(ui::SCALE_FACTOR_100P); 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_factors.push_back(ui::SCALE_FACTOR_200P); 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load images we expect to find as representations in icon_image, so we 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can later use them to validate icon_image. 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bitmap_16.empty()); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There is no image of size 32 defined in the extension manifest, so we 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should expect manifest image of size 48 resized to size 32. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap_48_resized_to_32 = 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GetTestBitmap(extension.get(), "48.png", 32); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bitmap_48_resized_to_32.empty()); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconImage image(browser_context(), 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconsInfo::GetIcons(extension.get()), 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16, 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No representations in |image_| yet. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia::ImageSkiaReps image_reps = image.image_skia().image_reps(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0u, image_reps.size()); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets representation for a scale factor. 24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Before the image representation is loaded, image should contain blank 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // image representation. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_100P))); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image.image_skia().GetRepresentation(1.0f); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should get the right representation now. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), bitmap_16)); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(16, representation.pixel_width()); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets representation for an additional scale factor. 26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image.image_skia().GetRepresentation(2.0f); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_200P))); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2u, image.image_skia().image_reps().size()); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image.image_skia().GetRepresentation(2.0f); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Image should have been resized. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(32, representation.pixel_width()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_48_resized_to_32)); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is no resource with either exact or bigger size, but there is a smaller 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resource. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, FallbackToSmallerWhenNoBigger) { 28368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<ui::ScaleFactor> supported_factors; 28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_factors.push_back(ui::SCALE_FACTOR_100P); 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) supported_factors.push_back(ui::SCALE_FACTOR_200P); 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ui::test::ScopedSetSupportedScaleFactors scoped_supported(supported_factors); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load images we expect to find as representations in icon_image, so we 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can later use them to validate icon_image. 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap_48 = GetTestBitmap(extension.get(), "48.png", 48); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bitmap_48.empty()); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconImage image(browser_context(), 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconsInfo::GetIcons(extension.get()), 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32, 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(2.0f); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image.image_skia().GetRepresentation(2.0f); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have loaded the biggest smaller resource resized to the actual 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size. 31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(2.0f, representation.scale()); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(64, representation.pixel_width()); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureBitmapSize(bitmap_48, 64))); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is no resource with exact size, but there is a smaller and a bigger 32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// one. The bigger resource should be loaded. 32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(ExtensionIconImageTest, FallbackToBigger) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load images we expect to find as representations in icon_image, so we 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can later use them to validate icon_image. 33203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SkBitmap bitmap_24 = GetTestBitmap(extension.get(), "24.png", 24); 33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ASSERT_FALSE(bitmap_24.empty()); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconImage image(browser_context(), 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconsInfo::GetIcons(extension.get()), 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17, 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image.image_skia().GetRepresentation(1.0f); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // We should have loaded the smallest bigger (resized) resource. 35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1.0f, representation.scale()); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(17, representation.pixel_width()); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), 35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EnsureBitmapSize(bitmap_24, 17))); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If resource set is empty, |GetRepresentation| should synchronously return 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// default icon, without notifying observer of image change. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, NoResources) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconSet empty_icon_set; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kRequestedSize = 24; 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconImage image(browser_context(), 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) empty_icon_set, 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kRequestedSize, 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 37968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) default_icon.GetRepresentation(1.0f).sk_bitmap(), 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kRequestedSize))); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, ImageLoadedCount()); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have a default icon representation. 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image.image_skia().GetRepresentation(1.0f); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 39068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) default_icon.GetRepresentation(1.0f).sk_bitmap(), 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kRequestedSize))); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If resource set is invalid, image load should be done asynchronously and 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the observer should be notified when it's done. |GetRepresentation| should 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return the default icon representation once image load is done. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, InvalidResource) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kInvalidIconSize = 24; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconSet invalid_icon_set; 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalid_icon_set.Add(kInvalidIconSize, "invalid.png"); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconImage image(browser_context(), 409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 410868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) invalid_icon_set, 411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidIconSize, 412868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateBlankBitmapForScale(kInvalidIconSize, ui::SCALE_FACTOR_100P))); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have default icon representation now. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image.image_skia().GetRepresentation(1.0f); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 42968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) default_icon.GetRepresentation(1.0f).sk_bitmap(), 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kInvalidIconSize))); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that IconImage works with lazily (but synchronously) created default 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// icon when IconImage returns synchronously. 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, LazyDefaultIcon) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon), 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon.size()); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconSet empty_icon_set; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kRequestedSize = 128; 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconImage image(browser_context(), 448868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 449868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) empty_icon_set, 450868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kRequestedSize, 451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) lazy_default_icon, 452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ASSERT_FALSE(lazy_default_icon.HasRepresentation(1.0f)); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The resouce set is empty, so we should get the result right away. 45968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_TRUE(lazy_default_icon.HasRepresentation(1.0f)); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 46368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) default_icon.GetRepresentation(1.0f).sk_bitmap(), 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kRequestedSize))); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have a default icon representation. 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that IconImage works with lazily (but synchronously) created default 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// icon when IconImage returns asynchronously. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, LazyDefaultIcon_AsyncIconImage) { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon), 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon.size()); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kInvalidIconSize = 24; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconSet invalid_icon_set; 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalid_icon_set.Add(kInvalidIconSize, "invalid.png"); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconImage image(browser_context(), 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) invalid_icon_set, 488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidIconSize, 489868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) lazy_default_icon, 490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ASSERT_FALSE(lazy_default_icon.HasRepresentation(1.0f)); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::ImageSkiaRep representation = image.image_skia().GetRepresentation(1.0f); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have default icon representation now. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_TRUE(lazy_default_icon.HasRepresentation(1.0f)); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image.image_skia().GetRepresentation(1.0f); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) default_icon.GetRepresentation(1.0f).sk_bitmap(), 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kInvalidIconSize))); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests behavior of image created by IconImage after IconImage host goes 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// away. The image should still return loaded representations. If requested 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// representation was not loaded while IconImage host was around, transparent 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// representations should be returned. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, IconImageDestruction) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load images we expect to find as representations in icon_image, so we 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can later use them to validate icon_image. 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bitmap_16.empty()); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<IconImage> image( 5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new IconImage(browser_context(), 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci IconsInfo::GetIcons(extension.get()), 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16, 532868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 533868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this)); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load an image representation. 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 53768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) image->image_skia().GetRepresentation(1.0f); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image->image_skia().image_reps().size()); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stash loaded image skia, and destroy |image|. 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia image_skia = image->image_skia(); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.reset(); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension = NULL; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Image skia should still be able to get previously loaded representation. 54968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image_skia.GetRepresentation(1.0f); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) EXPECT_EQ(1.0f, representation.scale()); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(16, representation.pixel_width()); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), bitmap_16)); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // When requesting another representation, we should not crash and return some 556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // image of the size. It could be blank or a rescale from the existing 1.0f 557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // icon. 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) representation = image_skia.GetRepresentation(2.0f); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(16, representation.GetWidth()); 561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(16, representation.GetHeight()); 562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(2.0f, representation.scale()); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace extensions 566