|  | // 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 "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::CreateNetworkConflictWarning(const std::string& extension_id) { | 
|  | std::vector<std::string> message_parameters; | 
|  | return Warning( | 
|  | kNetworkConflict, | 
|  | extension_id, | 
|  | IDS_EXTENSION_WARNINGS_NETWORK_CONFLICT, | 
|  | message_parameters); | 
|  | } | 
|  |  | 
|  | // static | 
|  | Warning Warning::CreateRedirectConflictWarning( | 
|  | const std::string& extension_id, | 
|  | const std::string& winning_extension_id, | 
|  | const GURL& attempted_redirect_url, | 
|  | const GURL& winning_redirect_url) { | 
|  | std::vector<std::string> message_parameters; | 
|  | message_parameters.push_back(attempted_redirect_url.spec()); | 
|  | message_parameters.push_back(kTranslate + winning_extension_id); | 
|  | message_parameters.push_back(winning_redirect_url.spec()); | 
|  | return Warning( | 
|  | kRedirectConflict, | 
|  | extension_id, | 
|  | IDS_EXTENSION_WARNINGS_REDIRECT_CONFLICT, | 
|  | message_parameters); | 
|  | } | 
|  |  | 
|  | // static | 
|  | Warning Warning::CreateRequestHeaderConflictWarning( | 
|  | const std::string& extension_id, | 
|  | const std::string& winning_extension_id, | 
|  | const std::string& conflicting_header) { | 
|  | std::vector<std::string> message_parameters; | 
|  | message_parameters.push_back(conflicting_header); | 
|  | message_parameters.push_back(kTranslate + winning_extension_id); | 
|  | return Warning( | 
|  | kNetworkConflict, | 
|  | extension_id, | 
|  | IDS_EXTENSION_WARNINGS_REQUEST_HEADER_CONFLICT, | 
|  | message_parameters); | 
|  | } | 
|  |  | 
|  | // static | 
|  | Warning Warning::CreateResponseHeaderConflictWarning( | 
|  | const std::string& extension_id, | 
|  | const std::string& winning_extension_id, | 
|  | const std::string& conflicting_header) { | 
|  | std::vector<std::string> message_parameters; | 
|  | message_parameters.push_back(conflicting_header); | 
|  | message_parameters.push_back(kTranslate + winning_extension_id); | 
|  | return Warning( | 
|  | kNetworkConflict, | 
|  | extension_id, | 
|  | IDS_EXTENSION_WARNINGS_RESPONSE_HEADER_CONFLICT, | 
|  | message_parameters); | 
|  | } | 
|  |  | 
|  | // static | 
|  | Warning Warning::CreateCredentialsConflictWarning( | 
|  | const std::string& extension_id, | 
|  | const std::string& winning_extension_id) { | 
|  | std::vector<std::string> message_parameters; | 
|  | message_parameters.push_back(kTranslate + winning_extension_id); | 
|  | return Warning( | 
|  | kNetworkConflict, | 
|  | extension_id, | 
|  | IDS_EXTENSION_WARNINGS_CREDENTIALS_CONFLICT, | 
|  | 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); | 
|  | } | 
|  |  | 
|  | 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(); | 
|  | } | 
|  | } | 
|  |  | 
|  | bool operator<(const Warning& a, const Warning& b) { | 
|  | if (a.extension_id() != b.extension_id()) | 
|  | return a.extension_id() < b.extension_id(); | 
|  | return a.warning_type() < b.warning_type(); | 
|  | } | 
|  |  | 
|  | }  // namespace extensions |