1 // Copyright (c) 2013 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. 4 5 #include "chrome/common/extensions/api/extension_action/page_action_handler.h" 6 7 #include "base/strings/utf_string_conversions.h" 8 #include "base/values.h" 9 #include "chrome/common/extensions/extension.h" 10 #include "chrome/common/extensions/extension_constants.h" 11 #include "chrome/common/extensions/extension_file_util.h" 12 #include "chrome/common/extensions/extension_manifest_constants.h" 13 #include "grit/generated_resources.h" 14 15 namespace keys = extension_manifest_keys; 16 namespace errors = extension_manifest_errors; 17 18 namespace extensions { 19 20 PageActionHandler::PageActionHandler() { 21 } 22 23 PageActionHandler::~PageActionHandler() { 24 } 25 26 bool PageActionHandler::Parse(Extension* extension, string16* error) { 27 scoped_ptr<ActionInfo> page_action_info; 28 const base::DictionaryValue* page_action_value = NULL; 29 30 if (extension->manifest()->HasKey(keys::kPageActions)) { 31 const base::ListValue* list_value = NULL; 32 if (!extension->manifest()->GetList(keys::kPageActions, &list_value)) { 33 *error = ASCIIToUTF16(errors::kInvalidPageActionsList); 34 return false; 35 } 36 37 size_t list_value_length = list_value->GetSize(); 38 39 if (list_value_length == 0u) { 40 // A list with zero items is allowed, and is equivalent to not having 41 // a page_actions key in the manifest. Don't set |page_action_value|. 42 } else if (list_value_length == 1u) { 43 if (!list_value->GetDictionary(0, &page_action_value)) { 44 *error = ASCIIToUTF16(errors::kInvalidPageAction); 45 return false; 46 } 47 } else { // list_value_length > 1u. 48 *error = ASCIIToUTF16(errors::kInvalidPageActionsListSize); 49 return false; 50 } 51 } else if (extension->manifest()->HasKey(keys::kPageAction)) { 52 if (!extension->manifest()->GetDictionary(keys::kPageAction, 53 &page_action_value)) { 54 *error = ASCIIToUTF16(errors::kInvalidPageAction); 55 return false; 56 } 57 } 58 59 // An extension cannot have both browser and page actions. 60 if (extension->manifest()->HasKey(keys::kBrowserAction)) { 61 *error = ASCIIToUTF16(errors::kOneUISurfaceOnly); 62 return false; 63 } 64 65 // If page_action_value is not NULL, then there was a valid page action. 66 if (page_action_value) { 67 page_action_info = ActionInfo::Load(extension, page_action_value, error); 68 if (!page_action_info) 69 return false; // Failed to parse page action definition. 70 } 71 ActionInfo::SetPageActionInfo(extension, page_action_info.release()); 72 73 return true; 74 } 75 76 bool PageActionHandler::Validate(const Extension* extension, 77 std::string* error, 78 std::vector<InstallWarning>* warnings) const { 79 const extensions::ActionInfo* action = 80 extensions::ActionInfo::GetPageActionInfo(extension); 81 if (action && !action->default_icon.empty() && 82 !extension_file_util::ValidateExtensionIconSet( 83 action->default_icon, 84 extension, 85 IDS_EXTENSION_LOAD_ICON_FOR_PAGE_ACTION_FAILED, 86 error)) { 87 return false; 88 } 89 return true; 90 } 91 92 const std::vector<std::string> PageActionHandler::Keys() const { 93 std::vector<std::string> keys; 94 keys.push_back(keys::kPageAction); 95 keys.push_back(keys::kPageActions); 96 return keys; 97 } 98 99 } // namespace extensions 100