15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_icon_image.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_file_value_serializer.h" 8ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/image_loader.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/manifest_handlers/icons_handler.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/testing_profile.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/image_operations.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_source.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::IconImage; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Manifest; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap CreateBlankBitmapForScale(int size_dip, ui::ScaleFactor scale_factor) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const float scale = ui::GetScaleFactorScale(scale_factor); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.setConfig(SkBitmap::kARGB_8888_Config, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(size_dip * scale), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(size_dip * scale)); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.allocPixels(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0)); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bitmap; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkBitmap EnsureBitmapSize(const SkBitmap& original, int size) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (original.width() == size && original.height() == size) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return original; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap resized = skia::ImageOperations::Resize( 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original, skia::ImageOperations::RESIZE_LANCZOS3, size, size); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return resized; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Used to test behavior including images defined by an image skia source. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |GetImageForScale| simply returns image representation from the image given 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the ctor. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockImageSkiaSource : public gfx::ImageSkiaSource { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit MockImageSkiaSource(const gfx::ImageSkia& image) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : image_(image) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~MockImageSkiaSource() {} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual gfx::ImageSkiaRep GetImageForScale( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ScaleFactor scale_factor) OVERRIDE { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image_.GetRepresentation(scale_factor); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia image_; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class for synchronously loading extension image resource. 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestImageLoader { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit TestImageLoader(const Extension* extension) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : extension_(extension), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_(false), 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_loaded_(false) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestImageLoader() {} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnImageLoaded(const gfx::Image& image) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_ = image; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_loaded_ = true; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (waiting_) 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap LoadBitmap(const std::string& path, 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int size) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_loaded_ = false; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) image_loader_.LoadImageAsync( 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_, extension_->GetResource(path), gfx::Size(size, size), 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&TestImageLoader::OnImageLoaded, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |image_| still hasn't been loaded (i.e. it is being loaded 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // asynchronously), wait for it. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!image_loaded_) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_ = true; 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) waiting_ = false; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(image_loaded_); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image_.IsEmpty() ? SkBitmap() : *image_.ToSkBitmap(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool waiting_; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool image_loaded_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image image_; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ImageLoader image_loader_; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestImageLoader); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionIconImageTest : public testing::Test, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public IconImage::Observer { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconImageTest() 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : image_loaded_count_(0), 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_image_loaded_(false), 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_thread_(BrowserThread::UI, &ui_loop_), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_(BrowserThread::FILE), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_(BrowserThread::IO) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ExtensionIconImageTest() {} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForImageLoad() { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_image_loaded_ = true; 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_image_loaded_ = false; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ImageLoadedCount() { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = image_loaded_count_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_loaded_count_ = 0; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> CreateExtension(const char* name, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Location location) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create and load an extension. 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_file; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PathService::Get(chrome::DIR_TEST_DATA, &test_file)) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(true); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_file = test_file.AppendASCII("extensions").AppendASCII(name); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_code = 0; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JSONFileValueSerializer serializer(test_file.AppendASCII("app.json")); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DictionaryValue> valid_value( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<DictionaryValue*>(serializer.Deserialize(&error_code, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &error))); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, error_code) << error; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_code != 0) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(valid_value.get()); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!valid_value) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Extension::Create(test_file, location, *valid_value, 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::NO_FLAGS, &error); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing::Test overrides: 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_.Start(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_.Start(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IconImage::Delegate overrides: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnExtensionIconImageChanged(IconImage* image) OVERRIDE { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_loaded_count_++; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quit_in_image_loaded_) 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia GetDefaultIcon() { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDR_EXTENSIONS_FAVICON); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loads an image to be used in test from the extension. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The image will be loaded from the relative path |path|. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap GetTestBitmap(const Extension* extension, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& path, 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int size) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestImageLoader image_loader(extension); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return image_loader.LoadBitmap(path, size); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_loaded_count_; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool quit_in_image_loaded_; 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop ui_loop_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread file_thread_; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread io_thread_; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ExtensionIconImageTest); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, Basic) { 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Profile> profile(new TestingProfile()); 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) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IconImage image(profile.get(), 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extensions::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. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Before the image representation is loaded, image should contain blank 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // image representation. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_100P))); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should get the right representation now. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), bitmap_16)); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(16, representation.pixel_width()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets representation for an additional scale factor. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image.image_skia().GetRepresentation(ui::SCALE_FACTOR_200P); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_200P))); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2u, image.image_skia().image_reps().size()); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image.image_skia().GetRepresentation(ui::SCALE_FACTOR_200P); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Image should have been resized. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(32, representation.pixel_width()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap_48_resized_to_32)); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is no resource with either exact or bigger size, but there is a smaller 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resource. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, FallbackToSmallerWhenNoBigger) { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Profile> profile(new TestingProfile()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load images we expect to find as representations in icon_image, so we 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can later use them to validate icon_image. 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap_48 = GetTestBitmap(extension.get(), "48.png", 48); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bitmap_48.empty()); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IconImage image(profile.get(), 297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extensions::IconsInfo::GetIcons(extension.get()), 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32, 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.image_skia().GetRepresentation(ui::SCALE_FACTOR_200P); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image.image_skia().GetRepresentation(ui::SCALE_FACTOR_200P); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have loaded the biggest smaller resource resized to the actual 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::SCALE_FACTOR_200P, representation.scale_factor()); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(64, representation.pixel_width()); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureBitmapSize(bitmap_48, 64))); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is no resource with exact size, but there is a smaller and a bigger 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one. Requested size is smaller than 32 though, so the smaller resource should 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be loaded. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, FallbackToSmaller) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Profile> profile(new TestingProfile()); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load images we expect to find as representations in icon_image, so we 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can later use them to validate icon_image. 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bitmap_16.empty()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IconImage image(profile.get(), 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extensions::IconsInfo::GetIcons(extension.get()), 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17, 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have loaded smaller (resized) resource. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::SCALE_FACTOR_100P, representation.scale_factor()); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(17, representation.pixel_width()); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureBitmapSize(bitmap_16, 17))); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If resource set is empty, |GetRepresentation| should synchronously return 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// default icon, without notifying observer of image change. 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, NoResources) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Profile> profile(new TestingProfile()); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconSet empty_icon_set; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kRequestedSize = 24; 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IconImage image(profile.get(), 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) empty_icon_set, 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kRequestedSize, 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_icon.GetRepresentation(ui::SCALE_FACTOR_100P).sk_bitmap(), 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kRequestedSize))); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, ImageLoadedCount()); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have a default icon representation. 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_icon.GetRepresentation(ui::SCALE_FACTOR_100P).sk_bitmap(), 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kRequestedSize))); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If resource set is invalid, image load should be done asynchronously and 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the observer should be notified when it's done. |GetRepresentation| should 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return the default icon representation once image load is done. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, InvalidResource) { 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Profile> profile(new TestingProfile()); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kInvalidIconSize = 24; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconSet invalid_icon_set; 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalid_icon_set.Add(kInvalidIconSize, "invalid.png"); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 413868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IconImage image(profile.get(), 414868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) invalid_icon_set, 416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidIconSize, 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateBlankBitmapForScale(kInvalidIconSize, ui::SCALE_FACTOR_100P))); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have default icon representation now. 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_icon.GetRepresentation(ui::SCALE_FACTOR_100P).sk_bitmap(), 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kInvalidIconSize))); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that IconImage works with lazily (but synchronously) created default 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// icon when IconImage returns synchronously. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, LazyDefaultIcon) { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Profile> profile(new TestingProfile()); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon), 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon.size()); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconSet empty_icon_set; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kRequestedSize = 128; 454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IconImage image(profile.get(), 455868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 456868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) empty_icon_set, 457868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kRequestedSize, 458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) lazy_default_icon, 459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(lazy_default_icon.HasRepresentation(ui::SCALE_FACTOR_100P)); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The resouce set is empty, so we should get the result right away. 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(lazy_default_icon.HasRepresentation(ui::SCALE_FACTOR_100P)); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_icon.GetRepresentation(ui::SCALE_FACTOR_100P).sk_bitmap(), 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kRequestedSize))); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have a default icon representation. 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that IconImage works with lazily (but synchronously) created default 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// icon when IconImage returns asynchronously. 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, LazyDefaultIcon_AsyncIconImage) { 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Profile> profile(new TestingProfile()); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia lazy_default_icon(new MockImageSkiaSource(default_icon), 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon.size()); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kInvalidIconSize = 24; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionIconSet invalid_icon_set; 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) invalid_icon_set.Add(kInvalidIconSize, "invalid.png"); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IconImage image(profile.get(), 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 496868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) invalid_icon_set, 497868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kInvalidIconSize, 498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) lazy_default_icon, 499868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(lazy_default_icon.HasRepresentation(ui::SCALE_FACTOR_100P)); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should have default icon representation now. 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image.image_skia().image_reps().size()); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(lazy_default_icon.HasRepresentation(ui::SCALE_FACTOR_100P)); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image.image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EnsureBitmapSize( 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default_icon.GetRepresentation(ui::SCALE_FACTOR_100P).sk_bitmap(), 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kInvalidIconSize))); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests behavior of image created by IconImage after IconImage host goes 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// away. The image should still return loaded representations. If requested 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// representation was not loaded while IconImage host was around, transparent 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// representations should be returned. 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionIconImageTest, IconImageDestruction) { 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<Profile> profile(new TestingProfile()); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "extension_icon_image", Manifest::INVALID_LOCATION)); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia default_icon = GetDefaultIcon(); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load images we expect to find as representations in icon_image, so we 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can later use them to validate icon_image. 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap_16 = GetTestBitmap(extension.get(), "16.png", 16); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(bitmap_16.empty()); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<IconImage> image( 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new IconImage(profile.get(), 540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension.get(), 541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extensions::IconsInfo::GetIcons(extension.get()), 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16, 543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default_icon, 544868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this)); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load an image representation. 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkiaRep representation = 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image->image_skia().GetRepresentation(ui::SCALE_FACTOR_100P); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForImageLoad(); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1, ImageLoadedCount()); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, image->image_skia().image_reps().size()); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stash loaded image skia, and destroy |image|. 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia image_skia = image->image_skia(); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image.reset(); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension = NULL; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Image skia should still be able to get previously loaded representation. 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image_skia.GetRepresentation(ui::SCALE_FACTOR_100P); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::SCALE_FACTOR_100P, representation.scale_factor()); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(16, representation.pixel_width()); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual(representation.sk_bitmap(), bitmap_16)); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When requesting another representation, we should get blank image. 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation = image_skia.GetRepresentation(ui::SCALE_FACTOR_200P); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(gfx::BitmapsAreEqual( 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) representation.sk_bitmap(), 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBlankBitmapForScale(16, ui::SCALE_FACTOR_200P))); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 573