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/test/base/testing_profile.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.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) 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/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) { 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return image_rep1.scale() == image_rep2.scale() && 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) 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)gfx::ImageSkiaRep CreateBlankRep(int size_dip, float scale) { 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SkBitmap bitmap; 5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bitmap.setConfig(SkBitmap::kARGB_8888_Config, 5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) static_cast<int>(size_dip * scale), 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) static_cast<int>(size_dip * scale)); 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bitmap.allocPixels(); 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bitmap.eraseColor(SkColorSetARGB(0, 0, 0, 0)); 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return gfx::ImageSkiaRep(bitmap, scale); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image LoadIcon(const std::string& filename) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(chrome::DIR_TEST_DATA, &path); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = path.AppendASCII("extensions/api_test").AppendASCII(filename); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string file_contents; 7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::ReadFileToString(path, &file_contents); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned char* data = 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const unsigned char*>(file_contents.data()); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) gfx::PNGCodec::Decode(data, file_contents.length(), &bitmap); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::Image::CreateFrom1xBitmap(bitmap); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionActionIconFactoryTest 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public testing::Test, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public ExtensionActionIconFactory::Observer { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionActionIconFactoryTest() 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : quit_in_icon_updated_(false), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_thread_(BrowserThread::UI, &ui_loop_), 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_(BrowserThread::FILE), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_(BrowserThread::IO) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ExtensionActionIconFactoryTest() {} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForIconUpdate() { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_icon_updated_ = true; 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quit_in_icon_updated_ = false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> CreateExtension(const char* name, 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Location location) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create and load an extension. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath test_file; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!PathService::Get(chrome::DIR_TEST_DATA, &test_file)) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(true); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_file = test_file.AppendASCII("extensions/api_test").AppendASCII(name); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_code = 0; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JSONFileValueSerializer serializer(test_file.AppendASCII("manifest.json")); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> valid_value( 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<base::DictionaryValue*>(serializer.Deserialize(&error_code, 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &error))); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, error_code) << error; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_code != 0) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(valid_value.get()); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!valid_value) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension = 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::Create(test_file, location, *valid_value, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::NO_FLAGS, &error); 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(extension.get()) << error; 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (extension.get()) 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension_service_->AddExtension(extension.get()); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // testing::Test overrides: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() OVERRIDE { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_thread_.Start(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_thread_.Start(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_.reset(new TestingProfile); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine command_line(CommandLine::NO_PROGRAM); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service_ = static_cast<extensions::TestExtensionSystem*>( 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExtensionSystem::Get(profile_.get()))-> 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateExtensionService(&command_line, base::FilePath(), false); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() OVERRIDE { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_.reset(); // Get all DeleteSoon calls sent to ui_loop_. 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_loop_.RunUntilIdle(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ExtensionActionIconFactory::Observer overrides: 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnIconUpdated() OVERRIDE { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quit_in_icon_updated_) 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia GetFavicon() { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDR_EXTENSIONS_FAVICON); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionAction* GetBrowserAction(const Extension& extension) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ExtensionActionManager::Get(profile())->GetBrowserAction(extension); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestingProfile* profile() { return profile_.get(); } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool quit_in_icon_updated_; 16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop ui_loop_; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread file_thread_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread io_thread_; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TestingProfile> profile_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService* extension_service_; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined OS_CHROMEOS 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::ScopedTestCrosSettings test_cros_settings_; 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::ScopedTestUserManager test_user_manager_; 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ExtensionActionIconFactoryTest); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If there is no default icon, and the icon has not been set using |SetIcon|, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the factory should return favicon. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionActionIconFactoryTest, NoIcons) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load an extension that has browser action without default icon set in the 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest and does not call |SetIcon| by default. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "browser_action/no_icon", Manifest::INVALID_LOCATION)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionAction* browser_action = GetBrowserAction(*extension.get()); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(browser_action->default_icon()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia favicon = GetFavicon(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionActionIconFactory icon_factory( 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile(), extension.get(), browser_action, this); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image icon = icon_factory.GetIcon(0); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) favicon.GetRepresentation(1.0f), 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(1.0f))); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the icon has been set using |SetIcon|, the factory should return that 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// icon. 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionActionIconFactoryTest, AfterSetIcon) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load an extension that has browser action without default icon set in the 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest and does not call |SetIcon| by default (but has an browser action 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // icon resource). 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "browser_action/no_icon", Manifest::INVALID_LOCATION)); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionAction* browser_action = GetBrowserAction(*extension.get()); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(browser_action->default_icon()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image set_icon = LoadIcon("browser_action/no_icon/icon.png"); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(set_icon.IsEmpty()); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_action->SetIcon(0, set_icon); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionActionIconFactory icon_factory( 231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile(), extension.get(), browser_action, this); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image icon = icon_factory.GetIcon(0); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) set_icon.ToImageSkia()->GetRepresentation(1.0f), 23768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(1.0f))); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It should still return favicon for another tabs. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon = icon_factory.GetIcon(1); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetFavicon().GetRepresentation(1.0f), 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(1.0f))); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If there is a default icon, and the icon has not been set using |SetIcon|, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the factory should return the default icon. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionActionIconFactoryTest, DefaultIcon) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load an extension that has browser action without default icon set in the 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest and does not call |SetIcon| by default (but has an browser action 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // icon resource). 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(CreateExtension( 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "browser_action/no_icon", Manifest::INVALID_LOCATION)); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(extension.get() != NULL); 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ExtensionAction* browser_action = GetBrowserAction(*extension.get()); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(browser_action->default_icon()); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action->GetExplicitlySetIcon(0 /*tab id*/).isNull()); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image default_icon = 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureImageSize(LoadIcon("browser_action/no_icon/icon.png"), 19); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(default_icon.IsEmpty()); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ExtensionIconSet> default_icon_set(new ExtensionIconSet()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon_set->Add(19, "icon.png"); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_action->set_default_icon(default_icon_set.Pass()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser_action->default_icon()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionActionIconFactory icon_factory( 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile(), extension.get(), browser_action, this); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image icon = icon_factory.GetIcon(0); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The icon should be loaded asynchronously. Initially a transparent icon 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be returned. 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CreateBlankRep(19, 1.0f), 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(1.0f))); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitForIconUpdate(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon = icon_factory.GetIcon(0); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The default icon representation should be loaded at this point. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) default_icon.ToImageSkia()->GetRepresentation(1.0f), 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(1.0f))); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The same icon should be returned for the other tabs. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon = icon_factory.GetIcon(1); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ImageRepsAreEqual( 29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) default_icon.ToImageSkia()->GetRepresentation(1.0f), 29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) icon.ToImageSkia()->GetRepresentation(1.0f))); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 302