1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/extensions/manifest_handlers/extension_action_handler.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/values.h"
10 #include "chrome/common/extensions/api/extension_action/action_info.h"
11 #include "chrome/common/extensions/extension_constants.h"
12 #include "chrome/grit/generated_resources.h"
13 #include "extensions/common/extension.h"
14 #include "extensions/common/feature_switch.h"
15 #include "extensions/common/file_util.h"
16 #include "extensions/common/manifest_constants.h"
18 namespace extensions
{
20 ExtensionActionHandler::ExtensionActionHandler() {
23 ExtensionActionHandler::~ExtensionActionHandler() {
26 bool ExtensionActionHandler::Parse(Extension
* extension
,
27 base::string16
* error
) {
28 const char* key
= NULL
;
29 const char* error_key
= NULL
;
30 if (extension
->manifest()->HasKey(manifest_keys::kPageAction
)) {
31 key
= manifest_keys::kPageAction
;
32 error_key
= manifest_errors::kInvalidPageAction
;
35 if (extension
->manifest()->HasKey(manifest_keys::kBrowserAction
)) {
37 // An extension cannot have both browser and page actions.
38 *error
= base::ASCIIToUTF16(manifest_errors::kOneUISurfaceOnly
);
41 key
= manifest_keys::kBrowserAction
;
42 error_key
= manifest_errors::kInvalidBrowserAction
;
46 const base::DictionaryValue
* dict
= NULL
;
47 if (!extension
->manifest()->GetDictionary(key
, &dict
)) {
48 *error
= base::ASCIIToUTF16(error_key
);
52 scoped_ptr
<ActionInfo
> action_info
=
53 ActionInfo::Load(extension
, dict
, error
);
55 return false; // Failed to parse extension action definition.
57 if (key
== manifest_keys::kPageAction
)
58 ActionInfo::SetPageActionInfo(extension
, action_info
.release());
60 ActionInfo::SetBrowserActionInfo(extension
, action_info
.release());
61 } else { // No key, used for synthesizing an action for extensions with none.
62 if (!FeatureSwitch::extension_action_redesign()->IsEnabled())
63 return true; // Do nothing if the switch is off.
64 if (Manifest::IsComponentLocation(extension
->location()))
65 return true; // Don't synthesize actions for component extensions.
66 if (extension
->manifest()->HasKey(
67 manifest_keys::kSynthesizeExtensionAction
)) {
68 *error
= base::ASCIIToUTF16(base::StringPrintf(
69 "Key %s is reserved.", manifest_keys::kSynthesizeExtensionAction
));
70 return false; // No one should use this key.
73 // Set an empty page action. We use a page action (instead of a browser
74 // action) because the action should not be seen as enabled on every page.
75 ActionInfo::SetPageActionInfo(extension
, new ActionInfo());
81 bool ExtensionActionHandler::Validate(
82 const Extension
* extension
,
84 std::vector
<InstallWarning
>* warnings
) const {
85 int error_message
= 0;
86 const ActionInfo
* action
= ActionInfo::GetPageActionInfo(extension
);
88 error_message
= IDS_EXTENSION_LOAD_ICON_FOR_PAGE_ACTION_FAILED
;
90 action
= ActionInfo::GetBrowserActionInfo(extension
);
91 error_message
= IDS_EXTENSION_LOAD_ICON_FOR_BROWSER_ACTION_FAILED
;
94 if (action
&& !action
->default_icon
.empty() &&
95 !file_util::ValidateExtensionIconSet(
96 action
->default_icon
, extension
, error_message
, error
)) {
102 bool ExtensionActionHandler::AlwaysParseForType(Manifest::Type type
) const {
103 return type
== Manifest::TYPE_EXTENSION
;
106 const std::vector
<std::string
> ExtensionActionHandler::Keys() const {
107 std::vector
<std::string
> keys
;
108 keys
.push_back(manifest_keys::kPageAction
);
109 keys
.push_back(manifest_keys::kBrowserAction
);
110 keys
.push_back(manifest_keys::kSynthesizeExtensionAction
);
114 } // namespace extensions