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)#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/observer_list.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/extension_action/action_info.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_icon_set.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkColor.h" 21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// TODO(robertphillips): change this to "class SkBaseDevice;" 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/skia/include/core/SkDevice.h" 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/linear_animation.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GURL; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SkBitmap; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Canvas; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Image; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ImageSkia; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Rect; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Size; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ExtensionAction encapsulates the state of a browser action, page action, or 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// script badge. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instances can have both global and per-tab state. If a property does not have 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a per-tab value, the global value is used instead. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionAction { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use this ID to indicate the default state for properties that take a tab_id 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameter. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kDefaultTabId; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Appearance { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The action icon is hidden. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INVISIBLE, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The action is trying to get the user's attention but isn't yet 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // running on the page. Currently only used for script badges. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WANTS_ATTENTION, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The action icon is visible with its normal appearance. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACTIVE, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A fade-in animation. 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) class IconAnimation : public gfx::LinearAnimation { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Observes changes to icon animation state. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Observer { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnIconChanged() = 0; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Observer() {} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A holder for an IconAnimation with a scoped observer. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ScopedObserver { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedObserver(const base::WeakPtr<IconAnimation>& icon_animation, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Observer* observer); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ScopedObserver(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the icon animation, or NULL if the reference has expired. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IconAnimation* icon_animation() const { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return icon_animation_.get(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IconAnimation> icon_animation_; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Observer* observer_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedObserver); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~IconAnimation(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the icon derived from the current animation state applied to 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |icon|. Ownership remains with this. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& Apply(const SkBitmap& icon) const; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddObserver(Observer* observer); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveObserver(Observer* observer); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct using ExtensionAction::RunIconAnimation(). 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ExtensionAction; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IconAnimation(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IconAnimation> AsWeakPtr(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // gfx::LinearAnimation implementation. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AnimateToState(double state) OVERRIDE; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Device we use to paint icons to. 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) mutable scoped_ptr<SkBaseDevice> device_; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObserverList<Observer> observers_; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<IconAnimation> weak_ptr_factory_; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IconAnimation); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionAction(const std::string& extension_id, 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ActionInfo::Type action_type, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const extensions::ActionInfo& manifest_data); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ExtensionAction(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets a copy of this, ownership passed to caller. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It doesn't make sense to copy of an ExtensionAction except in tests. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ExtensionAction> CopyForTest() const; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Given the extension action type, returns the size the extension action icon 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should have. The icon should be square, so only one dimension is 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returned. 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static int GetIconSizeForType(extensions::ActionInfo::Type type); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension id 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id() const { return extension_id_; } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // What kind of action is this? 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ActionInfo::Type action_type() const { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return action_type_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // action id -- only used with legacy page actions API 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id() const { return id_; } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_id(const std::string& id) { id_ = id; } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_changed() const { return has_changed_; } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_has_changed(bool value) { has_changed_ = value; } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the url which the popup will load when the user clicks this action's 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // icon. Setting an empty URL will disable the popup for a given tab. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetPopupUrl(int tab_id, const GURL& url); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use HasPopup() to see if a popup should be displayed. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasPopup(int tab_id) const; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the URL to display in a popup. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL GetPopupUrl(int tab_id) const; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set this action's title on a specific tab. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetTitle(int tab_id, const std::string& title) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetValue(&title_, tab_id, title); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If tab |tab_id| has a set title, return it. Otherwise, return 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the default title. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetTitle(int tab_id) const { return GetValue(&title_, tab_id); } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Icons are a bit different because the default value can be set to either a 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bitmap or a path. However, conceptually, there is only one default icon. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setting the default icon using a path clears the bitmap and vice-versa. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To retrieve the icon for the extension action, use 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ExtensionActionIconFactory. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set this action's icon bitmap on a specific tab. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetIcon(int tab_id, const gfx::Image& image); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Applies the attention and animation image transformations registered for 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the tab on the provided icon. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Image ApplyAttentionAndAnimation(const gfx::ImageSkia& icon, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_id) const; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the icon that has been set using |SetIcon| for the tab. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia GetExplicitlySetIcon(int tab_id) const; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Non-tab-specific icon path. This is used to support the default_icon key of 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // page and browser actions. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_default_icon(scoped_ptr<ExtensionIconSet> icon_set) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_icon_ = icon_set.Pass(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ExtensionIconSet* default_icon() const { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return default_icon_.get(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set this action's badge text on a specific tab. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetBadgeText(int tab_id, const std::string& text) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetValue(&badge_text_, tab_id, text); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the badge text for a tab, or the default if no badge text was set. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetBadgeText(int tab_id) const { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetValue(&badge_text_, tab_id); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set this action's badge text color on a specific tab. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetBadgeTextColor(int tab_id, SkColor text_color) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetValue(&badge_text_color_, tab_id, text_color); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the text color for a tab, or the default color if no text color 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was set. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor GetBadgeTextColor(int tab_id) const { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetValue(&badge_text_color_, tab_id); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set this action's badge background color on a specific tab. 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetBadgeBackgroundColor(int tab_id, SkColor color) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetValue(&badge_background_color_, tab_id, color); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the badge background color for a tab, or the default if no color 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was set. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkColor GetBadgeBackgroundColor(int tab_id) const { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetValue(&badge_background_color_, tab_id); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set this action's badge visibility on a specific tab. This takes 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // care of any appropriate transition animations. Returns true if 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the appearance has changed. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SetAppearance(int tab_id, Appearance value); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The declarative appearance overrides a default appearance but is overridden 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // by an appearance set directly on the tab. 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DeclarativeShow(int tab_id); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UndoDeclarativeShow(int tab_id); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the badge visibility for a tab, or the default badge visibility 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if none was set. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetIsVisible(int tab_id) const { 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetAppearance(tab_id) != INVISIBLE; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if the tab's action wants the user's attention. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WantsAttention(int tab_id) const { 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetAppearance(tab_id) == WANTS_ATTENTION; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove all tab-specific state. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ClearAllValuesForTab(int tab_id); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the specified tab has a badge, paint it into the provided bounds. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PaintBadge(gfx::Canvas* canvas, const gfx::Rect& bounds, int tab_id); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns icon image with badge for specified tab. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia GetIconWithBadge(const gfx::ImageSkia& icon, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_id, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& spacing) const; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets a weak reference to the icon animation for a tab, if any. The 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reference will only have a value while the animation is running. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtr<IconAnimation> GetIconAnimation(int tab_id) const; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Runs an animation on a tab. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunIconAnimation(int tab_id); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the icon animation is running on tab |tab_id|, applies it to 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |orig| and returns the result. Otherwise, just returns |orig|. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::ImageSkia ApplyIconAnimation(int tab_id, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& orig) const; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns width of the current icon for tab_id. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(tbarzic): The icon selection is done in ExtensionActionIconFactory. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should probably move this there too. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetIconWidth(int tab_id) const; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <class T> 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ValueTraits { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static T CreateEmpty() { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return T(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<class T> 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetValue(std::map<int, T>* map, int tab_id, const T& val) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*map)[tab_id] = val; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) template<class Map> 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const typename Map::mapped_type* FindOrNull( 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Map* map, 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const typename Map::key_type& key) { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typename Map::const_iterator iter = map->find(key); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == map->end()) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &iter->second; 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<class T> 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T GetValue(const std::map<int, T>* map, int tab_id) const { 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (const T* tab_value = FindOrNull(map, tab_id)) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *tab_value; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (const T* default_value = FindOrNull(map, kDefaultTabId)) { 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *default_value; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ValueTraits<T>::CreateEmpty(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Gets the appearance of |tab_id|. Returns the first of: a specific 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // appearance set on the tab; a declarative appearance set on the tab; the 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // default appearance set for all tabs; or INVISIBLE. Don't return this 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // result to an extension's background page because the declarative state can 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // leak information about hosts the extension doesn't have permission to 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // access. 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Appearance GetAppearance(int tab_id) const { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (const Appearance* tab_appearance = FindOrNull(&appearance_, tab_id)) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *tab_appearance; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ContainsKey(declarative_show_count_, tab_id)) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ACTIVE; 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (const Appearance* default_appearance = 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FindOrNull(&appearance_, kDefaultTabId)) 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *default_appearance; 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return INVISIBLE; 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The id for the extension this action belongs to (as defined in the 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension manifest). 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string extension_id_; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const extensions::ActionInfo::Type action_type_; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Each of these data items can have both a global state (stored with the key 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // kDefaultTabId), or tab-specific state (stored with the tab_id as the key). 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, GURL> popup_url_; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, std::string> title_; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, gfx::ImageSkia> icon_; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, std::string> badge_text_; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, SkColor> badge_background_color_; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, SkColor> badge_text_color_; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, Appearance> appearance_; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Declarative state exists for two reasons: First, we need to hide it from 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the extension's background/event page to avoid leaking data from hosts the 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extension doesn't have permission to access. Second, the action's state 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // gets both reset and given its declarative values in response to a 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WebContentsObserver::DidNavigateMainFrame event, and there's no way to set 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // those up to be called in the right order. 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Maps tab_id to the number of active (applied-but-not-reverted) 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // declarativeContent.ShowPageAction actions. 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<int, int> declarative_show_count_; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IconAnimations are destroyed by a delayed task on the UI message loop so 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that even if the Extension and ExtensionAction are destroyed on a non-UI 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread, the animation will still only be touched from the UI thread. This 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // causes the WeakPtr in this map to become NULL. GetIconAnimation() removes 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NULLs to prevent the map from growing without bound. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable std::map<int, base::WeakPtr<IconAnimation> > icon_animation_; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ExtensionIconSet containing paths to bitmaps from which default icon's 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // image representations will be selected. 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<const ExtensionIconSet> default_icon_; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The id for the ExtensionAction, for example: "RssPageAction". This is 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // needed for compat with an older version of the page actions API. 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string id_; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if the ExtensionAction's settings have changed from what was 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specified in the manifest. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_changed_; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ExtensionAction); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<> 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionAction::ValueTraits<int> { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static int CreateEmpty() { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_ 379