[Extensions] Make DeclarativeContent ContentAction's type-agnostic

Make the DeclarativeContent API's ContentActions agnostic to the type
of action the extension has, instead using any action associated with
the extension (whether it's a page action, browser action, or action).

Bug: 893373
Change-Id: I030d7670f314f5359167af7d7dfc3c2ca6164ba8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1564802
Commit-Queue: Devlin <rdevlin.cronin@chromium.org>
Reviewed-by: Karan Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#651082}
diff --git a/chrome/browser/extensions/api/declarative_content/content_action.cc b/chrome/browser/extensions/api/declarative_content/content_action.cc
index a067334..55c667746 100644
--- a/chrome/browser/extensions/api/declarative_content/content_action.cc
+++ b/chrome/browser/extensions/api/declarative_content/content_action.cc
@@ -69,8 +69,7 @@
     // TODO(devlin): We should probably throw an error if the extension has no
     // action specified in the manifest. Currently, this is allowed since
     // extensions will have a synthesized page action.
-    if (!ActionInfo::GetPageActionInfo(extension) &&
-        !ActionInfo::GetBrowserActionInfo(extension)) {
+    if (!ActionInfo::GetAnyActionInfo(extension)) {
       *error = kNoAction;
       return nullptr;
     }
@@ -109,8 +108,7 @@
 // Action that sets an extension's action icon.
 class SetIcon : public ContentAction {
  public:
-  SetIcon(const gfx::Image& icon, ActionInfo::Type action_type)
-      : icon_(icon), action_type_(action_type) {}
+  explicit SetIcon(const gfx::Image& icon) : icon_(icon) {}
   ~SetIcon() override {}
 
   static std::unique_ptr<ContentAction> Create(
@@ -152,20 +150,10 @@
  private:
   ExtensionAction* GetExtensionAction(Profile* profile,
                                       const Extension* extension) const {
-    switch (action_type_) {
-      case ActionInfo::TYPE_BROWSER:
-        return ExtensionActionManager::Get(profile)
-            ->GetBrowserAction(*extension);
-      case ActionInfo::TYPE_PAGE:
-        return ExtensionActionManager::Get(profile)->GetPageAction(*extension);
-      default:
-        NOTREACHED();
-    }
-    return NULL;
+    return ExtensionActionManager::Get(profile)->GetExtensionAction(*extension);
   }
 
   gfx::Image icon_;
-  ActionInfo::Type action_type_;
 
   DISALLOW_COPY_AND_ASSIGN(SetIcon);
 };
@@ -398,12 +386,7 @@
     const base::DictionaryValue* dict,
     std::string* error) {
   // We can't set a page or action's icon if the extension doesn't have one.
-  ActionInfo::Type type;
-  if (ActionInfo::GetPageActionInfo(extension) != NULL) {
-    type = ActionInfo::TYPE_PAGE;
-  } else if (ActionInfo::GetBrowserActionInfo(extension) != NULL) {
-    type = ActionInfo::TYPE_BROWSER;
-  } else {
+  if (!ActionInfo::GetAnyActionInfo(extension)) {
     *error = kNoPageOrBrowserAction;
     return nullptr;
   }
@@ -431,7 +414,7 @@
     *error = kIconNotSufficientlyVisible;
     return nullptr;
   }
-  return base::WrapUnique(new SetIcon(image, type));
+  return std::make_unique<SetIcon>(image);
 }
 
 //
diff --git a/chrome/common/extensions/api/extension_action/action_info.cc b/chrome/common/extensions/api/extension_action/action_info.cc
index a47cccf..d108f433 100644
--- a/chrome/common/extensions/api/extension_action/action_info.cc
+++ b/chrome/common/extensions/api/extension_action/action_info.cc
@@ -135,6 +135,20 @@
 }
 
 // static
+const ActionInfo* ActionInfo::GetAnyActionInfo(const Extension* extension) {
+  // TODO(devlin): Since all actions are mutually exclusive, we can store
+  // them all under the same key. For now, we don't do that because some callers
+  // need to differentiate between action types.
+  const ActionInfo* info = GetActionInfo(extension, keys::kBrowserAction);
+  if (info)
+    return info;
+  info = GetActionInfo(extension, keys::kPageAction);
+  if (info)
+    return info;
+  return GetActionInfo(extension, keys::kAction);
+}
+
+// static
 const ActionInfo* ActionInfo::GetExtensionActionInfo(
     const Extension* extension) {
   return GetActionInfo(extension, keys::kAction);
diff --git a/chrome/common/extensions/api/extension_action/action_info.h b/chrome/common/extensions/api/extension_action/action_info.h
index eaa0ed0..6be0b7b 100644
--- a/chrome/common/extensions/api/extension_action/action_info.h
+++ b/chrome/common/extensions/api/extension_action/action_info.h
@@ -43,6 +43,13 @@
                                           const base::DictionaryValue* dict,
                                           base::string16* error);
 
+  // Returns any action associated with the extension, whether it's specified
+  // under the "page_action", "browser_action", or "action" key (note this does
+  // *not* check system indicator).
+  // TODO(devlin): This is a crutch while moving away from the distinct action
+  // types. Remove it when that's done.
+  static const ActionInfo* GetAnyActionInfo(const Extension* extension);
+
   // Returns the action specified under the "action" key, if any.
   static const ActionInfo* GetExtensionActionInfo(const Extension* extension);