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 "chrome/browser/extensions/extension_warning_set.h" 6 7#include "base/files/file_path.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/chrome_notification_types.h" 10#include "chrome/common/extensions/extension_set.h" 11#include "content/public/browser/browser_thread.h" 12#include "extensions/common/extension.h" 13#include "grit/chromium_strings.h" 14#include "grit/generated_resources.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// ExtensionWarning 31// 32 33ExtensionWarning::ExtensionWarning( 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 49ExtensionWarning::ExtensionWarning(const ExtensionWarning& other) 50 : type_(other.type_), 51 extension_id_(other.extension_id_), 52 message_id_(other.message_id_), 53 message_parameters_(other.message_parameters_) {} 54 55ExtensionWarning::~ExtensionWarning() { 56} 57 58ExtensionWarning& ExtensionWarning::operator=(const ExtensionWarning& 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 67ExtensionWarning ExtensionWarning::CreateNetworkDelayWarning( 68 const std::string& extension_id) { 69 std::vector<std::string> message_parameters; 70 message_parameters.push_back(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME)); 71 return ExtensionWarning( 72 kNetworkDelay, 73 extension_id, 74 IDS_EXTENSION_WARNINGS_NETWORK_DELAY, 75 message_parameters); 76} 77 78// static 79ExtensionWarning ExtensionWarning::CreateNetworkConflictWarning( 80 const std::string& extension_id) { 81 std::vector<std::string> message_parameters; 82 return ExtensionWarning( 83 kNetworkConflict, 84 extension_id, 85 IDS_EXTENSION_WARNINGS_NETWORK_CONFLICT, 86 message_parameters); 87} 88 89// static 90ExtensionWarning ExtensionWarning::CreateRedirectConflictWarning( 91 const std::string& extension_id, 92 const std::string& winning_extension_id, 93 const GURL& attempted_redirect_url, 94 const GURL& winning_redirect_url) { 95 std::vector<std::string> message_parameters; 96 message_parameters.push_back(attempted_redirect_url.spec()); 97 message_parameters.push_back(kTranslate + winning_extension_id); 98 message_parameters.push_back(winning_redirect_url.spec()); 99 return ExtensionWarning( 100 kRedirectConflict, 101 extension_id, 102 IDS_EXTENSION_WARNINGS_REDIRECT_CONFLICT, 103 message_parameters); 104} 105 106// static 107ExtensionWarning ExtensionWarning::CreateRequestHeaderConflictWarning( 108 const std::string& extension_id, 109 const std::string& winning_extension_id, 110 const std::string& conflicting_header) { 111 std::vector<std::string> message_parameters; 112 message_parameters.push_back(conflicting_header); 113 message_parameters.push_back(kTranslate + winning_extension_id); 114 return ExtensionWarning( 115 kNetworkConflict, 116 extension_id, 117 IDS_EXTENSION_WARNINGS_REQUEST_HEADER_CONFLICT, 118 message_parameters); 119} 120 121// static 122ExtensionWarning ExtensionWarning::CreateResponseHeaderConflictWarning( 123 const std::string& extension_id, 124 const std::string& winning_extension_id, 125 const std::string& conflicting_header) { 126 std::vector<std::string> message_parameters; 127 message_parameters.push_back(conflicting_header); 128 message_parameters.push_back(kTranslate + winning_extension_id); 129 return ExtensionWarning( 130 kNetworkConflict, 131 extension_id, 132 IDS_EXTENSION_WARNINGS_RESPONSE_HEADER_CONFLICT, 133 message_parameters); 134} 135 136// static 137ExtensionWarning ExtensionWarning::CreateCredentialsConflictWarning( 138 const std::string& extension_id, 139 const std::string& winning_extension_id) { 140 std::vector<std::string> message_parameters; 141 message_parameters.push_back(kTranslate + winning_extension_id); 142 return ExtensionWarning( 143 kNetworkConflict, 144 extension_id, 145 IDS_EXTENSION_WARNINGS_CREDENTIALS_CONFLICT, 146 message_parameters); 147} 148 149// static 150ExtensionWarning ExtensionWarning::CreateRepeatedCacheFlushesWarning( 151 const std::string& extension_id) { 152 std::vector<std::string> message_parameters; 153 message_parameters.push_back(l10n_util::GetStringUTF8(IDS_PRODUCT_NAME)); 154 return ExtensionWarning( 155 kRepeatedCacheFlushes, 156 extension_id, 157 IDS_EXTENSION_WARNINGS_NETWORK_DELAY, 158 message_parameters); 159} 160 161// static 162ExtensionWarning ExtensionWarning::CreateDownloadFilenameConflictWarning( 163 const std::string& losing_extension_id, 164 const std::string& winning_extension_id, 165 const base::FilePath& losing_filename, 166 const base::FilePath& winning_filename) { 167 std::vector<std::string> message_parameters; 168 message_parameters.push_back(UTF16ToUTF8(losing_filename.LossyDisplayName())); 169 message_parameters.push_back(kTranslate + winning_extension_id); 170 message_parameters.push_back(UTF16ToUTF8( 171 winning_filename.LossyDisplayName())); 172 return ExtensionWarning( 173 kDownloadFilenameConflict, 174 losing_extension_id, 175 IDS_EXTENSION_WARNINGS_DOWNLOAD_FILENAME_CONFLICT, 176 message_parameters); 177} 178 179std::string ExtensionWarning::GetLocalizedMessage( 180 const ExtensionSet* extensions) const { 181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 182 183 // These parameters may be unsafe (URLs and Extension names) and need 184 // to be HTML-escaped before being embedded in the UI. Also extension IDs 185 // are translated to full extension names. 186 std::vector<base::string16> final_parameters; 187 for (size_t i = 0; i < message_parameters_.size(); ++i) { 188 std::string message = message_parameters_[i]; 189 if (StartsWithASCII(message, kTranslate, true)) { 190 std::string extension_id = message.substr(sizeof(kTranslate) - 1); 191 const extensions::Extension* extension = 192 extensions->GetByID(extension_id); 193 message = extension ? extension->name() : extension_id; 194 } 195 final_parameters.push_back(UTF8ToUTF16(net::EscapeForHTML(message))); 196 } 197 198 COMPILE_ASSERT(kMaxNumberOfParameters == 4u, YouNeedToAddMoreCaseStatements); 199 switch (final_parameters.size()) { 200 case 0: 201 return l10n_util::GetStringUTF8(message_id_); 202 case 1: 203 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0]); 204 case 2: 205 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 206 final_parameters[1]); 207 case 3: 208 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 209 final_parameters[1], final_parameters[2]); 210 case 4: 211 return l10n_util::GetStringFUTF8(message_id_, final_parameters[0], 212 final_parameters[1], final_parameters[2], final_parameters[3]); 213 default: 214 NOTREACHED(); 215 return std::string(); 216 } 217} 218 219bool operator<(const ExtensionWarning& a, const ExtensionWarning& b) { 220 if (a.extension_id() != b.extension_id()) 221 return a.extension_id() < b.extension_id(); 222 return a.warning_type() < b.warning_type(); 223} 224 225} // namespace extensions 226