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 3// found in the LICENSE file. 4 5#include "extensions/browser/warning_set.h" 6 7#include "base/files/file_path.h" 8#include "base/strings/string_util.h" 9#include "base/strings/utf_string_conversions.h" 10#include "content/public/browser/browser_thread.h" 11#include "extensions/common/extension.h" 12#include "extensions/common/extension_set.h" 13#include "extensions/common/extensions_client.h" 14#include "extensions/strings/grit/extensions_strings.h" 15#include "net/base/escape.h" 16#include "ui/base/l10n/l10n_util.h" 17 18using content::BrowserThread; 19 20namespace { 21// Prefix for message parameters indicating that the parameter needs to 22// be translated from an extension id to the extension name. 23const char kTranslate[] = "TO_TRANSLATE:"; 24const size_t kMaxNumberOfParameters = 4; 25} 26 27namespace extensions { 28 29// 30// Warning 31// 32 33Warning::Warning( 34 WarningType type, 35 const std::string& extension_id, 36 int message_id, 37 const std::vector<std::string>& message_parameters) 38 : type_(type), 39 extension_id_(extension_id), 40 message_id_(message_id), 41 message_parameters_(message_parameters) { 42 // These are invalid here because they do not have corresponding warning 43 // messages in the UI. 44 CHECK_NE(type, kInvalid); 45 CHECK_NE(type, kMaxWarningType); 46 CHECK_LE(message_parameters.size(), kMaxNumberOfParameters); 47} 48 49Warning::Warning(const Warning& other) 50 : type_(other.type_), 51 extension_id_(other.extension_id_), 52 message_id_(other.message_id_), 53 message_parameters_(other.message_parameters_) {} 54 55Warning::~Warning() { 56} 57 58Warning& Warning::operator=(const Warning& other) { 59 type_ = other.type_; 60 extension_id_ = other.extension_id_; 61 message_id_ = other.message_id_; 62 message_parameters_ = other.message_parameters_; 63 return *this; 64} 65 66// static 67Warning Warning::CreateNetworkDelayWarning( 68 const std::string& extension_id) { 69 std::vector<std::string> message_parameters; 70 message_parameters.push_back(ExtensionsClient::Get()->GetProductName()); 71 return Warning( 72 kNetworkDelay, 73 extension_id, 74 IDS_EXTENSION_WARNINGS_NETWORK_DELAY, 75 message_parameters); 76} 77 78// static 79Warning Warning::CreateNetworkConflictWarning(const std::string& extension_id) { 80 std::vector<std::string> message_parameters; 81 return Warning( 82 kNetworkConflict, 83 extension_id, 84 IDS_EXTENSION_WARNINGS_NETWORK_CONFLICT, 85 message_parameters); 86} 87 88// static 89Warning Warning::CreateRedirectConflictWarning( 90 const std::string& extension_id, 91 const std::string& winning_extension_id, 92 const GURL& attempted_redirect_url, 93 const GURL& winning_redirect_url) { 94 std::vector<std::string> message_parameters; 95 message_parameters.push_back(attempted_redirect_url.spec()); 96 message_parameters.push_back(kTranslate + winning_extension_id); 97 message_parameters.push_back(winning_redirect_url.spec()); 98 return Warning( 99 kRedirectConflict, 100 extension_id, 101 IDS_EXTENSION_WARNINGS_REDIRECT_CONFLICT, 102 message_parameters); 103} 104 105// static 106Warning Warning::CreateRequestHeaderConflictWarning( 107 const std::string& extension_id, 108 const std::string& winning_extension_id, 109 const std::string& conflicting_header) { 110 std::vector<std::string> message_parameters; 111 message_parameters.push_back(conflicting_header); 112 message_parameters.push_back(kTranslate + winning_extension_id); 113 return Warning( 114 kNetworkConflict, 115 extension_id, 116 IDS_EXTENSION_WARNINGS_REQUEST_HEADER_CONFLICT, 117 message_parameters); 118} 119 120// static 121Warning Warning::CreateResponseHeaderConflictWarning( 122 const std::string& extension_id, 123 const std::string& winning_extension_id, 124 const std::string& conflicting_header) { 125 std::vector<std::string> message_parameters; 126 message_parameters.push_back(conflicting_header); 127 message_parameters.push_back(kTranslate + winning_extension_id); 128 return Warning( 129 kNetworkConflict, 130 extension_id, 131 IDS_EXTENSION_WARNINGS_RESPONSE_HEADER_CONFLICT, 132 message_parameters); 133} 134 135// static 136Warning Warning::CreateCredentialsConflictWarning( 137 const std::string& extension_id, 138 const std::string& winning_extension_id) { 139 std::vector<std::string> message_parameters; 140 message_parameters.push_back(kTranslate + winning_extension_id); 141 return Warning( 142 kNetworkConflict, 143 extension_id, 144 IDS_EXTENSION_WARNINGS_CREDENTIALS_CONFLICT, 145 message_parameters); 146} 147 148// static 149Warning Warning::CreateRepeatedCacheFlushesWarning( 150 const std::string& extension_id) { 151 std::vector<std::string> message_parameters; 152 message_parameters.push_back(ExtensionsClient::Get()->GetProductName()); 153 return Warning( 154 kRepeatedCacheFlushes, 155 extension_id, 156 IDS_EXTENSION_WARNINGS_NETWORK_DELAY, 157 message_parameters); 158} 159 160// static 161Warning Warning::CreateDownloadFilenameConflictWarning( 162 const std::string& losing_extension_id, 163 const std::string& winning_extension_id, 164 const base::FilePath& losing_filename, 165 const base::FilePath& winning_filename) { 166 std::vector<std::string> message_parameters; 167 message_parameters.push_back(base::UTF16ToUTF8( 168 losing_filename.LossyDisplayName())); 169 message_parameters.push_back(kTranslate + winning_extension_id); 170 message_parameters.push_back(base::UTF16ToUTF8( 171 winning_filename.LossyDisplayName())); 172 return Warning( 173 kDownloadFilenameConflict, 174 losing_extension_id, 175 IDS_EXTENSION_WARNINGS_DOWNLOAD_FILENAME_CONFLICT, 176 message_parameters); 177} 178 179// static 180Warning Warning::CreateReloadTooFrequentWarning( 181 const std::string& extension_id) { 182 std::vector<std::string> message_parameters; 183 return Warning(kReloadTooFrequent, 184 extension_id, 185 IDS_EXTENSION_WARNING_RELOAD_TOO_FREQUENT, 186 message_parameters); 187} 188 189std::string Warning::GetLocalizedMessage(const ExtensionSet* extensions) const { 190 DCHECK_CURRENTLY_ON(BrowserThread::UI); 191 192 // These parameters may be unsafe (URLs and Extension names) and need 193 // to be HTML-escaped before being embedded in the UI. Also extension IDs 194 // are translated to full extension names. 195 std::vector<base::string16> final_parameters; 196 for (size_t i = 0; i < message_parameters_.size(); ++i) { 197 std::string message = message_parameters_[i]; 198 if (StartsWithASCII(message, kTranslate, true)) { 199 std::string extension_id = message.substr(sizeof(kTranslate) - 1); 200 const extensions::Extension* extension = 201 extensions->GetByID(extension_id); 202 message = extension ? extension->name() : extension_id; 203 } 204 final_parameters.push_back(base::UTF8ToUTF16(net::EscapeForHTML(message))); 205 } 206 207 COMPILE_ASSERT(kMaxNumberOfParameters == 4u, YouNeedToAddMoreCaseStatements); 208 switch (final_parameters.size()) { 209 case 0: 210 return l10n_util::GetStringUTF8(message_id_); 211 case 1: 212 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0]); 213 case 2: 214 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 215 final_parameters[1]); 216 case 3: 217 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 218 final_parameters[1], final_parameters[2]); 219 case 4: 220 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 221 final_parameters[1], final_parameters[2], final_parameters[3]); 222 default: 223 NOTREACHED(); 224 return std::string(); 225 } 226} 227 228bool operator<(const Warning& a, const Warning& b) { 229 if (a.extension_id() != b.extension_id()) 230 return a.extension_id() < b.extension_id(); 231 return a.warning_type() < b.warning_type(); 232} 233 234} // namespace extensions 235