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"
19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/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)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ExtensionAction encapsulates the state of a browser action or page action.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instances can have both global and per-tab state. If a property does not have
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a per-tab value, the global value is used instead.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionAction {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // The action that the UI should take after the ExtensionAction is clicked.
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  enum ShowAction {
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ACTION_NONE,
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ACTION_SHOW_POPUP,
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // We don't need a SHOW_CONTEXT_MENU because that's handled separately in
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // the UI.
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  };
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use this ID to indicate the default state for properties that take a tab_id
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parameter.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kDefaultTabId;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Max size (both dimensions) for page actions.
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  static const int kPageActionIconMaxSize;
55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionAction(const std::string& extension_id,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  extensions::ActionInfo::Type action_type,
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  const extensions::ActionInfo& manifest_data);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ExtensionAction();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets a copy of this, ownership passed to caller.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It doesn't make sense to copy of an ExtensionAction except in tests.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionAction> CopyForTest() const;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given the extension action type, returns the size the extension action icon
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should have. The icon should be square, so only one dimension is
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returned.
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static int GetIconSizeForType(extensions::ActionInfo::Type type);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extension id
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& extension_id() const { return extension_id_; }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // What kind of action is this?
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  extensions::ActionInfo::Type action_type() const {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return action_type_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // action id -- only used with legacy page actions API
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id() const { return id_; }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_id(const std::string& id) { id_ = id; }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the url which the popup will load when the user clicks this action's
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // icon.  Setting an empty URL will disable the popup for a given tab.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetPopupUrl(int tab_id, const GURL& url);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use HasPopup() to see if a popup should be displayed.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasPopup(int tab_id) const;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the URL to display in a popup.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL GetPopupUrl(int tab_id) const;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set this action's title on a specific tab.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetTitle(int tab_id, const std::string& title) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetValue(&title_, tab_id, title);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If tab |tab_id| has a set title, return it.  Otherwise, return
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the default title.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string GetTitle(int tab_id) const { return GetValue(&title_, tab_id); }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Icons are a bit different because the default value can be set to either a
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bitmap or a path. However, conceptually, there is only one default icon.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setting the default icon using a path clears the bitmap and vice-versa.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To retrieve the icon for the extension action, use
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExtensionActionIconFactory.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set this action's icon bitmap on a specific tab.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetIcon(int tab_id, const gfx::Image& image);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Tries to parse |*icon| from a dictionary {"19": imageData19, "38":
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // imageData38}, returning false if a value is corrupt.
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static bool ParseIconFromCanvasDictionary(const base::DictionaryValue& dict,
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            gfx::ImageSkia* icon);
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the icon that has been set using |SetIcon| for the tab.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia GetExplicitlySetIcon(int tab_id) const;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Sets the icon for a tab, in a way that can't be read by the extension's
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // javascript.  Multiple icons can be set at the same time; some icon with the
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // highest priority will be used.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void DeclarativeSetIcon(int tab_id, int priority, const gfx::Image& icon);
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void UndoDeclarativeSetIcon(int tab_id, int priority, const gfx::Image& icon);
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-tab-specific icon path. This is used to support the default_icon key of
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // page and browser actions.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_default_icon(scoped_ptr<ExtensionIconSet> icon_set) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     default_icon_ = icon_set.Pass();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ExtensionIconSet* default_icon() const {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return default_icon_.get();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set this action's badge text on a specific tab.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetBadgeText(int tab_id, const std::string& text) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetValue(&badge_text_, tab_id, text);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the badge text for a tab, or the default if no badge text was set.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string GetBadgeText(int tab_id) const {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetValue(&badge_text_, tab_id);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set this action's badge text color on a specific tab.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetBadgeTextColor(int tab_id, SkColor text_color) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetValue(&badge_text_color_, tab_id, text_color);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the text color for a tab, or the default color if no text color
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was set.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor GetBadgeTextColor(int tab_id) const {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetValue(&badge_text_color_, tab_id);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set this action's badge background color on a specific tab.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetBadgeBackgroundColor(int tab_id, SkColor color) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetValue(&badge_background_color_, tab_id, color);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the badge background color for a tab, or the default if no color
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // was set.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor GetBadgeBackgroundColor(int tab_id) const {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetValue(&badge_background_color_, tab_id);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set this action's badge visibility on a specific tab.  Returns true if
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the visibility has changed.
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool SetIsVisible(int tab_id, bool value);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The declarative appearance overrides a default appearance but is overridden
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // by an appearance set directly on the tab.
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DeclarativeShow(int tab_id);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UndoDeclarativeShow(int tab_id);
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const gfx::ImageSkia GetDeclarativeIcon(int tab_id) const;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the badge visibility for a tab, or the default badge visibility
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // if none was set.
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Gets the visibility of |tab_id|.  Returns the first of: a specific
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // visibility set on the tab; a declarative visibility set on the tab; the
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // default visibility set for all tabs; or |false|.  Don't return this
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // result to an extension's background page because the declarative state can
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // leak information about hosts the extension doesn't have permission to
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // access.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool GetIsVisible(int tab_id) const {
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (const bool* tab_is_visible = FindOrNull(&is_visible_, tab_id))
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return *tab_is_visible;
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (ContainsKey(declarative_show_count_, tab_id))
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (const bool* default_is_visible =
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FindOrNull(&is_visible_, kDefaultTabId))
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return *default_is_visible;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove all tab-specific state.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClearAllValuesForTab(int tab_id);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the specified tab has a badge, paint it into the provided bounds.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PaintBadge(gfx::Canvas* canvas, const gfx::Rect& bounds, int tab_id);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns icon image with badge for specified tab.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia GetIconWithBadge(const gfx::ImageSkia& icon,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  int tab_id,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const gfx::Size& spacing) const;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Determine whether or not the ExtensionAction has a value set for the given
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // |tab_id| for each property.
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool HasPopupUrl(int tab_id) const;
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool HasTitle(int tab_id) const;
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool HasBadgeText(int tab_id) const;
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool HasBadgeBackgroundColor(int tab_id) const;
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool HasBadgeTextColor(int tab_id) const;
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool HasIsVisible(int tab_id) const;
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool HasIcon(int tab_id) const;
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns width of the current icon for tab_id.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(tbarzic): The icon selection is done in ExtensionActionIconFactory.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should probably move this there too.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetIconWidth(int tab_id) const;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <class T>
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ValueTraits {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static T CreateEmpty() {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return T();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<class T>
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetValue(std::map<int, T>* map, int tab_id, const T& val) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*map)[tab_id] = val;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  template<class Map>
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const typename Map::mapped_type* FindOrNull(
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const Map* map,
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const typename Map::key_type& key) {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    typename Map::const_iterator iter = map->find(key);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (iter == map->end())
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return &iter->second;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<class T>
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T GetValue(const std::map<int, T>* map, int tab_id) const {
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (const T* tab_value = FindOrNull(map, tab_id)) {
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return *tab_value;
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (const T* default_value = FindOrNull(map, kDefaultTabId)) {
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return *default_value;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return ValueTraits<T>::CreateEmpty();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The id for the extension this action belongs to (as defined in the
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extension manifest).
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string extension_id_;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const extensions::ActionInfo::Type action_type_;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Each of these data items can have both a global state (stored with the key
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kDefaultTabId), or tab-specific state (stored with the tab_id as the key).
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, GURL> popup_url_;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, std::string> title_;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, gfx::ImageSkia> icon_;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, std::string> badge_text_;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, SkColor> badge_background_color_;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<int, SkColor> badge_text_color_;
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::map<int, bool> is_visible_;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Declarative state exists for two reasons: First, we need to hide it from
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the extension's background/event page to avoid leaking data from hosts the
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // extension doesn't have permission to access.  Second, the action's state
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // gets both reset and given its declarative values in response to a
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // WebContentsObserver::DidNavigateMainFrame event, and there's no way to set
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those up to be called in the right order.
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Maps tab_id to the number of active (applied-but-not-reverted)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // declarativeContent.ShowPageAction actions.
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<int, int> declarative_show_count_;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // declarative_icon_[tab_id][declarative_rule_priority] is a vector of icon
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // images that are currently in effect
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::map<int, std::map<int, std::vector<gfx::Image> > > declarative_icon_;
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExtensionIconSet containing paths to bitmaps from which default icon's
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // image representations will be selected.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<const ExtensionIconSet> default_icon_;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The id for the ExtensionAction, for example: "RssPageAction". This is
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // needed for compat with an older version of the page actions API.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id_;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExtensionAction);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ExtensionAction::ValueTraits<int> {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int CreateEmpty() {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_ACTION_H_
304