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_action_icon_factory.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 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" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_action.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_action_manager.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/test_extension_system.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.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" 24a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "ui/gfx/codec/png_codec.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h" 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_service.h" 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ImageRepsAreEqual(const gfx::ImageSkiaRep& image_rep1, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkiaRep& image_rep2) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return image_rep1.scale_factor() == image_rep2.scale_factor() && 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::BitmapsAreEqual(image_rep1.sk_bitmap(), image_rep2.sk_bitmap()); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image EnsureImageSize(const gfx::Image& original, int size) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap* original_bitmap = original.ToSkBitmap(); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (original_bitmap->width() == size && original_bitmap->height() == size) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return original; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap resized = skia::ImageOperations::Resize( 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *original.ToSkBitmap(), skia::ImageOperations::RESIZE_LANCZOS3, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size, size); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Image::CreateFrom1xBitmap(resized); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkiaRep CreateBlankRep(int size_dip, ui::ScaleFactor scale_factor) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const float scale = ui::GetScaleFactorScale(scale_factor); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.setConfig(SkBitmap::kARGB_8888_Config, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(size_dip * scale), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(size_dip * scale)); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.allocPixels(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0)); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::ImageSkiaRep(bitmap, scale_factor); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image LoadIcon(const std::string& filename) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(chrome::DIR_TEST_DATA, &path); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = path.AppendASCII("extensions/api_test").AppendASCII(filename); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string file_contents; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::ReadFileToString(path, &file_contents); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char* data = 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const unsigned char*>(file_contents.data()); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 78a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) gfx::PNGCodec::Decode(data, file_contents.length(), &bitmap); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Image::CreateFrom1xBitmap(bitmap); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionActionIconFactoryTest 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public testing::Test, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ExtensionActionIconFactory::Observer { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionActionIconFactoryTest() 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : quit_in_icon_updated_(false), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_thread_(BrowserThread::UI, &ui_loop_), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_(BrowserThread::FILE), 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_(BrowserThread::IO) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ExtensionActionIconFactoryTest() {} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForIconUpdate() { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_icon_updated_ = true; 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_icon_updated_ = false; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> CreateExtension(const char* name, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Location location) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create and load an extension. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_file; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PathService::Get(chrome::DIR_TEST_DATA, &test_file)) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(true); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_file = test_file.AppendASCII("extensions/api_test").AppendASCII(name); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_code = 0; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JSONFileValueSerializer serializer(test_file.AppendASCII("manifest.json")); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DictionaryValue> valid_value( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<DictionaryValue*>(serializer.Deserialize(&error_code, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &error))); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, error_code) << error; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_code != 0) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(valid_value.get()); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!valid_value) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension = 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::Create(test_file, location, *valid_value, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::NO_FLAGS, &error); 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(extension.get()) << error; 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (extension.get()) 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_service_->AddExtension(extension.get()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing::Test overrides: 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_.Start(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_.Start(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_.reset(new TestingProfile); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine command_line(CommandLine::NO_PROGRAM); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_ = static_cast<extensions::TestExtensionSystem*>( 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExtensionSystem::Get(profile_.get()))-> 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateExtensionService(&command_line, base::FilePath(), false); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_.reset(); // Get all DeleteSoon calls sent to ui_loop_. 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_loop_.RunUntilIdle(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ExtensionActionIconFactory::Observer overrides: 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnIconUpdated() OVERRIDE { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quit_in_icon_updated_) 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia GetFavicon() { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDR_EXTENSIONS_FAVICON); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionAction* GetBrowserAction(const Extension& extension) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExtensionActionManager::Get(profile())->GetBrowserAction(extension); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestingProfile* profile() { return profile_.get(); } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool quit_in_icon_updated_; 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop ui_loop_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread file_thread_; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread io_thread_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TestingProfile> profile_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService* extension_service_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined OS_CHROMEOS 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::ScopedTestCrosSettings test_cros_settings_; 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::ScopedTestUserManager test_user_manager_; 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ExtensionActionIconFactoryTest); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If there is no default icon, and the icon has not been set using |SetIcon|, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the factory should return favicon. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionActionIconFactoryTest, NoIcons) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load an extension that has browser action without default icon set in the 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest and does not call |SetIcon| by default. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "browser_action/no_icon", Manifest::INVALID_LOCATION)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionAction* browser_action = GetBrowserAction(*extension.get()); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(browser_action->default_icon()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia favicon = GetFavicon(); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionActionIconFactory icon_factory( 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile(), extension.get(), browser_action, this); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image icon = icon_factory.GetIcon(0); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon.GetRepresentation(ui::SCALE_FACTOR_100P), 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the icon has been set using |SetIcon|, the factory should return that 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// icon. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionActionIconFactoryTest, AfterSetIcon) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load an extension that has browser action without default icon set in the 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest and does not call |SetIcon| by default (but has an browser action 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // icon resource). 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "browser_action/no_icon", Manifest::INVALID_LOCATION)); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionAction* browser_action = GetBrowserAction(*extension.get()); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(browser_action->default_icon()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image set_icon = LoadIcon("browser_action/no_icon/icon.png"); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(set_icon.IsEmpty()); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_action->SetIcon(0, set_icon); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionActionIconFactory icon_factory( 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile(), extension.get(), browser_action, this); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image icon = icon_factory.GetIcon(0); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P), 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It should still return favicon for another tabs. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon = icon_factory.GetIcon(1); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetFavicon().GetRepresentation(ui::SCALE_FACTOR_100P), 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If there is a default icon, and the icon has not been set using |SetIcon|, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the factory should return the default icon. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionActionIconFactoryTest, DefaultIcon) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load an extension that has browser action without default icon set in the 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest and does not call |SetIcon| by default (but has an browser action 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // icon resource). 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "browser_action/no_icon", Manifest::INVALID_LOCATION)); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionAction* browser_action = GetBrowserAction(*extension.get()); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(browser_action->default_icon()); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image default_icon = 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureImageSize(LoadIcon("browser_action/no_icon/icon.png"), 19); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(default_icon.IsEmpty()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ExtensionIconSet> default_icon_set(new ExtensionIconSet()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon_set->Add(19, "icon.png"); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_action->set_default_icon(default_icon_set.Pass()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action->default_icon()); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionActionIconFactory icon_factory( 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile(), extension.get(), browser_action, this); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image icon = icon_factory.GetIcon(0); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The icon should be loaded asynchronously. Initially a transparent icon 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be returned. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateBlankRep(19, ui::SCALE_FACTOR_100P), 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForIconUpdate(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon = icon_factory.GetIcon(0); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The default icon representation should be loaded at this point. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The same icon should be returned for the other tabs. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon = icon_factory.GetIcon(1); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P), 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(ui::SCALE_FACTOR_100P))); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 303