blob: 9b7a956d229e585ceade20ace5362facbd7142a1 [file] [log] [blame]
// Copyright (c) 2012 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/browser/warning_set.h"
#include <stddef.h>
#include <tuple>
#include "base/files/file_path.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/extensions_client.h"
#include "extensions/strings/grit/extensions_strings.h"
#include "net/base/escape.h"
#include "ui/base/l10n/l10n_util.h"
using content::BrowserThread;
namespace {
// Prefix for message parameters indicating that the parameter needs to
// be translated from an extension id to the extension name.
const char kTranslate[] = "TO_TRANSLATE:";
const size_t kMaxNumberOfParameters = 4;
}
namespace extensions {
//
// Warning
//
Warning::Warning(
WarningType type,
const std::string& extension_id,
int message_id,
const std::vector<std::string>& message_parameters)
: type_(type),
extension_id_(extension_id),
message_id_(message_id),
message_parameters_(message_parameters) {
// These are invalid here because they do not have corresponding warning
// messages in the UI.
CHECK_NE(type, kInvalid);
CHECK_NE(type, kMaxWarningType);
CHECK_LE(message_parameters.size(), kMaxNumberOfParameters);
}
Warning::Warning(const Warning& other)
: type_(other.type_),
extension_id_(other.extension_id_),
message_id_(other.message_id_),
message_parameters_(other.message_parameters_) {}
Warning::~Warning() {
}
Warning& Warning::operator=(const Warning& other) {
type_ = other.type_;
extension_id_ = other.extension_id_;
message_id_ = other.message_id_;
message_parameters_ = other.message_parameters_;
return *this;
}
// static
Warning Warning::CreateNetworkDelayWarning(
const std::string& extension_id) {
std::vector<std::string> message_parameters;
message_parameters.push_back(ExtensionsClient::Get()->GetProductName());
return Warning(
kNetworkDelay,
extension_id,
IDS_EXTENSION_WARNINGS_NETWORK_DELAY,
message_parameters);
}
// static
Warning Warning::CreateRepeatedCacheFlushesWarning(
const std::string& extension_id) {
std::vector<std::string> message_parameters;
message_parameters.push_back(ExtensionsClient::Get()->GetProductName());
return Warning(
kRepeatedCacheFlushes,
extension_id,
IDS_EXTENSION_WARNINGS_NETWORK_DELAY,
message_parameters);
}
// static
Warning Warning::CreateDownloadFilenameConflictWarning(
const std::string& losing_extension_id,
const std::string& winning_extension_id,
const base::FilePath& losing_filename,
const base::FilePath& winning_filename) {
std::vector<std::string> message_parameters;
message_parameters.push_back(base::UTF16ToUTF8(
losing_filename.LossyDisplayName()));
message_parameters.push_back(kTranslate + winning_extension_id);
message_parameters.push_back(base::UTF16ToUTF8(
winning_filename.LossyDisplayName()));
return Warning(
kDownloadFilenameConflict,
losing_extension_id,
IDS_EXTENSION_WARNINGS_DOWNLOAD_FILENAME_CONFLICT,
message_parameters);
}
// static
Warning Warning::CreateReloadTooFrequentWarning(
const std::string& extension_id) {
std::vector<std::string> message_parameters;
return Warning(kReloadTooFrequent,
extension_id,
IDS_EXTENSION_WARNING_RELOAD_TOO_FREQUENT,
message_parameters);
}
// static
Warning Warning::CreateRulesetFailedToLoadWarning(
const ExtensionId& extension_id) {
return Warning(kRulesetFailedToLoad, extension_id,
IDS_EXTENSION_WARNING_RULESET_FAILED_TO_LOAD,
{} /*message_parameters*/);
}
bool Warning::operator<(const Warning& other) const {
return std::tie(extension_id_, type_) <
std::tie(other.extension_id_, other.type_);
}
std::string Warning::GetLocalizedMessage(const ExtensionSet* extensions) const {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// These parameters may be unsafe (URLs and Extension names) and need
// to be HTML-escaped before being embedded in the UI. Also extension IDs
// are translated to full extension names.
std::vector<base::string16> final_parameters;
for (size_t i = 0; i < message_parameters_.size(); ++i) {
std::string message = message_parameters_[i];
if (base::StartsWith(message, kTranslate, base::CompareCase::SENSITIVE)) {
std::string extension_id = message.substr(sizeof(kTranslate) - 1);
const extensions::Extension* extension =
extensions->GetByID(extension_id);
message = extension ? extension->name() : extension_id;
}
final_parameters.push_back(base::UTF8ToUTF16(net::EscapeForHTML(message)));
}
static_assert(kMaxNumberOfParameters == 4u,
"You Need To Add More Case Statements");
switch (final_parameters.size()) {
case 0:
return l10n_util::GetStringUTF8(message_id_);
case 1:
return l10n_util::GetStringFUTF8(message_id_, final_parameters[0]);
case 2:
return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
final_parameters[1]);
case 3:
return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
final_parameters[1], final_parameters[2]);
case 4:
return l10n_util::GetStringFUTF8(message_id_, final_parameters[0],
final_parameters[1], final_parameters[2], final_parameters[3]);
default:
NOTREACHED();
return std::string();
}
}
} // namespace extensions