| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/extensions/api/extension_action/action_info.h" | 5 #include "chrome/common/extensions/api/extension_action/action_info.h" |
| 6 | 6 |
| 7 #include "base/memory/scoped_ptr.h" | 7 #include <memory> |
| 8 |
| 8 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/common/extensions/api/commands/commands_handler.h" | 10 #include "chrome/common/extensions/api/commands/commands_handler.h" |
| 10 #include "extensions/common/constants.h" | 11 #include "extensions/common/constants.h" |
| 11 #include "extensions/common/error_utils.h" | 12 #include "extensions/common/error_utils.h" |
| 12 #include "extensions/common/extension.h" | 13 #include "extensions/common/extension.h" |
| 13 #include "extensions/common/manifest_constants.h" | 14 #include "extensions/common/manifest_constants.h" |
| 14 #include "extensions/common/manifest_handler_helpers.h" | 15 #include "extensions/common/manifest_handler_helpers.h" |
| 15 | 16 |
| 16 namespace extensions { | 17 namespace extensions { |
| 17 | 18 |
| 18 namespace errors = manifest_errors; | 19 namespace errors = manifest_errors; |
| 19 namespace keys = manifest_keys; | 20 namespace keys = manifest_keys; |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 // The manifest data container for the ActionInfos for BrowserActions, | 24 // The manifest data container for the ActionInfos for BrowserActions, |
| 24 // PageActions and SystemIndicators. | 25 // PageActions and SystemIndicators. |
| 25 struct ActionInfoData : public Extension::ManifestData { | 26 struct ActionInfoData : public Extension::ManifestData { |
| 26 explicit ActionInfoData(ActionInfo* action_info); | 27 explicit ActionInfoData(ActionInfo* action_info); |
| 27 ~ActionInfoData() override; | 28 ~ActionInfoData() override; |
| 28 | 29 |
| 29 // The action associated with the BrowserAction. | 30 // The action associated with the BrowserAction. |
| 30 scoped_ptr<ActionInfo> action_info; | 31 std::unique_ptr<ActionInfo> action_info; |
| 31 }; | 32 }; |
| 32 | 33 |
| 33 ActionInfoData::ActionInfoData(ActionInfo* info) : action_info(info) { | 34 ActionInfoData::ActionInfoData(ActionInfo* info) : action_info(info) { |
| 34 } | 35 } |
| 35 | 36 |
| 36 ActionInfoData::~ActionInfoData() { | 37 ActionInfoData::~ActionInfoData() { |
| 37 } | 38 } |
| 38 | 39 |
| 39 static const ActionInfo* GetActionInfo(const Extension* extension, | 40 static const ActionInfo* GetActionInfo(const Extension* extension, |
| 40 const std::string& key) { | 41 const std::string& key) { |
| 41 ActionInfoData* data = static_cast<ActionInfoData*>( | 42 ActionInfoData* data = static_cast<ActionInfoData*>( |
| 42 extension->GetManifestData(key)); | 43 extension->GetManifestData(key)); |
| 43 return data ? data->action_info.get() : NULL; | 44 return data ? data->action_info.get() : NULL; |
| 44 } | 45 } |
| 45 | 46 |
| 46 } // namespace | 47 } // namespace |
| 47 | 48 |
| 48 ActionInfo::ActionInfo() : synthesized(false) {} | 49 ActionInfo::ActionInfo() : synthesized(false) {} |
| 49 | 50 |
| 50 ActionInfo::ActionInfo(const ActionInfo& other) = default; | 51 ActionInfo::ActionInfo(const ActionInfo& other) = default; |
| 51 | 52 |
| 52 ActionInfo::~ActionInfo() { | 53 ActionInfo::~ActionInfo() { |
| 53 } | 54 } |
| 54 | 55 |
| 55 // static | 56 // static |
| 56 scoped_ptr<ActionInfo> ActionInfo::Load(const Extension* extension, | 57 std::unique_ptr<ActionInfo> ActionInfo::Load(const Extension* extension, |
| 57 const base::DictionaryValue* dict, | 58 const base::DictionaryValue* dict, |
| 58 base::string16* error) { | 59 base::string16* error) { |
| 59 scoped_ptr<ActionInfo> result(new ActionInfo()); | 60 std::unique_ptr<ActionInfo> result(new ActionInfo()); |
| 60 | 61 |
| 61 if (extension->manifest_version() == 1) { | 62 if (extension->manifest_version() == 1) { |
| 62 // kPageActionIcons is obsolete, and used by very few extensions. Continue | 63 // kPageActionIcons is obsolete, and used by very few extensions. Continue |
| 63 // loading it, but only take the first icon as the default_icon path. | 64 // loading it, but only take the first icon as the default_icon path. |
| 64 const base::ListValue* icons = NULL; | 65 const base::ListValue* icons = NULL; |
| 65 if (dict->HasKey(keys::kPageActionIcons) && | 66 if (dict->HasKey(keys::kPageActionIcons) && |
| 66 dict->GetList(keys::kPageActionIcons, &icons)) { | 67 dict->GetList(keys::kPageActionIcons, &icons)) { |
| 67 base::ListValue::const_iterator iter = icons->begin(); | 68 base::ListValue::const_iterator iter = icons->begin(); |
| 68 std::string path; | 69 std::string path; |
| 69 if (iter == icons->end() || | 70 if (iter == icons->end() || |
| 70 !(*iter)->GetAsString(&path) || | 71 !(*iter)->GetAsString(&path) || |
| 71 !manifest_handler_helpers::NormalizeAndValidatePath(&path)) { | 72 !manifest_handler_helpers::NormalizeAndValidatePath(&path)) { |
| 72 *error = base::ASCIIToUTF16(errors::kInvalidPageActionIconPath); | 73 *error = base::ASCIIToUTF16(errors::kInvalidPageActionIconPath); |
| 73 return scoped_ptr<ActionInfo>(); | 74 return std::unique_ptr<ActionInfo>(); |
| 74 } | 75 } |
| 75 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, path); | 76 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, path); |
| 76 } | 77 } |
| 77 | 78 |
| 78 std::string id; | 79 std::string id; |
| 79 if (dict->HasKey(keys::kPageActionId)) { | 80 if (dict->HasKey(keys::kPageActionId)) { |
| 80 if (!dict->GetString(keys::kPageActionId, &id)) { | 81 if (!dict->GetString(keys::kPageActionId, &id)) { |
| 81 *error = base::ASCIIToUTF16(errors::kInvalidPageActionId); | 82 *error = base::ASCIIToUTF16(errors::kInvalidPageActionId); |
| 82 return scoped_ptr<ActionInfo>(); | 83 return std::unique_ptr<ActionInfo>(); |
| 83 } | 84 } |
| 84 result->id = id; | 85 result->id = id; |
| 85 } | 86 } |
| 86 } | 87 } |
| 87 | 88 |
| 88 // Read the page action |default_icon| (optional). | 89 // Read the page action |default_icon| (optional). |
| 89 // The |default_icon| value can be either dictionary {icon size -> icon path} | 90 // The |default_icon| value can be either dictionary {icon size -> icon path} |
| 90 // or non empty string value. | 91 // or non empty string value. |
| 91 if (dict->HasKey(keys::kPageActionDefaultIcon)) { | 92 if (dict->HasKey(keys::kPageActionDefaultIcon)) { |
| 92 const base::DictionaryValue* icons_value = NULL; | 93 const base::DictionaryValue* icons_value = NULL; |
| 93 std::string default_icon; | 94 std::string default_icon; |
| 94 if (dict->GetDictionary(keys::kPageActionDefaultIcon, &icons_value)) { | 95 if (dict->GetDictionary(keys::kPageActionDefaultIcon, &icons_value)) { |
| 95 if (!manifest_handler_helpers::LoadIconsFromDictionary( | 96 if (!manifest_handler_helpers::LoadIconsFromDictionary( |
| 96 icons_value, &result->default_icon, error)) { | 97 icons_value, &result->default_icon, error)) { |
| 97 return scoped_ptr<ActionInfo>(); | 98 return std::unique_ptr<ActionInfo>(); |
| 98 } | 99 } |
| 99 } else if (dict->GetString(keys::kPageActionDefaultIcon, &default_icon) && | 100 } else if (dict->GetString(keys::kPageActionDefaultIcon, &default_icon) && |
| 100 manifest_handler_helpers::NormalizeAndValidatePath( | 101 manifest_handler_helpers::NormalizeAndValidatePath( |
| 101 &default_icon)) { | 102 &default_icon)) { |
| 102 // Choose the most optimistic (highest) icon density regardless of the | 103 // Choose the most optimistic (highest) icon density regardless of the |
| 103 // actual icon resolution, whatever that happens to be. Code elsewhere | 104 // actual icon resolution, whatever that happens to be. Code elsewhere |
| 104 // knows how to scale down to 19. | 105 // knows how to scale down to 19. |
| 105 result->default_icon.Add(extension_misc::EXTENSION_ICON_GIGANTOR, | 106 result->default_icon.Add(extension_misc::EXTENSION_ICON_GIGANTOR, |
| 106 default_icon); | 107 default_icon); |
| 107 } else { | 108 } else { |
| 108 *error = base::ASCIIToUTF16(errors::kInvalidPageActionIconPath); | 109 *error = base::ASCIIToUTF16(errors::kInvalidPageActionIconPath); |
| 109 return scoped_ptr<ActionInfo>(); | 110 return std::unique_ptr<ActionInfo>(); |
| 110 } | 111 } |
| 111 } | 112 } |
| 112 | 113 |
| 113 // Read the page action title from |default_title| if present, |name| if not | 114 // Read the page action title from |default_title| if present, |name| if not |
| 114 // (both optional). | 115 // (both optional). |
| 115 if (dict->HasKey(keys::kPageActionDefaultTitle)) { | 116 if (dict->HasKey(keys::kPageActionDefaultTitle)) { |
| 116 if (!dict->GetString(keys::kPageActionDefaultTitle, | 117 if (!dict->GetString(keys::kPageActionDefaultTitle, |
| 117 &result->default_title)) { | 118 &result->default_title)) { |
| 118 *error = base::ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); | 119 *error = base::ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); |
| 119 return scoped_ptr<ActionInfo>(); | 120 return std::unique_ptr<ActionInfo>(); |
| 120 } | 121 } |
| 121 } else if (extension->manifest_version() == 1 && dict->HasKey(keys::kName)) { | 122 } else if (extension->manifest_version() == 1 && dict->HasKey(keys::kName)) { |
| 122 if (!dict->GetString(keys::kName, &result->default_title)) { | 123 if (!dict->GetString(keys::kName, &result->default_title)) { |
| 123 *error = base::ASCIIToUTF16(errors::kInvalidPageActionName); | 124 *error = base::ASCIIToUTF16(errors::kInvalidPageActionName); |
| 124 return scoped_ptr<ActionInfo>(); | 125 return std::unique_ptr<ActionInfo>(); |
| 125 } | 126 } |
| 126 } | 127 } |
| 127 | 128 |
| 128 // Read the action's |popup| (optional). | 129 // Read the action's |popup| (optional). |
| 129 const char* popup_key = NULL; | 130 const char* popup_key = NULL; |
| 130 if (dict->HasKey(keys::kPageActionDefaultPopup)) | 131 if (dict->HasKey(keys::kPageActionDefaultPopup)) |
| 131 popup_key = keys::kPageActionDefaultPopup; | 132 popup_key = keys::kPageActionDefaultPopup; |
| 132 | 133 |
| 133 if (extension->manifest_version() == 1 && | 134 if (extension->manifest_version() == 1 && |
| 134 dict->HasKey(keys::kPageActionPopup)) { | 135 dict->HasKey(keys::kPageActionPopup)) { |
| 135 if (popup_key) { | 136 if (popup_key) { |
| 136 *error = ErrorUtils::FormatErrorMessageUTF16( | 137 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 137 errors::kInvalidPageActionOldAndNewKeys, | 138 errors::kInvalidPageActionOldAndNewKeys, |
| 138 keys::kPageActionDefaultPopup, | 139 keys::kPageActionDefaultPopup, |
| 139 keys::kPageActionPopup); | 140 keys::kPageActionPopup); |
| 140 return scoped_ptr<ActionInfo>(); | 141 return std::unique_ptr<ActionInfo>(); |
| 141 } | 142 } |
| 142 popup_key = keys::kPageActionPopup; | 143 popup_key = keys::kPageActionPopup; |
| 143 } | 144 } |
| 144 | 145 |
| 145 if (popup_key) { | 146 if (popup_key) { |
| 146 const base::DictionaryValue* popup = NULL; | 147 const base::DictionaryValue* popup = NULL; |
| 147 std::string url_str; | 148 std::string url_str; |
| 148 | 149 |
| 149 if (dict->GetString(popup_key, &url_str)) { | 150 if (dict->GetString(popup_key, &url_str)) { |
| 150 // On success, |url_str| is set. Nothing else to do. | 151 // On success, |url_str| is set. Nothing else to do. |
| 151 } else if (extension->manifest_version() == 1 && | 152 } else if (extension->manifest_version() == 1 && |
| 152 dict->GetDictionary(popup_key, &popup)) { | 153 dict->GetDictionary(popup_key, &popup)) { |
| 153 if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) { | 154 if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) { |
| 154 *error = ErrorUtils::FormatErrorMessageUTF16( | 155 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 155 errors::kInvalidPageActionPopupPath, "<missing>"); | 156 errors::kInvalidPageActionPopupPath, "<missing>"); |
| 156 return scoped_ptr<ActionInfo>(); | 157 return std::unique_ptr<ActionInfo>(); |
| 157 } | 158 } |
| 158 } else { | 159 } else { |
| 159 *error = base::ASCIIToUTF16(errors::kInvalidPageActionPopup); | 160 *error = base::ASCIIToUTF16(errors::kInvalidPageActionPopup); |
| 160 return scoped_ptr<ActionInfo>(); | 161 return std::unique_ptr<ActionInfo>(); |
| 161 } | 162 } |
| 162 | 163 |
| 163 if (!url_str.empty()) { | 164 if (!url_str.empty()) { |
| 164 // An empty string is treated as having no popup. | 165 // An empty string is treated as having no popup. |
| 165 result->default_popup_url = Extension::GetResourceURL(extension->url(), | 166 result->default_popup_url = Extension::GetResourceURL(extension->url(), |
| 166 url_str); | 167 url_str); |
| 167 if (!result->default_popup_url.is_valid()) { | 168 if (!result->default_popup_url.is_valid()) { |
| 168 *error = ErrorUtils::FormatErrorMessageUTF16( | 169 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 169 errors::kInvalidPageActionPopupPath, url_str); | 170 errors::kInvalidPageActionPopupPath, url_str); |
| 170 return scoped_ptr<ActionInfo>(); | 171 return std::unique_ptr<ActionInfo>(); |
| 171 } | 172 } |
| 172 } else { | 173 } else { |
| 173 DCHECK(result->default_popup_url.is_empty()) | 174 DCHECK(result->default_popup_url.is_empty()) |
| 174 << "Shouldn't be possible for the popup to be set."; | 175 << "Shouldn't be possible for the popup to be set."; |
| 175 } | 176 } |
| 176 } | 177 } |
| 177 | 178 |
| 178 return result; | 179 return result; |
| 179 } | 180 } |
| 180 | 181 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 | 214 |
| 214 // static | 215 // static |
| 215 bool ActionInfo::IsVerboseInstallMessage(const Extension* extension) { | 216 bool ActionInfo::IsVerboseInstallMessage(const Extension* extension) { |
| 216 const ActionInfo* page_action_info = GetPageActionInfo(extension); | 217 const ActionInfo* page_action_info = GetPageActionInfo(extension); |
| 217 return page_action_info && | 218 return page_action_info && |
| 218 (CommandsInfo::GetPageActionCommand(extension) || | 219 (CommandsInfo::GetPageActionCommand(extension) || |
| 219 !page_action_info->default_icon.empty()); | 220 !page_action_info->default_icon.empty()); |
| 220 } | 221 } |
| 221 | 222 |
| 222 } // namespace extensions | 223 } // namespace extensions |
| OLD | NEW |