| 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 | 
|---|