[go: nahoru, domu]

blob: 211ec046fe07c4d69e868ef61d99c82be7a46fe5 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "extensions/common/manifest_handlers/web_app_linked_shortcut_items.h"
#include <memory>
#include <utility>
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"
namespace extensions {
namespace keys = manifest_keys;
namespace errors = manifest_errors;
namespace {
bool ParseShortcutItemIconValue(
const base::Value& value,
WebAppLinkedShortcutItems::ShortcutItemInfo::IconInfo* icon_info,
std::u16string* error) {
const base::DictionaryValue* shortcut_item_icon_dict = nullptr;
if (!value.GetAsDictionary(&shortcut_item_icon_dict)) {
*error = base::UTF8ToUTF16(
manifest_errors::kInvalidWebAppLinkedShortcutItemIcon);
return false;
}
std::string icon_url;
if (!shortcut_item_icon_dict->GetString(
keys::kWebAppLinkedShortcutItemIconURL, &icon_url)) {
*error = base::UTF8ToUTF16(
manifest_errors::kInvalidWebAppLinkedShortcutItemIconUrl);
return false;
}
icon_info->url = GURL(icon_url);
if (!icon_info->url.is_valid()) {
*error = base::UTF8ToUTF16(
manifest_errors::kInvalidWebAppLinkedShortcutItemIconUrl);
return false;
}
if (!shortcut_item_icon_dict->GetInteger(
keys::kWebAppLinkedShortcutItemIconSize, &icon_info->size)) {
*error = base::UTF8ToUTF16(
manifest_errors::kInvalidWebAppLinkedShortcutItemIconSize);
return false;
}
return true;
}
bool ParseShortcutItemValue(const base::Value& value,
WebAppLinkedShortcutItems::ShortcutItemInfo* info,
std::u16string* error) {
const base::DictionaryValue* shortcut_item_dict = nullptr;
if (!value.GetAsDictionary(&shortcut_item_dict)) {
*error =
base::UTF8ToUTF16(manifest_errors::kInvalidWebAppLinkedShortcutItem);
return false;
}
if (!shortcut_item_dict->GetString(keys::kWebAppLinkedShortcutItemName,
&info->name)) {
*error = base::UTF8ToUTF16(
manifest_errors::kInvalidWebAppLinkedShortcutItemName);
return false;
}
std::string url_string;
if (!shortcut_item_dict->GetString(keys::kWebAppLinkedShortcutItemURL,
&url_string)) {
*error =
base::UTF8ToUTF16(manifest_errors::kInvalidWebAppLinkedShortcutItemUrl);
return false;
}
info->url = GURL(url_string);
if (!info->url.is_valid()) {
*error =
base::UTF8ToUTF16(manifest_errors::kInvalidWebAppLinkedShortcutItemUrl);
return false;
}
const base::ListValue* shortcut_item_icons_value = nullptr;
if (!shortcut_item_dict->GetList(keys::kWebAppLinkedShortcutItemIcons,
&shortcut_item_icons_value)) {
*error = base::UTF8ToUTF16(
manifest_errors::kInvalidWebAppLinkedShortcutItemIcons);
return false;
}
base::Value::ConstListView shortcut_item_icons_list =
shortcut_item_icons_value->GetList();
info->shortcut_item_icon_infos.reserve(shortcut_item_icons_list.size());
for (const auto& shortcut_item_icon_value : shortcut_item_icons_list) {
WebAppLinkedShortcutItems::ShortcutItemInfo::IconInfo icon_info;
if (!ParseShortcutItemIconValue(shortcut_item_icon_value, &icon_info,
error)) {
return false;
}
info->shortcut_item_icon_infos.push_back(icon_info);
}
return true;
}
} // namespace
WebAppLinkedShortcutItems::ShortcutItemInfo::IconInfo::IconInfo() = default;
WebAppLinkedShortcutItems::ShortcutItemInfo::IconInfo::~IconInfo() = default;
WebAppLinkedShortcutItems::ShortcutItemInfo::ShortcutItemInfo() = default;
WebAppLinkedShortcutItems::ShortcutItemInfo::ShortcutItemInfo(
const WebAppLinkedShortcutItems::ShortcutItemInfo& other) = default;
WebAppLinkedShortcutItems::ShortcutItemInfo::~ShortcutItemInfo() = default;
WebAppLinkedShortcutItems::WebAppLinkedShortcutItems() = default;
WebAppLinkedShortcutItems::WebAppLinkedShortcutItems(
const WebAppLinkedShortcutItems& other) = default;
WebAppLinkedShortcutItems::~WebAppLinkedShortcutItems() = default;
// static
const WebAppLinkedShortcutItems&
WebAppLinkedShortcutItems::GetWebAppLinkedShortcutItems(
const Extension* extension) {
WebAppLinkedShortcutItems* info = static_cast<WebAppLinkedShortcutItems*>(
extension->GetManifestData(keys::kWebAppLinkedShortcutItems));
if (info)
return *info;
static base::NoDestructor<WebAppLinkedShortcutItems>
empty_web_app_linked_shortcut_items;
return *empty_web_app_linked_shortcut_items;
}
WebAppLinkedShortcutItemsHandler::WebAppLinkedShortcutItemsHandler() = default;
WebAppLinkedShortcutItemsHandler::~WebAppLinkedShortcutItemsHandler() = default;
bool WebAppLinkedShortcutItemsHandler::Parse(Extension* extension,
std::u16string* error) {
// The "web_app_linked_shortcut_items" key is only available for Bookmark
// Apps. Including it elsewhere results in an install warning, and the linked
// shortcut items are not parsed.
if (!extension->from_bookmark()) {
extension->AddInstallWarning(InstallWarning(
errors::kInvalidWebAppLinkedShortcutItemsNotBookmarkApp));
return true;
}
auto web_app_linked_shortcut_items =
std::make_unique<WebAppLinkedShortcutItems>();
const base::Value* shortcut_items_value = nullptr;
if (!extension->manifest()->GetList(keys::kWebAppLinkedShortcutItems,
&shortcut_items_value)) {
*error =
base::UTF8ToUTF16(manifest_errors::kInvalidWebAppLinkedShortcutItems);
return false;
}
base::Value::ConstListView shortcut_items_list =
shortcut_items_value->GetList();
web_app_linked_shortcut_items->shortcut_item_infos.reserve(
shortcut_items_list.size());
for (const auto& shortcut_item_value : shortcut_items_list) {
WebAppLinkedShortcutItems::ShortcutItemInfo info;
if (!ParseShortcutItemValue(shortcut_item_value, &info, error))
return false;
web_app_linked_shortcut_items->shortcut_item_infos.push_back(info);
}
extension->SetManifestData(keys::kWebAppLinkedShortcutItems,
std::move(web_app_linked_shortcut_items));
return true;
}
base::span<const char* const> WebAppLinkedShortcutItemsHandler::Keys() const {
static constexpr const char* kKeys[] = {keys::kWebAppLinkedShortcutItems};
return kKeys;
}
} // namespace extensions