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 "base/memory/scoped_ptr.h" |
| 8 #include "base/utf_string_conversions.h" |
8 #include "chrome/common/extensions/api/commands/commands_handler.h" | 9 #include "chrome/common/extensions/api/commands/commands_handler.h" |
9 #include "chrome/common/extensions/extension.h" | 10 #include "chrome/common/extensions/extension.h" |
10 #include "chrome/common/extensions/extension_manifest_constants.h" | 11 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 12 #include "chrome/common/extensions/manifest_handler_helpers.h" |
| 13 #include "extensions/common/error_utils.h" |
| 14 |
| 15 namespace errors = extension_manifest_errors; |
| 16 namespace keys = extension_manifest_keys; |
11 | 17 |
12 namespace extensions { | 18 namespace extensions { |
13 | 19 |
14 namespace { | 20 namespace { |
15 | 21 |
16 // The manifest data container for the ActionInfos for BrowserActions and | 22 // The manifest data container for the ActionInfos for BrowserActions and |
17 // ScriptBadges. | 23 // ScriptBadges. |
18 struct ActionInfoData : public Extension::ManifestData { | 24 struct ActionInfoData : public Extension::ManifestData { |
19 explicit ActionInfoData(ActionInfo* action_info); | 25 explicit ActionInfoData(ActionInfo* action_info); |
20 virtual ~ActionInfoData(); | 26 virtual ~ActionInfoData(); |
(...skipping 18 matching lines...) Expand all Loading... |
39 | 45 |
40 } // namespace | 46 } // namespace |
41 | 47 |
42 ActionInfo::ActionInfo() { | 48 ActionInfo::ActionInfo() { |
43 } | 49 } |
44 | 50 |
45 ActionInfo::~ActionInfo() { | 51 ActionInfo::~ActionInfo() { |
46 } | 52 } |
47 | 53 |
48 // static | 54 // static |
| 55 scoped_ptr<ActionInfo> ActionInfo::Load(const Extension* extension, |
| 56 const base::DictionaryValue* dict, |
| 57 string16* error) { |
| 58 scoped_ptr<ActionInfo> result(new ActionInfo()); |
| 59 |
| 60 if (extension->manifest_version() == 1) { |
| 61 // kPageActionIcons is obsolete, and used by very few extensions. Continue |
| 62 // loading it, but only take the first icon as the default_icon path. |
| 63 const ListValue* icons = NULL; |
| 64 if (dict->HasKey(keys::kPageActionIcons) && |
| 65 dict->GetList(keys::kPageActionIcons, &icons)) { |
| 66 for (ListValue::const_iterator iter = icons->begin(); |
| 67 iter != icons->end(); ++iter) { |
| 68 std::string path; |
| 69 if (!(*iter)->GetAsString(&path) || |
| 70 !manifest_handler_helpers::NormalizeAndValidatePath(&path)) { |
| 71 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); |
| 72 return scoped_ptr<ActionInfo>(); |
| 73 } |
| 74 |
| 75 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, path); |
| 76 break; |
| 77 } |
| 78 } |
| 79 |
| 80 std::string id; |
| 81 if (dict->HasKey(keys::kPageActionId)) { |
| 82 if (!dict->GetString(keys::kPageActionId, &id)) { |
| 83 *error = ASCIIToUTF16(errors::kInvalidPageActionId); |
| 84 return scoped_ptr<ActionInfo>(); |
| 85 } |
| 86 result->id = id; |
| 87 } |
| 88 } |
| 89 |
| 90 // Read the page action |default_icon| (optional). |
| 91 // The |default_icon| value can be either dictionary {icon size -> icon path} |
| 92 // or non empty string value. |
| 93 if (dict->HasKey(keys::kPageActionDefaultIcon)) { |
| 94 const DictionaryValue* icons_value = NULL; |
| 95 std::string default_icon; |
| 96 if (dict->GetDictionary(keys::kPageActionDefaultIcon, &icons_value)) { |
| 97 if (!manifest_handler_helpers::LoadIconsFromDictionary( |
| 98 icons_value, |
| 99 extension_misc::kExtensionActionIconSizes, |
| 100 extension_misc::kNumExtensionActionIconSizes, |
| 101 &result->default_icon, |
| 102 error)) { |
| 103 return scoped_ptr<ActionInfo>(); |
| 104 } |
| 105 } else if (dict->GetString(keys::kPageActionDefaultIcon, &default_icon) && |
| 106 manifest_handler_helpers::NormalizeAndValidatePath( |
| 107 &default_icon)) { |
| 108 result->default_icon.Add(extension_misc::EXTENSION_ICON_ACTION, |
| 109 default_icon); |
| 110 } else { |
| 111 *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath); |
| 112 return scoped_ptr<ActionInfo>(); |
| 113 } |
| 114 } |
| 115 |
| 116 // Read the page action title from |default_title| if present, |name| if not |
| 117 // (both optional). |
| 118 if (dict->HasKey(keys::kPageActionDefaultTitle)) { |
| 119 if (!dict->GetString(keys::kPageActionDefaultTitle, |
| 120 &result->default_title)) { |
| 121 *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle); |
| 122 return scoped_ptr<ActionInfo>(); |
| 123 } |
| 124 } else if (extension->manifest_version() == 1 && dict->HasKey(keys::kName)) { |
| 125 if (!dict->GetString(keys::kName, &result->default_title)) { |
| 126 *error = ASCIIToUTF16(errors::kInvalidPageActionName); |
| 127 return scoped_ptr<ActionInfo>(); |
| 128 } |
| 129 } |
| 130 |
| 131 // Read the action's |popup| (optional). |
| 132 const char* popup_key = NULL; |
| 133 if (dict->HasKey(keys::kPageActionDefaultPopup)) |
| 134 popup_key = keys::kPageActionDefaultPopup; |
| 135 |
| 136 if (extension->manifest_version() == 1 && |
| 137 dict->HasKey(keys::kPageActionPopup)) { |
| 138 if (popup_key) { |
| 139 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 140 errors::kInvalidPageActionOldAndNewKeys, |
| 141 keys::kPageActionDefaultPopup, |
| 142 keys::kPageActionPopup); |
| 143 return scoped_ptr<ActionInfo>(); |
| 144 } |
| 145 popup_key = keys::kPageActionPopup; |
| 146 } |
| 147 |
| 148 if (popup_key) { |
| 149 const DictionaryValue* popup = NULL; |
| 150 std::string url_str; |
| 151 |
| 152 if (dict->GetString(popup_key, &url_str)) { |
| 153 // On success, |url_str| is set. Nothing else to do. |
| 154 } else if (extension->manifest_version() == 1 && |
| 155 dict->GetDictionary(popup_key, &popup)) { |
| 156 if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) { |
| 157 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 158 errors::kInvalidPageActionPopupPath, "<missing>"); |
| 159 return scoped_ptr<ActionInfo>(); |
| 160 } |
| 161 } else { |
| 162 *error = ASCIIToUTF16(errors::kInvalidPageActionPopup); |
| 163 return scoped_ptr<ActionInfo>(); |
| 164 } |
| 165 |
| 166 if (!url_str.empty()) { |
| 167 // An empty string is treated as having no popup. |
| 168 result->default_popup_url = Extension::GetResourceURL(extension->url(), |
| 169 url_str); |
| 170 if (!result->default_popup_url.is_valid()) { |
| 171 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 172 errors::kInvalidPageActionPopupPath, url_str); |
| 173 return scoped_ptr<ActionInfo>(); |
| 174 } |
| 175 } else { |
| 176 DCHECK(result->default_popup_url.is_empty()) |
| 177 << "Shouldn't be possible for the popup to be set."; |
| 178 } |
| 179 } |
| 180 |
| 181 return result.Pass(); |
| 182 } |
| 183 |
| 184 // static |
49 const ActionInfo* ActionInfo::GetBrowserActionInfo(const Extension* extension) { | 185 const ActionInfo* ActionInfo::GetBrowserActionInfo(const Extension* extension) { |
50 return GetActionInfo(extension, extension_manifest_keys::kBrowserAction); | 186 return GetActionInfo(extension, keys::kBrowserAction); |
51 } | 187 } |
52 | 188 |
53 const ActionInfo* ActionInfo::GetPageActionInfo(const Extension* extension) { | 189 const ActionInfo* ActionInfo::GetPageActionInfo(const Extension* extension) { |
54 return GetActionInfo(extension, extension_manifest_keys::kPageAction); | 190 return GetActionInfo(extension, keys::kPageAction); |
55 } | 191 } |
56 | 192 |
57 // static | 193 // static |
58 const ActionInfo* ActionInfo::GetScriptBadgeInfo(const Extension* extension) { | 194 const ActionInfo* ActionInfo::GetScriptBadgeInfo(const Extension* extension) { |
59 return GetActionInfo(extension, extension_manifest_keys::kScriptBadge); | 195 return GetActionInfo(extension, keys::kScriptBadge); |
60 } | 196 } |
61 | 197 |
62 // static | 198 // static |
63 const ActionInfo* ActionInfo::GetPageLauncherInfo(const Extension* extension) { | 199 const ActionInfo* ActionInfo::GetPageLauncherInfo(const Extension* extension) { |
64 return GetActionInfo(extension, extension_manifest_keys::kPageLauncher); | 200 return GetActionInfo(extension, keys::kPageLauncher); |
| 201 } |
| 202 |
| 203 // static |
| 204 const ActionInfo* ActionInfo::GetSystemIndicatorInfo( |
| 205 const Extension* extension) { |
| 206 return GetActionInfo(extension, keys::kSystemIndicator); |
65 } | 207 } |
66 | 208 |
67 // static | 209 // static |
68 void ActionInfo::SetBrowserActionInfo(Extension* extension, ActionInfo* info) { | 210 void ActionInfo::SetBrowserActionInfo(Extension* extension, ActionInfo* info) { |
69 extension->SetManifestData(extension_manifest_keys::kBrowserAction, | 211 extension->SetManifestData(keys::kBrowserAction, |
70 new ActionInfoData(info)); | 212 new ActionInfoData(info)); |
71 } | 213 } |
72 | 214 |
73 // static | 215 // static |
74 void ActionInfo::SetPageActionInfo(Extension* extension, ActionInfo* info) { | 216 void ActionInfo::SetPageActionInfo(Extension* extension, ActionInfo* info) { |
75 extension->SetManifestData(extension_manifest_keys::kPageAction, | 217 extension->SetManifestData(keys::kPageAction, |
76 new ActionInfoData(info)); | 218 new ActionInfoData(info)); |
77 } | 219 } |
78 | 220 |
79 // static | 221 // static |
80 void ActionInfo::SetScriptBadgeInfo(Extension* extension, ActionInfo* info) { | 222 void ActionInfo::SetScriptBadgeInfo(Extension* extension, ActionInfo* info) { |
81 extension->SetManifestData(extension_manifest_keys::kScriptBadge, | 223 extension->SetManifestData(keys::kScriptBadge, |
82 new ActionInfoData(info)); | 224 new ActionInfoData(info)); |
83 } | 225 } |
84 | 226 |
85 // static | 227 // static |
86 void ActionInfo::SetPageLauncherInfo(Extension* extension, ActionInfo* info) { | 228 void ActionInfo::SetPageLauncherInfo(Extension* extension, ActionInfo* info) { |
87 extension->SetManifestData(extension_manifest_keys::kPageLauncher, | 229 extension->SetManifestData(keys::kPageLauncher, new ActionInfoData(info)); |
88 new ActionInfoData(info)); | |
89 } | 230 } |
90 | 231 |
91 // static | 232 // static |
| 233 void ActionInfo::SetSystemIndicatorInfo(Extension* extension, |
| 234 ActionInfo* info) { |
| 235 extension->SetManifestData(keys::kSystemIndicator, new ActionInfoData(info)); |
| 236 } |
| 237 |
| 238 // static |
92 bool ActionInfo::IsVerboseInstallMessage(const Extension* extension) { | 239 bool ActionInfo::IsVerboseInstallMessage(const Extension* extension) { |
93 const ActionInfo* page_action_info = GetPageActionInfo(extension); | 240 const ActionInfo* page_action_info = GetPageActionInfo(extension); |
94 return page_action_info && | 241 return page_action_info && |
95 (CommandsInfo::GetPageActionCommand(extension) || | 242 (CommandsInfo::GetPageActionCommand(extension) || |
96 !page_action_info->default_icon.empty()); | 243 !page_action_info->default_icon.empty()); |
97 } | 244 } |
98 | 245 |
99 } // namespace extensions | 246 } // namespace extensions |
OLD | NEW |